blob: 75b2294f515ce37b1a007eec3d1c80b96d84871e [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
Jeff Brownf2f487182010-10-01 17:46:21 -070049#define INDENT " "
50#define INDENT2 " "
51
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070052namespace android {
53
Jeff Brownb88102f2010-09-08 11:49:43 -070054// Delay between reporting long touch events to the power manager.
55const nsecs_t EVENT_IGNORE_DURATION = 300 * 1000000LL; // 300 ms
56
57// Default input dispatching timeout if there is no focused application or paused window
58// from which to determine an appropriate dispatching timeout.
59const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
60
61// Amount of time to allow for all pending events to be processed when an app switch
62// key is on the way. This is used to preempt input dispatch and drop input events
63// when an application takes too long to respond and the user has pressed an app switch key.
64const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
65
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070066
Jeff Brown7fbdc842010-06-17 20:52:56 -070067static inline nsecs_t now() {
68 return systemTime(SYSTEM_TIME_MONOTONIC);
69}
70
Jeff Brownb88102f2010-09-08 11:49:43 -070071static inline const char* toString(bool value) {
72 return value ? "true" : "false";
73}
74
Jeff Brown01ce2e92010-09-26 22:20:12 -070075static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
76 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
77 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
78}
79
80static bool isValidKeyAction(int32_t action) {
81 switch (action) {
82 case AKEY_EVENT_ACTION_DOWN:
83 case AKEY_EVENT_ACTION_UP:
84 return true;
85 default:
86 return false;
87 }
88}
89
90static bool validateKeyEvent(int32_t action) {
91 if (! isValidKeyAction(action)) {
92 LOGE("Key event has invalid action code 0x%x", action);
93 return false;
94 }
95 return true;
96}
97
98static bool isValidMotionAction(int32_t action) {
99 switch (action & AMOTION_EVENT_ACTION_MASK) {
100 case AMOTION_EVENT_ACTION_DOWN:
101 case AMOTION_EVENT_ACTION_UP:
102 case AMOTION_EVENT_ACTION_CANCEL:
103 case AMOTION_EVENT_ACTION_MOVE:
104 case AMOTION_EVENT_ACTION_POINTER_DOWN:
105 case AMOTION_EVENT_ACTION_POINTER_UP:
106 case AMOTION_EVENT_ACTION_OUTSIDE:
107 return true;
108 default:
109 return false;
110 }
111}
112
113static bool validateMotionEvent(int32_t action, size_t pointerCount,
114 const int32_t* pointerIds) {
115 if (! isValidMotionAction(action)) {
116 LOGE("Motion event has invalid action code 0x%x", action);
117 return false;
118 }
119 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
120 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
121 pointerCount, MAX_POINTERS);
122 return false;
123 }
124 for (size_t i = 0; i < pointerCount; i++) {
125 if (pointerIds[i] < 0 || pointerIds[i] > MAX_POINTER_ID) {
126 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
127 pointerIds[i], MAX_POINTER_ID);
128 return false;
129 }
130 }
131 return true;
132}
133
Jeff Brownb88102f2010-09-08 11:49:43 -0700134
135// --- InputWindow ---
136
Jeff Brownb88102f2010-09-08 11:49:43 -0700137bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
138 return x >= touchableAreaLeft && x <= touchableAreaRight
139 && y >= touchableAreaTop && y <= touchableAreaBottom;
140}
141
Jeff Brown19dfc832010-10-05 12:26:23 -0700142bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
143 return x >= frameLeft && x <= frameRight
144 && y >= frameTop && y <= frameBottom;
145}
146
147bool InputWindow::isTrustedOverlay() const {
148 return layoutParamsType == TYPE_INPUT_METHOD
149 || layoutParamsType == TYPE_INPUT_METHOD_DIALOG;
150}
151
Jeff Brownb88102f2010-09-08 11:49:43 -0700152
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700153// --- InputDispatcher ---
154
Jeff Brown9c3cda02010-06-15 01:31:58 -0700155InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Brownb88102f2010-09-08 11:49:43 -0700156 mPolicy(policy),
157 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
158 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brown01ce2e92010-09-26 22:20:12 -0700159 mFocusedWindow(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700160 mFocusedApplication(NULL),
161 mCurrentInputTargetsValid(false),
162 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700163 mLooper = new Looper(false);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700164
Jeff Brownb88102f2010-09-08 11:49:43 -0700165 mInboundQueue.headSentinel.refCount = -1;
166 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
167 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700168
Jeff Brownb88102f2010-09-08 11:49:43 -0700169 mInboundQueue.tailSentinel.refCount = -1;
170 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
171 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700172
173 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700174
Jeff Brownae9fc032010-08-18 15:51:08 -0700175 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
176 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
177 mThrottleState.lastDeviceId = -1;
178
179#if DEBUG_THROTTLING
180 mThrottleState.originalSampleCount = 0;
181 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
182#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700183}
184
185InputDispatcher::~InputDispatcher() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700186 { // acquire lock
187 AutoMutex _l(mLock);
188
189 resetKeyRepeatLocked();
Jeff Brown54a18252010-09-16 14:07:33 -0700190 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700191 drainInboundQueueLocked();
192 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700193
194 while (mConnectionsByReceiveFd.size() != 0) {
195 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
196 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700197}
198
199void InputDispatcher::dispatchOnce() {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700200 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700201 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700202
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700203 nsecs_t nextWakeupTime = LONG_LONG_MAX;
204 { // acquire lock
205 AutoMutex _l(mLock);
Jeff Brownb88102f2010-09-08 11:49:43 -0700206 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700207
Jeff Brownb88102f2010-09-08 11:49:43 -0700208 if (runCommandsLockedInterruptible()) {
209 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700210 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700211 } // release lock
212
Jeff Brownb88102f2010-09-08 11:49:43 -0700213 // Wait for callback or timeout or wake. (make sure we round up, not down)
214 nsecs_t currentTime = now();
215 int32_t timeoutMillis;
216 if (nextWakeupTime > currentTime) {
217 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
218 timeout = (timeout + 999999LL) / 1000000LL;
219 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
220 } else {
221 timeoutMillis = 0;
222 }
223
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700224 mLooper->pollOnce(timeoutMillis);
Jeff Brownb88102f2010-09-08 11:49:43 -0700225}
226
227void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
228 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
229 nsecs_t currentTime = now();
230
231 // Reset the key repeat timer whenever we disallow key events, even if the next event
232 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
233 // out of sleep.
234 if (keyRepeatTimeout < 0) {
235 resetKeyRepeatLocked();
236 }
237
238 // If dispatching is disabled, drop all events in the queue.
239 if (! mDispatchEnabled) {
240 if (mPendingEvent || ! mInboundQueue.isEmpty()) {
241 LOGI("Dropping pending events because input dispatch is disabled.");
Jeff Brown54a18252010-09-16 14:07:33 -0700242 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700243 drainInboundQueueLocked();
244 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700245 return;
246 }
247
Jeff Brownb88102f2010-09-08 11:49:43 -0700248 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
249 if (mDispatchFrozen) {
250#if DEBUG_FOCUS
251 LOGD("Dispatch frozen. Waiting some more.");
252#endif
253 return;
254 }
255
256 // Optimize latency of app switches.
257 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
258 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
259 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
260 if (mAppSwitchDueTime < *nextWakeupTime) {
261 *nextWakeupTime = mAppSwitchDueTime;
262 }
263
Jeff Brownb88102f2010-09-08 11:49:43 -0700264 // Ready to start a new event.
265 // If we don't already have a pending event, go grab one.
266 if (! mPendingEvent) {
267 if (mInboundQueue.isEmpty()) {
268 if (isAppSwitchDue) {
269 // The inbound queue is empty so the app switch key we were waiting
270 // for will never arrive. Stop waiting for it.
271 resetPendingAppSwitchLocked(false);
272 isAppSwitchDue = false;
273 }
274
275 // Synthesize a key repeat if appropriate.
276 if (mKeyRepeatState.lastKeyEntry) {
277 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
278 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
279 } else {
280 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
281 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
282 }
283 }
284 }
285 if (! mPendingEvent) {
286 return;
287 }
288 } else {
289 // Inbound queue has at least one entry.
290 EventEntry* entry = mInboundQueue.headSentinel.next;
291
292 // Throttle the entry if it is a move event and there are no
293 // other events behind it in the queue. Due to movement batching, additional
294 // samples may be appended to this event by the time the throttling timeout
295 // expires.
296 // TODO Make this smarter and consider throttling per device independently.
297 if (entry->type == EventEntry::TYPE_MOTION) {
298 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
299 int32_t deviceId = motionEntry->deviceId;
300 uint32_t source = motionEntry->source;
301 if (! isAppSwitchDue
302 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
303 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
304 && deviceId == mThrottleState.lastDeviceId
305 && source == mThrottleState.lastSource) {
306 nsecs_t nextTime = mThrottleState.lastEventTime
307 + mThrottleState.minTimeBetweenEvents;
308 if (currentTime < nextTime) {
309 // Throttle it!
310#if DEBUG_THROTTLING
311 LOGD("Throttling - Delaying motion event for "
312 "device 0x%x, source 0x%08x by up to %0.3fms.",
313 deviceId, source, (nextTime - currentTime) * 0.000001);
314#endif
315 if (nextTime < *nextWakeupTime) {
316 *nextWakeupTime = nextTime;
317 }
318 if (mThrottleState.originalSampleCount == 0) {
319 mThrottleState.originalSampleCount =
320 motionEntry->countSamples();
321 }
322 return;
323 }
324 }
325
326#if DEBUG_THROTTLING
327 if (mThrottleState.originalSampleCount != 0) {
328 uint32_t count = motionEntry->countSamples();
329 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
330 count - mThrottleState.originalSampleCount,
331 mThrottleState.originalSampleCount, count);
332 mThrottleState.originalSampleCount = 0;
333 }
334#endif
335
336 mThrottleState.lastEventTime = entry->eventTime < currentTime
337 ? entry->eventTime : currentTime;
338 mThrottleState.lastDeviceId = deviceId;
339 mThrottleState.lastSource = source;
340 }
341
342 mInboundQueue.dequeue(entry);
343 mPendingEvent = entry;
344 }
345 }
346
347 // Now we have an event to dispatch.
348 assert(mPendingEvent != NULL);
Jeff Brown54a18252010-09-16 14:07:33 -0700349 bool done = false;
Jeff Brownb88102f2010-09-08 11:49:43 -0700350 switch (mPendingEvent->type) {
351 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
352 ConfigurationChangedEntry* typedEntry =
353 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700354 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -0700355 break;
356 }
357
358 case EventEntry::TYPE_KEY: {
359 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700360 bool appSwitchKey = isAppSwitchKey(typedEntry->keyCode);
361 bool dropEvent = isAppSwitchDue && ! appSwitchKey;
362 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout, dropEvent,
363 nextWakeupTime);
364 if (done) {
365 if (dropEvent) {
366 LOGI("Dropped key because of pending overdue app switch.");
367 } else if (appSwitchKey) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700368 resetPendingAppSwitchLocked(true);
Jeff Brownb88102f2010-09-08 11:49:43 -0700369 }
370 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700371 break;
372 }
373
374 case EventEntry::TYPE_MOTION: {
375 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700376 bool dropEvent = isAppSwitchDue;
377 done = dispatchMotionLocked(currentTime, typedEntry, dropEvent, nextWakeupTime);
378 if (done) {
379 if (dropEvent) {
380 LOGI("Dropped motion because of pending overdue app switch.");
381 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700382 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700383 break;
384 }
385
386 default:
387 assert(false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700388 break;
389 }
390
Jeff Brown54a18252010-09-16 14:07:33 -0700391 if (done) {
392 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700393 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
394 }
395}
396
397bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
398 bool needWake = mInboundQueue.isEmpty();
399 mInboundQueue.enqueueAtTail(entry);
400
401 switch (entry->type) {
402 case EventEntry::TYPE_KEY:
403 needWake |= detectPendingAppSwitchLocked(static_cast<KeyEntry*>(entry));
404 break;
405 }
406
407 return needWake;
408}
409
410bool InputDispatcher::isAppSwitchKey(int32_t keyCode) {
411 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
412}
413
414bool InputDispatcher::isAppSwitchPendingLocked() {
415 return mAppSwitchDueTime != LONG_LONG_MAX;
416}
417
418bool InputDispatcher::detectPendingAppSwitchLocked(KeyEntry* inboundKeyEntry) {
419 if (inboundKeyEntry->action == AKEY_EVENT_ACTION_UP
420 && ! (inboundKeyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
421 && isAppSwitchKey(inboundKeyEntry->keyCode)
422 && isEventFromReliableSourceLocked(inboundKeyEntry)) {
423#if DEBUG_APP_SWITCH
424 LOGD("App switch is pending!");
425#endif
426 mAppSwitchDueTime = inboundKeyEntry->eventTime + APP_SWITCH_TIMEOUT;
427 return true; // need wake
428 }
429 return false;
430}
431
432void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
433 mAppSwitchDueTime = LONG_LONG_MAX;
434
435#if DEBUG_APP_SWITCH
436 if (handled) {
437 LOGD("App switch has arrived.");
438 } else {
439 LOGD("App switch was abandoned.");
440 }
441#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700442}
443
Jeff Brown9c3cda02010-06-15 01:31:58 -0700444bool InputDispatcher::runCommandsLockedInterruptible() {
445 if (mCommandQueue.isEmpty()) {
446 return false;
447 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700448
Jeff Brown9c3cda02010-06-15 01:31:58 -0700449 do {
450 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
451
452 Command command = commandEntry->command;
453 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
454
Jeff Brown7fbdc842010-06-17 20:52:56 -0700455 commandEntry->connection.clear();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700456 mAllocator.releaseCommandEntry(commandEntry);
457 } while (! mCommandQueue.isEmpty());
458 return true;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700459}
460
Jeff Brown9c3cda02010-06-15 01:31:58 -0700461InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
462 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
463 mCommandQueue.enqueueAtTail(commandEntry);
464 return commandEntry;
465}
466
Jeff Brownb88102f2010-09-08 11:49:43 -0700467void InputDispatcher::drainInboundQueueLocked() {
468 while (! mInboundQueue.isEmpty()) {
469 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700470 releaseInboundEventLocked(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700471 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700472}
473
Jeff Brown54a18252010-09-16 14:07:33 -0700474void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700475 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700476 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700477 mPendingEvent = NULL;
478 }
479}
480
Jeff Brown54a18252010-09-16 14:07:33 -0700481void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700482 InjectionState* injectionState = entry->injectionState;
483 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700484#if DEBUG_DISPATCH_CYCLE
Jeff Brown01ce2e92010-09-26 22:20:12 -0700485 LOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700486#endif
487 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
488 }
489 mAllocator.releaseEventEntry(entry);
490}
491
492bool InputDispatcher::isEventFromReliableSourceLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700493 InjectionState* injectionState = entry->injectionState;
494 return ! injectionState
495 || injectionState->injectorUid == 0
Jeff Brownb88102f2010-09-08 11:49:43 -0700496 || mPolicy->checkInjectEventsPermissionNonReentrant(
Jeff Brown01ce2e92010-09-26 22:20:12 -0700497 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -0700498}
499
500void InputDispatcher::resetKeyRepeatLocked() {
501 if (mKeyRepeatState.lastKeyEntry) {
502 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
503 mKeyRepeatState.lastKeyEntry = NULL;
504 }
505}
506
507InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brownb21fb102010-09-07 10:44:57 -0700508 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown349703e2010-06-22 01:27:15 -0700509 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
510
Jeff Brown349703e2010-06-22 01:27:15 -0700511 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700512 uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700513 if (entry->refCount == 1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700514 mAllocator.recycleKeyEntry(entry);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700515 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700516 entry->policyFlags = policyFlags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700517 entry->repeatCount += 1;
518 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700519 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700520 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700521 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700522 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700523
524 mKeyRepeatState.lastKeyEntry = newEntry;
525 mAllocator.releaseKeyEntry(entry);
526
527 entry = newEntry;
528 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700529 entry->syntheticRepeat = true;
530
531 // Increment reference count since we keep a reference to the event in
532 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
533 entry->refCount += 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700534
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700535 if (entry->repeatCount == 1) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700536 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700537 }
538
Jeff Brownb21fb102010-09-07 10:44:57 -0700539 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700540 return entry;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700541}
542
Jeff Brownb88102f2010-09-08 11:49:43 -0700543bool InputDispatcher::dispatchConfigurationChangedLocked(
544 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700545#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownb88102f2010-09-08 11:49:43 -0700546 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
547#endif
548
549 // Reset key repeating in case a keyboard device was added or removed or something.
550 resetKeyRepeatLocked();
551
552 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
553 CommandEntry* commandEntry = postCommandLocked(
554 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
555 commandEntry->eventTime = entry->eventTime;
556 return true;
557}
558
559bool InputDispatcher::dispatchKeyLocked(
560 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brown54a18252010-09-16 14:07:33 -0700561 bool dropEvent, nsecs_t* nextWakeupTime) {
562 // Give the policy a chance to intercept the key.
563 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
564 bool trusted;
565 if (! dropEvent && mFocusedWindow) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700566 trusted = checkInjectionPermission(mFocusedWindow, entry->injectionState);
Jeff Brown54a18252010-09-16 14:07:33 -0700567 } else {
568 trusted = isEventFromReliableSourceLocked(entry);
569 }
570 if (trusted) {
571 CommandEntry* commandEntry = postCommandLocked(
572 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
573 if (! dropEvent && mFocusedWindow) {
574 commandEntry->inputChannel = mFocusedWindow->inputChannel;
575 }
576 commandEntry->keyEntry = entry;
577 entry->refCount += 1;
578 return false; // wait for the command to run
579 } else {
580 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
581 }
582 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
583 resetTargetsLocked();
584 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
585 return true;
586 }
587
588 // Clean up if dropping the event.
589 if (dropEvent) {
590 resetTargetsLocked();
591 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
592 return true;
593 }
594
Jeff Brownb88102f2010-09-08 11:49:43 -0700595 // Preprocessing.
596 if (! entry->dispatchInProgress) {
597 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
598
599 if (entry->repeatCount == 0
600 && entry->action == AKEY_EVENT_ACTION_DOWN
601 && ! entry->isInjected()) {
602 if (mKeyRepeatState.lastKeyEntry
603 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
604 // We have seen two identical key downs in a row which indicates that the device
605 // driver is automatically generating key repeats itself. We take note of the
606 // repeat here, but we disable our own next key repeat timer since it is clear that
607 // we will not need to synthesize key repeats ourselves.
608 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
609 resetKeyRepeatLocked();
610 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
611 } else {
612 // Not a repeat. Save key down state in case we do see a repeat later.
613 resetKeyRepeatLocked();
614 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
615 }
616 mKeyRepeatState.lastKeyEntry = entry;
617 entry->refCount += 1;
618 } else if (! entry->syntheticRepeat) {
619 resetKeyRepeatLocked();
620 }
621
622 entry->dispatchInProgress = true;
Jeff Brown54a18252010-09-16 14:07:33 -0700623 resetTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700624 }
625
626 // Identify targets.
627 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700628 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
629 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700630 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
631 return false;
632 }
633
634 setInjectionResultLocked(entry, injectionResult);
635 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
636 return true;
637 }
638
639 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700640 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700641 }
642
643 // Dispatch the key.
644 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
645
646 // Poke user activity.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700647 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
648 pokeUserActivityLocked(entry->eventTime, POWER_MANAGER_BUTTON_EVENT);
649 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700650 return true;
651}
652
653void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
654#if DEBUG_OUTBOUND_EVENT_DETAILS
655 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
656 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
657 "downTime=%lld",
658 prefix,
659 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
660 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
661 entry->downTime);
662#endif
663}
664
665bool InputDispatcher::dispatchMotionLocked(
Jeff Brown54a18252010-09-16 14:07:33 -0700666 nsecs_t currentTime, MotionEntry* entry, bool dropEvent, nsecs_t* nextWakeupTime) {
667 // Clean up if dropping the event.
668 if (dropEvent) {
669 resetTargetsLocked();
670 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
671 return true;
672 }
673
Jeff Brownb88102f2010-09-08 11:49:43 -0700674 // Preprocessing.
675 if (! entry->dispatchInProgress) {
676 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
677
678 entry->dispatchInProgress = true;
Jeff Brown54a18252010-09-16 14:07:33 -0700679 resetTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700680 }
681
682 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
683
684 // Identify targets.
685 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700686 int32_t injectionResult;
687 if (isPointerEvent) {
688 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700689 injectionResult = findTouchedWindowTargetsLocked(currentTime,
690 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700691 } else {
692 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700693 injectionResult = findFocusedWindowTargetsLocked(currentTime,
694 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700695 }
696 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
697 return false;
698 }
699
700 setInjectionResultLocked(entry, injectionResult);
701 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
702 return true;
703 }
704
705 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700706 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700707 }
708
709 // Dispatch the motion.
710 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
711
712 // Poke user activity.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700713 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
714 int32_t eventType;
715 if (isPointerEvent) {
716 switch (entry->action) {
717 case AMOTION_EVENT_ACTION_DOWN:
Jeff Brownb88102f2010-09-08 11:49:43 -0700718 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700719 break;
720 case AMOTION_EVENT_ACTION_UP:
721 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
722 break;
723 default:
724 if (entry->eventTime - entry->downTime >= EVENT_IGNORE_DURATION) {
725 eventType = POWER_MANAGER_TOUCH_EVENT;
726 } else {
727 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
728 }
729 break;
Jeff Brownb88102f2010-09-08 11:49:43 -0700730 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700731 } else {
732 eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brownb88102f2010-09-08 11:49:43 -0700733 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700734 pokeUserActivityLocked(entry->eventTime, eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700735 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700736 return true;
737}
738
739
740void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
741#if DEBUG_OUTBOUND_EVENT_DETAILS
742 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700743 "action=0x%x, flags=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700744 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700745 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700746 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
747 entry->action, entry->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700748 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
749 entry->downTime);
750
751 // Print the most recent sample that we have available, this may change due to batching.
752 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700753 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700754 for (; sample->next != NULL; sample = sample->next) {
755 sampleCount += 1;
756 }
757 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -0700758 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700759 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700760 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700761 i, entry->pointerIds[i],
Jeff Brown8d608662010-08-30 03:02:23 -0700762 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
763 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
764 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
765 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
766 sample->pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700767 }
768
769 // Keep in mind that due to batching, it is possible for the number of samples actually
770 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700771 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700772 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
773 }
774#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700775}
776
777void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
778 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
779#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -0700780 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700781 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700782 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700783#endif
784
Jeff Brown9c3cda02010-06-15 01:31:58 -0700785 assert(eventEntry->dispatchInProgress); // should already have been set to true
786
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700787 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
788 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
789
Jeff Brown519e0242010-09-15 15:18:56 -0700790 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700791 if (connectionIndex >= 0) {
792 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700793 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700794 resumeWithAppendedMotionSample);
795 } else {
796 LOGW("Framework requested delivery of an input event to channel '%s' but it "
797 "is not registered with the input dispatcher.",
798 inputTarget.inputChannel->getName().string());
799 }
800 }
801}
802
Jeff Brown54a18252010-09-16 14:07:33 -0700803void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700804 mCurrentInputTargetsValid = false;
805 mCurrentInputTargets.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700806 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
807}
808
Jeff Brown01ce2e92010-09-26 22:20:12 -0700809void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700810 mCurrentInputTargetsValid = true;
811}
812
813int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
814 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
815 nsecs_t* nextWakeupTime) {
816 if (application == NULL && window == NULL) {
817 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
818#if DEBUG_FOCUS
819 LOGD("Waiting for system to become ready for input.");
820#endif
821 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
822 mInputTargetWaitStartTime = currentTime;
823 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
824 mInputTargetWaitTimeoutExpired = false;
825 }
826 } else {
827 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
828#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700829 LOGD("Waiting for application to become ready for input: %s",
830 getApplicationWindowLabelLocked(application, window).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700831#endif
832 nsecs_t timeout = window ? window->dispatchingTimeout :
833 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
834
835 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
836 mInputTargetWaitStartTime = currentTime;
837 mInputTargetWaitTimeoutTime = currentTime + timeout;
838 mInputTargetWaitTimeoutExpired = false;
839 }
840 }
841
842 if (mInputTargetWaitTimeoutExpired) {
843 return INPUT_EVENT_INJECTION_TIMED_OUT;
844 }
845
846 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown519e0242010-09-15 15:18:56 -0700847 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700848
849 // Force poll loop to wake up immediately on next iteration once we get the
850 // ANR response back from the policy.
851 *nextWakeupTime = LONG_LONG_MIN;
852 return INPUT_EVENT_INJECTION_PENDING;
853 } else {
854 // Force poll loop to wake up when timeout is due.
855 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
856 *nextWakeupTime = mInputTargetWaitTimeoutTime;
857 }
858 return INPUT_EVENT_INJECTION_PENDING;
859 }
860}
861
Jeff Brown519e0242010-09-15 15:18:56 -0700862void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
863 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700864 if (newTimeout > 0) {
865 // Extend the timeout.
866 mInputTargetWaitTimeoutTime = now() + newTimeout;
867 } else {
868 // Give up.
869 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -0700870
Jeff Brown01ce2e92010-09-26 22:20:12 -0700871 // Release the touch targets.
872 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -0700873
Jeff Brown519e0242010-09-15 15:18:56 -0700874 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -0700875 if (inputChannel.get()) {
876 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
877 if (connectionIndex >= 0) {
878 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
879 connection->inputState.setOutOfSync();
880 }
Jeff Brown519e0242010-09-15 15:18:56 -0700881 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700882 }
883}
884
Jeff Brown519e0242010-09-15 15:18:56 -0700885nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -0700886 nsecs_t currentTime) {
887 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
888 return currentTime - mInputTargetWaitStartTime;
889 }
890 return 0;
891}
892
893void InputDispatcher::resetANRTimeoutsLocked() {
894#if DEBUG_FOCUS
895 LOGD("Resetting ANR timeouts.");
896#endif
897
Jeff Brownb88102f2010-09-08 11:49:43 -0700898 // Reset input target wait timeout.
899 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
900}
901
Jeff Brown01ce2e92010-09-26 22:20:12 -0700902int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
903 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700904 mCurrentInputTargets.clear();
905
906 int32_t injectionResult;
907
908 // If there is no currently focused window and no focused application
909 // then drop the event.
910 if (! mFocusedWindow) {
911 if (mFocusedApplication) {
912#if DEBUG_FOCUS
913 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -0700914 "focused application that may eventually add a window: %s.",
915 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700916#endif
917 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
918 mFocusedApplication, NULL, nextWakeupTime);
919 goto Unresponsive;
920 }
921
922 LOGI("Dropping event because there is no focused window or focused application.");
923 injectionResult = INPUT_EVENT_INJECTION_FAILED;
924 goto Failed;
925 }
926
927 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700928 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700929 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
930 goto Failed;
931 }
932
933 // If the currently focused window is paused then keep waiting.
934 if (mFocusedWindow->paused) {
935#if DEBUG_FOCUS
936 LOGD("Waiting because focused window is paused.");
937#endif
938 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
939 mFocusedApplication, mFocusedWindow, nextWakeupTime);
940 goto Unresponsive;
941 }
942
Jeff Brown519e0242010-09-15 15:18:56 -0700943 // If the currently focused window is still working on previous events then keep waiting.
944 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
945#if DEBUG_FOCUS
946 LOGD("Waiting because focused window still processing previous input.");
947#endif
948 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
949 mFocusedApplication, mFocusedWindow, nextWakeupTime);
950 goto Unresponsive;
951 }
952
Jeff Brownb88102f2010-09-08 11:49:43 -0700953 // Success! Output targets.
954 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700955 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -0700956
957 // Done.
958Failed:
959Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -0700960 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
961 updateDispatchStatisticsLocked(currentTime, entry,
962 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -0700963#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700964 LOGD("findFocusedWindow finished: injectionResult=%d, "
965 "timeSpendWaitingForApplication=%0.1fms",
966 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -0700967#endif
968 return injectionResult;
969}
970
Jeff Brown01ce2e92010-09-26 22:20:12 -0700971int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
972 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700973 enum InjectionPermission {
974 INJECTION_PERMISSION_UNKNOWN,
975 INJECTION_PERMISSION_GRANTED,
976 INJECTION_PERMISSION_DENIED
977 };
978
Jeff Brownb88102f2010-09-08 11:49:43 -0700979 mCurrentInputTargets.clear();
980
981 nsecs_t startTime = now();
982
983 // For security reasons, we defer updating the touch state until we are sure that
984 // event injection will be allowed.
985 //
986 // FIXME In the original code, screenWasOff could never be set to true.
987 // The reason is that the POLICY_FLAG_WOKE_HERE
988 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
989 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
990 // actually enqueued using the policyFlags that appeared in the final EV_SYN
991 // events upon which no preprocessing took place. So policyFlags was always 0.
992 // In the new native input dispatcher we're a bit more careful about event
993 // preprocessing so the touches we receive can actually have non-zero policyFlags.
994 // Unfortunately we obtain undesirable behavior.
995 //
996 // Here's what happens:
997 //
998 // When the device dims in anticipation of going to sleep, touches
999 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1000 // the device to brighten and reset the user activity timer.
1001 // Touches on other windows (such as the launcher window)
1002 // are dropped. Then after a moment, the device goes to sleep. Oops.
1003 //
1004 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1005 // instead of POLICY_FLAG_WOKE_HERE...
1006 //
1007 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1008
1009 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001010 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001011
1012 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001013 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1014 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1015 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1016 mTempTouchState.reset();
1017 mTempTouchState.down = true;
1018 } else {
1019 mTempTouchState.copyFrom(mTouchState);
1020 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001021
Jeff Brown01ce2e92010-09-26 22:20:12 -07001022 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1023 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1024 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1025 /* Case 1: New splittable pointer going down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001026
Jeff Brown01ce2e92010-09-26 22:20:12 -07001027 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1028 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1029 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1030 const InputWindow* newTouchedWindow = NULL;
1031 const InputWindow* topErrorWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07001032
1033 // Traverse windows from front to back to find touched window and outside targets.
1034 size_t numWindows = mWindows.size();
1035 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001036 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001037 int32_t flags = window->layoutParamsFlags;
1038
1039 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1040 if (! topErrorWindow) {
1041 topErrorWindow = window;
1042 }
1043 }
1044
1045 if (window->visible) {
1046 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1047 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1048 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1049 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1050 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1051 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001052 }
1053 break; // found touched window, exit window loop
1054 }
1055 }
1056
Jeff Brown01ce2e92010-09-26 22:20:12 -07001057 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1058 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001059 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1060 if (isWindowObscuredAtPointLocked(window, x, y)) {
1061 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1062 }
1063
1064 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001065 }
1066 }
1067 }
1068
1069 // If there is an error window but it is not taking focus (typically because
1070 // it is invisible) then wait for it. Any other focused window may in
1071 // fact be in ANR state.
1072 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1073#if DEBUG_FOCUS
1074 LOGD("Waiting because system error window is pending.");
1075#endif
1076 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1077 NULL, NULL, nextWakeupTime);
1078 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1079 goto Unresponsive;
1080 }
1081
Jeff Brown01ce2e92010-09-26 22:20:12 -07001082 // Figure out whether splitting will be allowed for this window.
Jeff Brown0c1f7562010-09-28 13:24:41 -07001083 if (newTouchedWindow
1084 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001085 // New window supports splitting.
1086 isSplit = true;
1087 } else if (isSplit) {
1088 // New window does not support splitting but we have already split events.
1089 // Assign the pointer to the first foreground window we find.
1090 // (May be NULL which is why we put this code block before the next check.)
1091 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1092 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001093
Jeff Brownb88102f2010-09-08 11:49:43 -07001094 // If we did not find a touched window then fail.
1095 if (! newTouchedWindow) {
1096 if (mFocusedApplication) {
1097#if DEBUG_FOCUS
1098 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001099 "focused application that may eventually add a new window: %s.",
1100 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001101#endif
1102 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1103 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001104 goto Unresponsive;
1105 }
1106
1107 LOGI("Dropping event because there is no touched window or focused application.");
1108 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001109 goto Failed;
1110 }
1111
Jeff Brown19dfc832010-10-05 12:26:23 -07001112 // Set target flags.
1113 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1114 if (isSplit) {
1115 targetFlags |= InputTarget::FLAG_SPLIT;
1116 }
1117 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1118 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1119 }
1120
Jeff Brown01ce2e92010-09-26 22:20:12 -07001121 // Update the temporary touch state.
1122 BitSet32 pointerIds;
1123 if (isSplit) {
1124 uint32_t pointerId = entry->pointerIds[pointerIndex];
1125 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001126 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001127 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001128 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001129 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001130
1131 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001132 if (! mTempTouchState.down) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001133 LOGI("Dropping event because the pointer is not down.");
1134 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001135 goto Failed;
1136 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001137 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001138
Jeff Brown01ce2e92010-09-26 22:20:12 -07001139 // Check permission to inject into all touched foreground windows and ensure there
1140 // is at least one touched foreground window.
1141 {
1142 bool haveForegroundWindow = false;
1143 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1144 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1145 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1146 haveForegroundWindow = true;
1147 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1148 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1149 injectionPermission = INJECTION_PERMISSION_DENIED;
1150 goto Failed;
1151 }
1152 }
1153 }
1154 if (! haveForegroundWindow) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001155#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown01ce2e92010-09-26 22:20:12 -07001156 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001157#endif
1158 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001159 goto Failed;
1160 }
1161
Jeff Brown01ce2e92010-09-26 22:20:12 -07001162 // Permission granted to injection into all touched foreground windows.
1163 injectionPermission = INJECTION_PERMISSION_GRANTED;
1164 }
Jeff Brown519e0242010-09-15 15:18:56 -07001165
Jeff Brown01ce2e92010-09-26 22:20:12 -07001166 // Ensure all touched foreground windows are ready for new input.
1167 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1168 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1169 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1170 // If the touched window is paused then keep waiting.
1171 if (touchedWindow.window->paused) {
1172#if DEBUG_INPUT_DISPATCHER_POLICY
1173 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001174#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001175 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1176 NULL, touchedWindow.window, nextWakeupTime);
1177 goto Unresponsive;
1178 }
1179
1180 // If the touched window is still working on previous events then keep waiting.
1181 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1182#if DEBUG_FOCUS
1183 LOGD("Waiting because touched window still processing previous input.");
1184#endif
1185 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1186 NULL, touchedWindow.window, nextWakeupTime);
1187 goto Unresponsive;
1188 }
1189 }
1190 }
1191
1192 // If this is the first pointer going down and the touched window has a wallpaper
1193 // then also add the touched wallpaper windows so they are locked in for the duration
1194 // of the touch gesture.
1195 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1196 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1197 if (foregroundWindow->hasWallpaper) {
1198 for (size_t i = 0; i < mWindows.size(); i++) {
1199 const InputWindow* window = & mWindows[i];
1200 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001201 mTempTouchState.addOrUpdateWindow(window,
1202 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001203 }
1204 }
1205 }
1206 }
1207
Jeff Brownb88102f2010-09-08 11:49:43 -07001208 // Success! Output targets.
1209 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001210
Jeff Brown01ce2e92010-09-26 22:20:12 -07001211 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1212 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1213 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1214 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001215 }
1216
Jeff Brown01ce2e92010-09-26 22:20:12 -07001217 // Drop the outside touch window since we will not care about them in the next iteration.
1218 mTempTouchState.removeOutsideTouchWindows();
1219
Jeff Brownb88102f2010-09-08 11:49:43 -07001220Failed:
1221 // Check injection permission once and for all.
1222 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001223 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001224 injectionPermission = INJECTION_PERMISSION_GRANTED;
1225 } else {
1226 injectionPermission = INJECTION_PERMISSION_DENIED;
1227 }
1228 }
1229
1230 // Update final pieces of touch state if the injector had permission.
1231 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001232 if (maskedAction == AMOTION_EVENT_ACTION_UP
1233 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1234 // All pointers up or canceled.
1235 mTempTouchState.reset();
1236 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1237 // First pointer went down.
1238 if (mTouchState.down) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001239 LOGW("Pointer down received while already down.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001240 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001241 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1242 // One pointer went up.
1243 if (isSplit) {
1244 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1245 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001246
Jeff Brown01ce2e92010-09-26 22:20:12 -07001247 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1248 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1249 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1250 touchedWindow.pointerIds.clearBit(pointerId);
1251 if (touchedWindow.pointerIds.isEmpty()) {
1252 mTempTouchState.windows.removeAt(i);
1253 continue;
1254 }
1255 }
1256 i += 1;
1257 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001258 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001259 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001260
1261 // Save changes to touch state.
1262 mTouchState.copyFrom(mTempTouchState);
Jeff Brownb88102f2010-09-08 11:49:43 -07001263 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001264#if DEBUG_FOCUS
1265 LOGD("Not updating touch focus because injection was denied.");
1266#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001267 }
1268
1269Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001270 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1271 updateDispatchStatisticsLocked(currentTime, entry,
1272 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001273#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001274 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1275 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001276 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001277#endif
1278 return injectionResult;
1279}
1280
Jeff Brown01ce2e92010-09-26 22:20:12 -07001281void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1282 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001283 mCurrentInputTargets.push();
1284
1285 InputTarget& target = mCurrentInputTargets.editTop();
1286 target.inputChannel = window->inputChannel;
1287 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001288 target.xOffset = - window->frameLeft;
1289 target.yOffset = - window->frameTop;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001290 target.windowType = window->layoutParamsType;
1291 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001292}
1293
1294void InputDispatcher::addMonitoringTargetsLocked() {
1295 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1296 mCurrentInputTargets.push();
1297
1298 InputTarget& target = mCurrentInputTargets.editTop();
1299 target.inputChannel = mMonitoringChannels[i];
1300 target.flags = 0;
Jeff Brownb88102f2010-09-08 11:49:43 -07001301 target.xOffset = 0;
1302 target.yOffset = 0;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001303 target.windowType = InputWindow::TYPE_SYSTEM_OVERLAY;
Jeff Brownb88102f2010-09-08 11:49:43 -07001304 }
1305}
1306
1307bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001308 const InjectionState* injectionState) {
1309 if (injectionState
1310 && injectionState->injectorUid > 0
1311 && (window == NULL || window->ownerUid != injectionState->injectorUid)) {
1312 bool result = mPolicy->checkInjectEventsPermissionNonReentrant(
1313 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001314 if (! result) {
1315 if (window) {
1316 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1317 "with input channel %s owned by uid %d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07001318 injectionState->injectorPid, injectionState->injectorUid,
1319 window->inputChannel->getName().string(),
Jeff Brownb88102f2010-09-08 11:49:43 -07001320 window->ownerUid);
1321 } else {
1322 LOGW("Permission denied: injecting event from pid %d uid %d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07001323 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001324 }
1325 return false;
1326 }
1327 }
1328 return true;
1329}
1330
Jeff Brown19dfc832010-10-05 12:26:23 -07001331bool InputDispatcher::isWindowObscuredAtPointLocked(
1332 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07001333 size_t numWindows = mWindows.size();
1334 for (size_t i = 0; i < numWindows; i++) {
1335 const InputWindow* other = & mWindows.itemAt(i);
1336 if (other == window) {
1337 break;
1338 }
Jeff Brown19dfc832010-10-05 12:26:23 -07001339 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001340 return true;
1341 }
1342 }
1343 return false;
1344}
1345
Jeff Brown519e0242010-09-15 15:18:56 -07001346bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1347 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1348 if (connectionIndex >= 0) {
1349 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1350 return connection->outboundQueue.isEmpty();
1351 } else {
1352 return true;
1353 }
1354}
1355
1356String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1357 const InputWindow* window) {
1358 if (application) {
1359 if (window) {
1360 String8 label(application->name);
1361 label.append(" - ");
1362 label.append(window->name);
1363 return label;
1364 } else {
1365 return application->name;
1366 }
1367 } else if (window) {
1368 return window->name;
1369 } else {
1370 return String8("<unknown application or window>");
1371 }
1372}
1373
Jeff Brown01ce2e92010-09-26 22:20:12 -07001374bool InputDispatcher::shouldPokeUserActivityForCurrentInputTargetsLocked() {
1375 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
1376 if (mCurrentInputTargets[i].windowType == InputWindow::TYPE_KEYGUARD) {
1377 return false;
1378 }
1379 }
1380 return true;
1381}
1382
1383void InputDispatcher::pokeUserActivityLocked(nsecs_t eventTime, int32_t eventType) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001384 CommandEntry* commandEntry = postCommandLocked(
1385 & InputDispatcher::doPokeUserActivityLockedInterruptible);
1386 commandEntry->eventTime = eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001387 commandEntry->userActivityEventType = eventType;
1388}
1389
Jeff Brown7fbdc842010-06-17 20:52:56 -07001390void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1391 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001392 bool resumeWithAppendedMotionSample) {
1393#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001394 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001395 "xOffset=%f, yOffset=%f, "
1396 "windowType=%d, pointerIds=0x%x, "
1397 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001398 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001399 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001400 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001401 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001402#endif
1403
Jeff Brown01ce2e92010-09-26 22:20:12 -07001404 // Make sure we are never called for streaming when splitting across multiple windows.
1405 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1406 assert(! (resumeWithAppendedMotionSample && isSplit));
1407
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001408 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001409 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001410 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001411 LOGW("channel '%s' ~ Dropping event because the channel status is %s",
1412 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001413 return;
1414 }
1415
Jeff Brown01ce2e92010-09-26 22:20:12 -07001416 // Split a motion event if needed.
1417 if (isSplit) {
1418 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1419
1420 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1421 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1422 MotionEntry* splitMotionEntry = splitMotionEvent(
1423 originalMotionEntry, inputTarget->pointerIds);
1424#if DEBUG_FOCUS
1425 LOGD("channel '%s' ~ Split motion event.",
1426 connection->getInputChannelName());
1427 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1428#endif
1429 eventEntry = splitMotionEntry;
1430 }
1431 }
1432
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001433 // Resume the dispatch cycle with a freshly appended motion sample.
1434 // First we check that the last dispatch entry in the outbound queue is for the same
1435 // motion event to which we appended the motion sample. If we find such a dispatch
1436 // entry, and if it is currently in progress then we try to stream the new sample.
1437 bool wasEmpty = connection->outboundQueue.isEmpty();
1438
1439 if (! wasEmpty && resumeWithAppendedMotionSample) {
1440 DispatchEntry* motionEventDispatchEntry =
1441 connection->findQueuedDispatchEntryForEvent(eventEntry);
1442 if (motionEventDispatchEntry) {
1443 // If the dispatch entry is not in progress, then we must be busy dispatching an
1444 // earlier event. Not a problem, the motion event is on the outbound queue and will
1445 // be dispatched later.
1446 if (! motionEventDispatchEntry->inProgress) {
1447#if DEBUG_BATCHING
1448 LOGD("channel '%s' ~ Not streaming because the motion event has "
1449 "not yet been dispatched. "
1450 "(Waiting for earlier events to be consumed.)",
1451 connection->getInputChannelName());
1452#endif
1453 return;
1454 }
1455
1456 // If the dispatch entry is in progress but it already has a tail of pending
1457 // motion samples, then it must mean that the shared memory buffer filled up.
1458 // Not a problem, when this dispatch cycle is finished, we will eventually start
1459 // a new dispatch cycle to process the tail and that tail includes the newly
1460 // appended motion sample.
1461 if (motionEventDispatchEntry->tailMotionSample) {
1462#if DEBUG_BATCHING
1463 LOGD("channel '%s' ~ Not streaming because no new samples can "
1464 "be appended to the motion event in this dispatch cycle. "
1465 "(Waiting for next dispatch cycle to start.)",
1466 connection->getInputChannelName());
1467#endif
1468 return;
1469 }
1470
1471 // The dispatch entry is in progress and is still potentially open for streaming.
1472 // Try to stream the new motion sample. This might fail if the consumer has already
1473 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001474 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1475 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001476 status_t status = connection->inputPublisher.appendMotionSample(
1477 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1478 if (status == OK) {
1479#if DEBUG_BATCHING
1480 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1481 connection->getInputChannelName());
1482#endif
1483 return;
1484 }
1485
1486#if DEBUG_BATCHING
1487 if (status == NO_MEMORY) {
1488 LOGD("channel '%s' ~ Could not append motion sample to currently "
1489 "dispatched move event because the shared memory buffer is full. "
1490 "(Waiting for next dispatch cycle to start.)",
1491 connection->getInputChannelName());
1492 } else if (status == status_t(FAILED_TRANSACTION)) {
1493 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001494 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001495 "(Waiting for next dispatch cycle to start.)",
1496 connection->getInputChannelName());
1497 } else {
1498 LOGD("channel '%s' ~ Could not append motion sample to currently "
1499 "dispatched move event due to an error, status=%d. "
1500 "(Waiting for next dispatch cycle to start.)",
1501 connection->getInputChannelName(), status);
1502 }
1503#endif
1504 // Failed to stream. Start a new tail of pending motion samples to dispatch
1505 // in the next cycle.
1506 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1507 return;
1508 }
1509 }
1510
Jeff Brownb88102f2010-09-08 11:49:43 -07001511 // Bring the input state back in line with reality in case it drifted off during an ANR.
1512 if (connection->inputState.isOutOfSync()) {
1513 mTempCancelationEvents.clear();
1514 connection->inputState.synthesizeCancelationEvents(& mAllocator, mTempCancelationEvents);
1515 connection->inputState.resetOutOfSync();
1516
1517 if (! mTempCancelationEvents.isEmpty()) {
1518 LOGI("channel '%s' ~ Generated %d cancelation events to bring channel back in sync "
1519 "with reality.",
1520 connection->getInputChannelName(), mTempCancelationEvents.size());
1521
1522 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1523 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1524 switch (cancelationEventEntry->type) {
1525 case EventEntry::TYPE_KEY:
1526 logOutboundKeyDetailsLocked(" ",
1527 static_cast<KeyEntry*>(cancelationEventEntry));
1528 break;
1529 case EventEntry::TYPE_MOTION:
1530 logOutboundMotionDetailsLocked(" ",
1531 static_cast<MotionEntry*>(cancelationEventEntry));
1532 break;
1533 }
1534
1535 DispatchEntry* cancelationDispatchEntry =
1536 mAllocator.obtainDispatchEntry(cancelationEventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07001537 0, inputTarget->xOffset, inputTarget->yOffset); // increments ref
Jeff Brownb88102f2010-09-08 11:49:43 -07001538 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1539
1540 mAllocator.releaseEventEntry(cancelationEventEntry);
1541 }
1542 }
1543 }
1544
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001545 // This is a new event.
1546 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001547 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown519e0242010-09-15 15:18:56 -07001548 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1549 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001550 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001551 }
1552
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001553 // Handle the case where we could not stream a new motion sample because the consumer has
1554 // already consumed the motion event (otherwise the corresponding dispatch entry would
1555 // still be in the outbound queue for this connection). We set the head motion sample
1556 // to the list starting with the newly appended motion sample.
1557 if (resumeWithAppendedMotionSample) {
1558#if DEBUG_BATCHING
1559 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1560 "that cannot be streamed because the motion event has already been consumed.",
1561 connection->getInputChannelName());
1562#endif
1563 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1564 dispatchEntry->headMotionSample = appendedMotionSample;
1565 }
1566
1567 // Enqueue the dispatch entry.
1568 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1569
1570 // If the outbound queue was previously empty, start the dispatch cycle going.
1571 if (wasEmpty) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001572 activateConnectionLocked(connection.get());
Jeff Brown519e0242010-09-15 15:18:56 -07001573 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001574 }
1575}
1576
Jeff Brown7fbdc842010-06-17 20:52:56 -07001577void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001578 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001579#if DEBUG_DISPATCH_CYCLE
1580 LOGD("channel '%s' ~ startDispatchCycle",
1581 connection->getInputChannelName());
1582#endif
1583
1584 assert(connection->status == Connection::STATUS_NORMAL);
1585 assert(! connection->outboundQueue.isEmpty());
1586
Jeff Brownb88102f2010-09-08 11:49:43 -07001587 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001588 assert(! dispatchEntry->inProgress);
1589
Jeff Brownb88102f2010-09-08 11:49:43 -07001590 // Mark the dispatch entry as in progress.
1591 dispatchEntry->inProgress = true;
1592
1593 // Update the connection's input state.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001594 EventEntry* eventEntry = dispatchEntry->eventEntry;
1595 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001596
1597#if FILTER_INPUT_EVENTS
1598 // Filter out inconsistent sequences of input events.
1599 // The input system may drop or inject events in a way that could violate implicit
1600 // invariants on input state and potentially cause an application to crash
1601 // or think that a key or pointer is stuck down. Technically we make no guarantees
1602 // of consistency but it would be nice to improve on this where possible.
1603 // XXX: This code is a proof of concept only. Not ready for prime time.
1604 if (consistency == InputState::TOLERABLE) {
1605#if DEBUG_DISPATCH_CYCLE
1606 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1607 "current input state but that is likely to be tolerated by the application.",
1608 connection->getInputChannelName());
1609#endif
1610 } else if (consistency == InputState::BROKEN) {
1611 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1612 "current input state and that is likely to cause the application to crash.",
1613 connection->getInputChannelName());
1614 startNextDispatchCycleLocked(currentTime, connection);
1615 return;
1616 }
1617#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001618
1619 // Publish the event.
1620 status_t status;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001621 switch (eventEntry->type) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001622 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001623 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001624
1625 // Apply target flags.
1626 int32_t action = keyEntry->action;
1627 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001628
1629 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001630 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001631 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1632 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1633 keyEntry->eventTime);
1634
1635 if (status) {
1636 LOGE("channel '%s' ~ Could not publish key event, "
1637 "status=%d", connection->getInputChannelName(), status);
1638 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1639 return;
1640 }
1641 break;
1642 }
1643
1644 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001645 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001646
1647 // Apply target flags.
1648 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001649 int32_t flags = motionEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001650 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001651 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001652 }
Jeff Brown85a31762010-09-01 17:01:00 -07001653 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1654 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1655 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001656
1657 // If headMotionSample is non-NULL, then it points to the first new sample that we
1658 // were unable to dispatch during the previous cycle so we resume dispatching from
1659 // that point in the list of motion samples.
1660 // Otherwise, we just start from the first sample of the motion event.
1661 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1662 if (! firstMotionSample) {
1663 firstMotionSample = & motionEntry->firstSample;
1664 }
1665
Jeff Brownd3616592010-07-16 17:21:06 -07001666 // Set the X and Y offset depending on the input source.
1667 float xOffset, yOffset;
1668 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1669 xOffset = dispatchEntry->xOffset;
1670 yOffset = dispatchEntry->yOffset;
1671 } else {
1672 xOffset = 0.0f;
1673 yOffset = 0.0f;
1674 }
1675
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001676 // Publish the motion event and the first motion sample.
1677 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07001678 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownd3616592010-07-16 17:21:06 -07001679 xOffset, yOffset,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001680 motionEntry->xPrecision, motionEntry->yPrecision,
1681 motionEntry->downTime, firstMotionSample->eventTime,
1682 motionEntry->pointerCount, motionEntry->pointerIds,
1683 firstMotionSample->pointerCoords);
1684
1685 if (status) {
1686 LOGE("channel '%s' ~ Could not publish motion event, "
1687 "status=%d", connection->getInputChannelName(), status);
1688 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1689 return;
1690 }
1691
1692 // Append additional motion samples.
1693 MotionSample* nextMotionSample = firstMotionSample->next;
1694 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1695 status = connection->inputPublisher.appendMotionSample(
1696 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1697 if (status == NO_MEMORY) {
1698#if DEBUG_DISPATCH_CYCLE
1699 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1700 "be sent in the next dispatch cycle.",
1701 connection->getInputChannelName());
1702#endif
1703 break;
1704 }
1705 if (status != OK) {
1706 LOGE("channel '%s' ~ Could not append motion sample "
1707 "for a reason other than out of memory, status=%d",
1708 connection->getInputChannelName(), status);
1709 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1710 return;
1711 }
1712 }
1713
1714 // Remember the next motion sample that we could not dispatch, in case we ran out
1715 // of space in the shared memory buffer.
1716 dispatchEntry->tailMotionSample = nextMotionSample;
1717 break;
1718 }
1719
1720 default: {
1721 assert(false);
1722 }
1723 }
1724
1725 // Send the dispatch signal.
1726 status = connection->inputPublisher.sendDispatchSignal();
1727 if (status) {
1728 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1729 connection->getInputChannelName(), status);
1730 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1731 return;
1732 }
1733
1734 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001735 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001736 connection->lastDispatchTime = currentTime;
1737
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001738 // Notify other system components.
1739 onDispatchCycleStartedLocked(currentTime, connection);
1740}
1741
Jeff Brown7fbdc842010-06-17 20:52:56 -07001742void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1743 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001744#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001745 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001746 "%01.1fms since dispatch",
1747 connection->getInputChannelName(),
1748 connection->getEventLatencyMillis(currentTime),
1749 connection->getDispatchLatencyMillis(currentTime));
1750#endif
1751
Jeff Brown9c3cda02010-06-15 01:31:58 -07001752 if (connection->status == Connection::STATUS_BROKEN
1753 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001754 return;
1755 }
1756
Jeff Brown519e0242010-09-15 15:18:56 -07001757 // Notify other system components.
1758 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001759
1760 // Reset the publisher since the event has been consumed.
1761 // We do this now so that the publisher can release some of its internal resources
1762 // while waiting for the next dispatch cycle to begin.
1763 status_t status = connection->inputPublisher.reset();
1764 if (status) {
1765 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1766 connection->getInputChannelName(), status);
1767 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1768 return;
1769 }
1770
Jeff Brownb88102f2010-09-08 11:49:43 -07001771 startNextDispatchCycleLocked(currentTime, connection);
1772}
1773
1774void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1775 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001776 // Start the next dispatch cycle for this connection.
1777 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001778 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001779 if (dispatchEntry->inProgress) {
1780 // Finish or resume current event in progress.
1781 if (dispatchEntry->tailMotionSample) {
1782 // We have a tail of undispatched motion samples.
1783 // Reuse the same DispatchEntry and start a new cycle.
1784 dispatchEntry->inProgress = false;
1785 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1786 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07001787 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001788 return;
1789 }
1790 // Finished.
1791 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07001792 if (dispatchEntry->hasForegroundTarget()) {
1793 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001794 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001795 mAllocator.releaseDispatchEntry(dispatchEntry);
1796 } else {
1797 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07001798 // progress event, which means we actually aborted it.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001799 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07001800 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001801 return;
1802 }
1803 }
1804
1805 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07001806 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001807}
1808
Jeff Brown7fbdc842010-06-17 20:52:56 -07001809void InputDispatcher::abortDispatchCycleLocked(nsecs_t currentTime,
1810 const sp<Connection>& connection, bool broken) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001811#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001812 LOGD("channel '%s' ~ abortDispatchCycle - broken=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001813 connection->getInputChannelName(), toString(broken));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001814#endif
1815
Jeff Brownb88102f2010-09-08 11:49:43 -07001816 // Input state will no longer be realistic.
1817 connection->inputState.setOutOfSync();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001818
Jeff Brownb88102f2010-09-08 11:49:43 -07001819 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07001820 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001821
1822 // Handle the case where the connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07001823 // Ignore already broken or zombie connections.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001824 if (broken) {
Jeff Brown519e0242010-09-15 15:18:56 -07001825 if (connection->status == Connection::STATUS_NORMAL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07001826 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001827
Jeff Brown9c3cda02010-06-15 01:31:58 -07001828 // Notify other system components.
1829 onDispatchCycleBrokenLocked(currentTime, connection);
1830 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001831 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001832}
1833
Jeff Brown519e0242010-09-15 15:18:56 -07001834void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1835 while (! connection->outboundQueue.isEmpty()) {
1836 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1837 if (dispatchEntry->hasForegroundTarget()) {
1838 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001839 }
1840 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001841 }
1842
Jeff Brown519e0242010-09-15 15:18:56 -07001843 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07001844}
1845
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001846int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001847 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1848
1849 { // acquire lock
1850 AutoMutex _l(d->mLock);
1851
1852 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1853 if (connectionIndex < 0) {
1854 LOGE("Received spurious receive callback for unknown input channel. "
1855 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001856 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001857 }
1858
Jeff Brown7fbdc842010-06-17 20:52:56 -07001859 nsecs_t currentTime = now();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001860
1861 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001862 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001863 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1864 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001865 d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001866 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001867 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001868 }
1869
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001870 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001871 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1872 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001873 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001874 }
1875
1876 status_t status = connection->inputPublisher.receiveFinishedSignal();
1877 if (status) {
1878 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1879 connection->getInputChannelName(), status);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001880 d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001881 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001882 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001883 }
1884
Jeff Brown7fbdc842010-06-17 20:52:56 -07001885 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001886 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001887 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001888 } // release lock
1889}
1890
Jeff Brown01ce2e92010-09-26 22:20:12 -07001891InputDispatcher::MotionEntry*
1892InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1893 assert(pointerIds.value != 0);
1894
1895 uint32_t splitPointerIndexMap[MAX_POINTERS];
1896 int32_t splitPointerIds[MAX_POINTERS];
1897 PointerCoords splitPointerCoords[MAX_POINTERS];
1898
1899 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1900 uint32_t splitPointerCount = 0;
1901
1902 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1903 originalPointerIndex++) {
1904 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1905 if (pointerIds.hasBit(pointerId)) {
1906 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1907 splitPointerIds[splitPointerCount] = pointerId;
1908 splitPointerCoords[splitPointerCount] =
1909 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1910 splitPointerCount += 1;
1911 }
1912 }
1913 assert(splitPointerCount == pointerIds.count());
1914
1915 int32_t action = originalMotionEntry->action;
1916 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1917 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
1918 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1919 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
1920 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
1921 if (pointerIds.hasBit(pointerId)) {
1922 if (pointerIds.count() == 1) {
1923 // The first/last pointer went down/up.
1924 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
1925 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07001926 } else {
1927 // A secondary pointer went down/up.
1928 uint32_t splitPointerIndex = 0;
1929 while (pointerId != splitPointerIds[splitPointerIndex]) {
1930 splitPointerIndex += 1;
1931 }
1932 action = maskedAction | (splitPointerIndex
1933 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07001934 }
1935 } else {
1936 // An unrelated pointer changed.
1937 action = AMOTION_EVENT_ACTION_MOVE;
1938 }
1939 }
1940
1941 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
1942 originalMotionEntry->eventTime,
1943 originalMotionEntry->deviceId,
1944 originalMotionEntry->source,
1945 originalMotionEntry->policyFlags,
1946 action,
1947 originalMotionEntry->flags,
1948 originalMotionEntry->metaState,
1949 originalMotionEntry->edgeFlags,
1950 originalMotionEntry->xPrecision,
1951 originalMotionEntry->yPrecision,
1952 originalMotionEntry->downTime,
1953 splitPointerCount, splitPointerIds, splitPointerCoords);
1954
1955 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
1956 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
1957 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
1958 splitPointerIndex++) {
1959 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
1960 splitPointerCoords[splitPointerIndex] =
1961 originalMotionSample->pointerCoords[originalPointerIndex];
1962 }
1963
1964 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
1965 splitPointerCoords);
1966 }
1967
1968 return splitMotionEntry;
1969}
1970
Jeff Brown9c3cda02010-06-15 01:31:58 -07001971void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001972#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07001973 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001974#endif
1975
Jeff Brownb88102f2010-09-08 11:49:43 -07001976 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001977 { // acquire lock
1978 AutoMutex _l(mLock);
1979
Jeff Brown7fbdc842010-06-17 20:52:56 -07001980 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001981 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001982 } // release lock
1983
Jeff Brownb88102f2010-09-08 11:49:43 -07001984 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001985 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001986 }
1987}
1988
Jeff Brownc5ed5912010-07-14 18:48:53 -07001989void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001990 uint32_t policyFlags, int32_t action, int32_t flags,
1991 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
1992#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brownc5ed5912010-07-14 18:48:53 -07001993 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001994 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07001995 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001996 keyCode, scanCode, metaState, downTime);
1997#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001998 if (! validateKeyEvent(action)) {
1999 return;
2000 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002001
Jeff Brownb88102f2010-09-08 11:49:43 -07002002 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002003 { // acquire lock
2004 AutoMutex _l(mLock);
2005
Jeff Brown7fbdc842010-06-17 20:52:56 -07002006 int32_t repeatCount = 0;
2007 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002008 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002009 metaState, repeatCount, downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002010
Jeff Brownb88102f2010-09-08 11:49:43 -07002011 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002012 } // release lock
2013
Jeff Brownb88102f2010-09-08 11:49:43 -07002014 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002015 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002016 }
2017}
2018
Jeff Brownc5ed5912010-07-14 18:48:53 -07002019void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002020 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002021 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2022 float xPrecision, float yPrecision, nsecs_t downTime) {
2023#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brownc5ed5912010-07-14 18:48:53 -07002024 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002025 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2026 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2027 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002028 xPrecision, yPrecision, downTime);
2029 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002030 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002031 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002032 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002033 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown8d608662010-08-30 03:02:23 -07002034 pointerCoords[i].pressure, pointerCoords[i].size,
2035 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2036 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2037 pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002038 }
2039#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002040 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2041 return;
2042 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002043
Jeff Brownb88102f2010-09-08 11:49:43 -07002044 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002045 { // acquire lock
2046 AutoMutex _l(mLock);
2047
2048 // Attempt batching and streaming of move events.
Jeff Brownc5ed5912010-07-14 18:48:53 -07002049 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002050 // BATCHING CASE
2051 //
2052 // Try to append a move sample to the tail of the inbound queue for this device.
2053 // Give up if we encounter a non-move motion event for this device since that
2054 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002055 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2056 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002057 if (entry->type != EventEntry::TYPE_MOTION) {
2058 // Keep looking for motion events.
2059 continue;
2060 }
2061
2062 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2063 if (motionEntry->deviceId != deviceId) {
2064 // Keep looking for this device.
2065 continue;
2066 }
2067
Jeff Brownc5ed5912010-07-14 18:48:53 -07002068 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown7fbdc842010-06-17 20:52:56 -07002069 || motionEntry->pointerCount != pointerCount
2070 || motionEntry->isInjected()) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002071 // Last motion event in the queue for this device is not compatible for
2072 // appending new samples. Stop here.
2073 goto NoBatchingOrStreaming;
2074 }
2075
2076 // The last motion event is a move and is compatible for appending.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002077 // Do the batching magic.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002078 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002079#if DEBUG_BATCHING
2080 LOGD("Appended motion sample onto batch for most recent "
2081 "motion event for this device in the inbound queue.");
2082#endif
Jeff Brown9c3cda02010-06-15 01:31:58 -07002083 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002084 }
2085
2086 // STREAMING CASE
2087 //
2088 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002089 // Search the outbound queue for the current foreground targets to find a dispatched
2090 // motion event that is still in progress. If found, then, appen the new sample to
2091 // that event and push it out to all current targets. The logic in
2092 // prepareDispatchCycleLocked takes care of the case where some targets may
2093 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002094 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002095 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2096 const InputTarget& inputTarget = mCurrentInputTargets[i];
2097 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2098 // Skip non-foreground targets. We only want to stream if there is at
2099 // least one foreground target whose dispatch is still in progress.
2100 continue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002101 }
Jeff Brown519e0242010-09-15 15:18:56 -07002102
2103 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2104 if (connectionIndex < 0) {
2105 // Connection must no longer be valid.
2106 continue;
2107 }
2108
2109 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2110 if (connection->outboundQueue.isEmpty()) {
2111 // This foreground target has an empty outbound queue.
2112 continue;
2113 }
2114
2115 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2116 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002117 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2118 || dispatchEntry->isSplit()) {
2119 // No motion event is being dispatched, or it is being split across
2120 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002121 continue;
2122 }
2123
2124 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2125 dispatchEntry->eventEntry);
2126 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2127 || motionEntry->deviceId != deviceId
2128 || motionEntry->pointerCount != pointerCount
2129 || motionEntry->isInjected()) {
2130 // The motion event is not compatible with this move.
2131 continue;
2132 }
2133
2134 // Hurray! This foreground target is currently dispatching a move event
2135 // that we can stream onto. Append the motion sample and resume dispatch.
2136 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2137#if DEBUG_BATCHING
2138 LOGD("Appended motion sample onto batch for most recently dispatched "
2139 "motion event for this device in the outbound queues. "
2140 "Attempting to stream the motion sample.");
2141#endif
2142 nsecs_t currentTime = now();
2143 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2144 true /*resumeWithAppendedMotionSample*/);
2145
2146 runCommandsLockedInterruptible();
2147 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002148 }
2149 }
2150
2151NoBatchingOrStreaming:;
2152 }
2153
2154 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002155 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002156 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002157 xPrecision, yPrecision, downTime,
2158 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002159
Jeff Brownb88102f2010-09-08 11:49:43 -07002160 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002161 } // release lock
2162
Jeff Brownb88102f2010-09-08 11:49:43 -07002163 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002164 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002165 }
2166}
2167
Jeff Brown7fbdc842010-06-17 20:52:56 -07002168int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002169 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002170#if DEBUG_INBOUND_EVENT_DETAILS
2171 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002172 "syncMode=%d, timeoutMillis=%d",
2173 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002174#endif
2175
2176 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2177
Jeff Brown01ce2e92010-09-26 22:20:12 -07002178 InjectionState* injectionState;
Jeff Brownb88102f2010-09-08 11:49:43 -07002179 bool needWake;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002180 { // acquire lock
2181 AutoMutex _l(mLock);
2182
Jeff Brown01ce2e92010-09-26 22:20:12 -07002183 EventEntry* injectedEntry = createEntryFromInjectedInputEventLocked(event);
Jeff Brownb88102f2010-09-08 11:49:43 -07002184 if (! injectedEntry) {
2185 return INPUT_EVENT_INJECTION_FAILED;
2186 }
2187
Jeff Brown01ce2e92010-09-26 22:20:12 -07002188 injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002189 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002190 injectionState->injectionIsAsync = true;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002191 }
2192
Jeff Brown01ce2e92010-09-26 22:20:12 -07002193 injectionState->refCount += 1;
2194 injectedEntry->injectionState = injectionState;
2195
Jeff Brownb88102f2010-09-08 11:49:43 -07002196 needWake = enqueueInboundEventLocked(injectedEntry);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002197 } // release lock
2198
Jeff Brownb88102f2010-09-08 11:49:43 -07002199 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002200 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002201 }
2202
2203 int32_t injectionResult;
2204 { // acquire lock
2205 AutoMutex _l(mLock);
2206
Jeff Brown6ec402b2010-07-28 15:48:59 -07002207 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2208 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2209 } else {
2210 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002211 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002212 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2213 break;
2214 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002215
Jeff Brown7fbdc842010-06-17 20:52:56 -07002216 nsecs_t remainingTimeout = endTime - now();
2217 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002218#if DEBUG_INJECTION
2219 LOGD("injectInputEvent - Timed out waiting for injection result "
2220 "to become available.");
2221#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002222 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2223 break;
2224 }
2225
Jeff Brown6ec402b2010-07-28 15:48:59 -07002226 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2227 }
2228
2229 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2230 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002231 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002232#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002233 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002234 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002235#endif
2236 nsecs_t remainingTimeout = endTime - now();
2237 if (remainingTimeout <= 0) {
2238#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002239 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002240 "dispatches to finish.");
2241#endif
2242 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2243 break;
2244 }
2245
2246 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2247 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002248 }
2249 }
2250
Jeff Brown01ce2e92010-09-26 22:20:12 -07002251 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002252 } // release lock
2253
Jeff Brown6ec402b2010-07-28 15:48:59 -07002254#if DEBUG_INJECTION
2255 LOGD("injectInputEvent - Finished with result %d. "
2256 "injectorPid=%d, injectorUid=%d",
2257 injectionResult, injectorPid, injectorUid);
2258#endif
2259
Jeff Brown7fbdc842010-06-17 20:52:56 -07002260 return injectionResult;
2261}
2262
2263void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002264 InjectionState* injectionState = entry->injectionState;
2265 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002266#if DEBUG_INJECTION
2267 LOGD("Setting input event injection result to %d. "
2268 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002269 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002270#endif
2271
Jeff Brown01ce2e92010-09-26 22:20:12 -07002272 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002273 // Log the outcome since the injector did not wait for the injection result.
2274 switch (injectionResult) {
2275 case INPUT_EVENT_INJECTION_SUCCEEDED:
2276 LOGV("Asynchronous input event injection succeeded.");
2277 break;
2278 case INPUT_EVENT_INJECTION_FAILED:
2279 LOGW("Asynchronous input event injection failed.");
2280 break;
2281 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2282 LOGW("Asynchronous input event injection permission denied.");
2283 break;
2284 case INPUT_EVENT_INJECTION_TIMED_OUT:
2285 LOGW("Asynchronous input event injection timed out.");
2286 break;
2287 }
2288 }
2289
Jeff Brown01ce2e92010-09-26 22:20:12 -07002290 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002291 mInjectionResultAvailableCondition.broadcast();
2292 }
2293}
2294
Jeff Brown01ce2e92010-09-26 22:20:12 -07002295void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2296 InjectionState* injectionState = entry->injectionState;
2297 if (injectionState) {
2298 injectionState->pendingForegroundDispatches += 1;
2299 }
2300}
2301
Jeff Brown519e0242010-09-15 15:18:56 -07002302void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002303 InjectionState* injectionState = entry->injectionState;
2304 if (injectionState) {
2305 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002306
Jeff Brown01ce2e92010-09-26 22:20:12 -07002307 if (injectionState->pendingForegroundDispatches == 0) {
2308 mInjectionSyncFinishedCondition.broadcast();
2309 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002310 }
2311}
2312
2313InputDispatcher::EventEntry* InputDispatcher::createEntryFromInjectedInputEventLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002314 const InputEvent* event) {
2315 switch (event->getType()) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07002316 case AINPUT_EVENT_TYPE_KEY: {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002317 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002318 if (! validateKeyEvent(keyEvent->getAction())) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002319 return NULL;
2320 }
2321
Jeff Brown85a31762010-09-01 17:01:00 -07002322 uint32_t policyFlags = POLICY_FLAG_INJECTED;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002323
2324 KeyEntry* keyEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
Jeff Brownc5ed5912010-07-14 18:48:53 -07002325 keyEvent->getDeviceId(), keyEvent->getSource(), policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002326 keyEvent->getAction(), keyEvent->getFlags(),
2327 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
2328 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2329 return keyEntry;
2330 }
2331
Jeff Brownc5ed5912010-07-14 18:48:53 -07002332 case AINPUT_EVENT_TYPE_MOTION: {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002333 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002334 if (! validateMotionEvent(motionEvent->getAction(),
2335 motionEvent->getPointerCount(), motionEvent->getPointerIds())) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002336 return NULL;
2337 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002338
Jeff Brown85a31762010-09-01 17:01:00 -07002339 uint32_t policyFlags = POLICY_FLAG_INJECTED;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002340
2341 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2342 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2343 size_t pointerCount = motionEvent->getPointerCount();
2344
2345 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002346 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
Jeff Brown85a31762010-09-01 17:01:00 -07002347 motionEvent->getAction(), motionEvent->getFlags(),
2348 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
Jeff Brown7fbdc842010-06-17 20:52:56 -07002349 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2350 motionEvent->getDownTime(), uint32_t(pointerCount),
2351 motionEvent->getPointerIds(), samplePointerCoords);
2352 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2353 sampleEventTimes += 1;
2354 samplePointerCoords += pointerCount;
2355 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2356 }
2357 return motionEntry;
2358 }
2359
2360 default:
2361 assert(false);
2362 return NULL;
2363 }
2364}
2365
Jeff Brown01ce2e92010-09-26 22:20:12 -07002366const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2367 for (size_t i = 0; i < mWindows.size(); i++) {
2368 const InputWindow* window = & mWindows[i];
2369 if (window->inputChannel == inputChannel) {
2370 return window;
2371 }
2372 }
2373 return NULL;
2374}
2375
Jeff Brownb88102f2010-09-08 11:49:43 -07002376void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2377#if DEBUG_FOCUS
2378 LOGD("setInputWindows");
2379#endif
2380 { // acquire lock
2381 AutoMutex _l(mLock);
2382
Jeff Brown01ce2e92010-09-26 22:20:12 -07002383 // Clear old window pointers.
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002384 mFocusedWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07002385 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002386
2387 // Loop over new windows and rebuild the necessary window pointers for
2388 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002389 mWindows.appendVector(inputWindows);
2390
2391 size_t numWindows = mWindows.size();
2392 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002393 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002394 if (window->hasFocus) {
2395 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002396 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002397 }
2398 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002399
2400 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2401 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2402 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2403 if (window) {
2404 touchedWindow.window = window;
2405 i += 1;
2406 } else {
2407 mTouchState.windows.removeAt(i);
2408 }
2409 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002410
Jeff Brownb88102f2010-09-08 11:49:43 -07002411#if DEBUG_FOCUS
2412 logDispatchStateLocked();
2413#endif
2414 } // release lock
2415
2416 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002417 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002418}
2419
2420void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2421#if DEBUG_FOCUS
2422 LOGD("setFocusedApplication");
2423#endif
2424 { // acquire lock
2425 AutoMutex _l(mLock);
2426
2427 releaseFocusedApplicationLocked();
2428
2429 if (inputApplication) {
2430 mFocusedApplicationStorage = *inputApplication;
2431 mFocusedApplication = & mFocusedApplicationStorage;
2432 }
2433
2434#if DEBUG_FOCUS
2435 logDispatchStateLocked();
2436#endif
2437 } // release lock
2438
2439 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002440 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002441}
2442
2443void InputDispatcher::releaseFocusedApplicationLocked() {
2444 if (mFocusedApplication) {
2445 mFocusedApplication = NULL;
2446 mFocusedApplicationStorage.handle.clear();
2447 }
2448}
2449
2450void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2451#if DEBUG_FOCUS
2452 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2453#endif
2454
2455 bool changed;
2456 { // acquire lock
2457 AutoMutex _l(mLock);
2458
2459 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2460 if (mDispatchFrozen && ! frozen) {
2461 resetANRTimeoutsLocked();
2462 }
2463
2464 mDispatchEnabled = enabled;
2465 mDispatchFrozen = frozen;
2466 changed = true;
2467 } else {
2468 changed = false;
2469 }
2470
2471#if DEBUG_FOCUS
2472 logDispatchStateLocked();
2473#endif
2474 } // release lock
2475
2476 if (changed) {
2477 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002478 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002479 }
2480}
2481
Jeff Browne6504122010-09-27 14:52:15 -07002482bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2483 const sp<InputChannel>& toChannel) {
2484#if DEBUG_FOCUS
2485 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2486 fromChannel->getName().string(), toChannel->getName().string());
2487#endif
2488 { // acquire lock
2489 AutoMutex _l(mLock);
2490
2491 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2492 const InputWindow* toWindow = getWindowLocked(toChannel);
2493 if (! fromWindow || ! toWindow) {
2494#if DEBUG_FOCUS
2495 LOGD("Cannot transfer focus because from or to window not found.");
2496#endif
2497 return false;
2498 }
2499 if (fromWindow == toWindow) {
2500#if DEBUG_FOCUS
2501 LOGD("Trivial transfer to same window.");
2502#endif
2503 return true;
2504 }
2505
2506 bool found = false;
2507 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2508 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2509 if (touchedWindow.window == fromWindow) {
2510 int32_t oldTargetFlags = touchedWindow.targetFlags;
2511 BitSet32 pointerIds = touchedWindow.pointerIds;
2512
2513 mTouchState.windows.removeAt(i);
2514
2515 int32_t newTargetFlags = 0;
2516 if (oldTargetFlags & InputTarget::FLAG_FOREGROUND) {
2517 newTargetFlags |= InputTarget::FLAG_FOREGROUND;
2518 if (toWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) {
2519 newTargetFlags |= InputTarget::FLAG_SPLIT;
2520 }
2521 }
2522 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2523
2524 found = true;
2525 break;
2526 }
2527 }
2528
2529 if (! found) {
2530#if DEBUG_FOCUS
2531 LOGD("Focus transfer failed because from window did not have focus.");
2532#endif
2533 return false;
2534 }
2535
2536#if DEBUG_FOCUS
2537 logDispatchStateLocked();
2538#endif
2539 } // release lock
2540
2541 // Wake up poll loop since it may need to make new input dispatching choices.
2542 mLooper->wake();
2543 return true;
2544}
2545
Jeff Brownb88102f2010-09-08 11:49:43 -07002546void InputDispatcher::logDispatchStateLocked() {
2547 String8 dump;
2548 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002549
2550 char* text = dump.lockBuffer(dump.size());
2551 char* start = text;
2552 while (*start != '\0') {
2553 char* end = strchr(start, '\n');
2554 if (*end == '\n') {
2555 *(end++) = '\0';
2556 }
2557 LOGD("%s", start);
2558 start = end;
2559 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002560}
2561
2562void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002563 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2564 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07002565
2566 if (mFocusedApplication) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002567 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002568 mFocusedApplication->name.string(),
2569 mFocusedApplication->dispatchingTimeout / 1000000.0);
2570 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002571 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002572 }
Jeff Brownf2f487182010-10-01 17:46:21 -07002573 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002574 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f487182010-10-01 17:46:21 -07002575
2576 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2577 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2578 if (!mTouchState.windows.isEmpty()) {
2579 dump.append(INDENT "TouchedWindows:\n");
2580 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2581 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2582 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2583 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2584 touchedWindow.targetFlags);
2585 }
2586 } else {
2587 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002588 }
2589
Jeff Brownf2f487182010-10-01 17:46:21 -07002590 if (!mWindows.isEmpty()) {
2591 dump.append(INDENT "Windows:\n");
2592 for (size_t i = 0; i < mWindows.size(); i++) {
2593 const InputWindow& window = mWindows[i];
2594 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2595 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2596 "frame=[%d,%d][%d,%d], "
2597 "visibleFrame=[%d,%d][%d,%d], "
2598 "touchableArea=[%d,%d][%d,%d], "
2599 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2600 i, window.name.string(),
2601 toString(window.paused),
2602 toString(window.hasFocus),
2603 toString(window.hasWallpaper),
2604 toString(window.visible),
2605 toString(window.canReceiveKeys),
2606 window.layoutParamsFlags, window.layoutParamsType,
2607 window.layer,
2608 window.frameLeft, window.frameTop,
2609 window.frameRight, window.frameBottom,
2610 window.visibleFrameLeft, window.visibleFrameTop,
2611 window.visibleFrameRight, window.visibleFrameBottom,
2612 window.touchableAreaLeft, window.touchableAreaTop,
2613 window.touchableAreaRight, window.touchableAreaBottom,
2614 window.ownerPid, window.ownerUid,
2615 window.dispatchingTimeout / 1000000.0);
2616 }
2617 } else {
2618 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002619 }
2620
Jeff Brownf2f487182010-10-01 17:46:21 -07002621 if (!mMonitoringChannels.isEmpty()) {
2622 dump.append(INDENT "MonitoringChannels:\n");
2623 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2624 const sp<InputChannel>& channel = mMonitoringChannels[i];
2625 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2626 }
2627 } else {
2628 dump.append(INDENT "MonitoringChannels: <none>\n");
2629 }
Jeff Brown519e0242010-09-15 15:18:56 -07002630
Jeff Brownf2f487182010-10-01 17:46:21 -07002631 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2632
2633 if (!mActiveConnections.isEmpty()) {
2634 dump.append(INDENT "ActiveConnections:\n");
2635 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2636 const Connection* connection = mActiveConnections[i];
2637 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
2638 "inputState.isNeutral=%s, inputState.isOutOfSync=%s\n",
2639 i, connection->getInputChannelName(), connection->getStatusLabel(),
2640 connection->outboundQueue.count(),
2641 toString(connection->inputState.isNeutral()),
2642 toString(connection->inputState.isOutOfSync()));
2643 }
2644 } else {
2645 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002646 }
2647
2648 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002649 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002650 (mAppSwitchDueTime - now()) / 1000000.0);
2651 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002652 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002653 }
2654}
2655
2656status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002657#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07002658 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2659 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07002660#endif
2661
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002662 { // acquire lock
2663 AutoMutex _l(mLock);
2664
Jeff Brown519e0242010-09-15 15:18:56 -07002665 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002666 LOGW("Attempted to register already registered input channel '%s'",
2667 inputChannel->getName().string());
2668 return BAD_VALUE;
2669 }
2670
2671 sp<Connection> connection = new Connection(inputChannel);
2672 status_t status = connection->initialize();
2673 if (status) {
2674 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2675 inputChannel->getName().string(), status);
2676 return status;
2677 }
2678
Jeff Brown2cbecea2010-08-17 15:59:26 -07002679 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002680 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002681
Jeff Brownb88102f2010-09-08 11:49:43 -07002682 if (monitor) {
2683 mMonitoringChannels.push(inputChannel);
2684 }
2685
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002686 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07002687
Jeff Brown9c3cda02010-06-15 01:31:58 -07002688 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002689 } // release lock
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002690 return OK;
2691}
2692
2693status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002694#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07002695 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07002696#endif
2697
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002698 { // acquire lock
2699 AutoMutex _l(mLock);
2700
Jeff Brown519e0242010-09-15 15:18:56 -07002701 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002702 if (connectionIndex < 0) {
2703 LOGW("Attempted to unregister already unregistered input channel '%s'",
2704 inputChannel->getName().string());
2705 return BAD_VALUE;
2706 }
2707
2708 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2709 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2710
2711 connection->status = Connection::STATUS_ZOMBIE;
2712
Jeff Brownb88102f2010-09-08 11:49:43 -07002713 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2714 if (mMonitoringChannels[i] == inputChannel) {
2715 mMonitoringChannels.removeAt(i);
2716 break;
2717 }
2718 }
2719
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002720 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07002721
Jeff Brown7fbdc842010-06-17 20:52:56 -07002722 nsecs_t currentTime = now();
2723 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002724
2725 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002726 } // release lock
2727
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002728 // Wake the poll loop because removing the connection may have changed the current
2729 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002730 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002731 return OK;
2732}
2733
Jeff Brown519e0242010-09-15 15:18:56 -07002734ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07002735 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2736 if (connectionIndex >= 0) {
2737 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2738 if (connection->inputChannel.get() == inputChannel.get()) {
2739 return connectionIndex;
2740 }
2741 }
2742
2743 return -1;
2744}
2745
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002746void InputDispatcher::activateConnectionLocked(Connection* connection) {
2747 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2748 if (mActiveConnections.itemAt(i) == connection) {
2749 return;
2750 }
2751 }
2752 mActiveConnections.add(connection);
2753}
2754
2755void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2756 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2757 if (mActiveConnections.itemAt(i) == connection) {
2758 mActiveConnections.removeAt(i);
2759 return;
2760 }
2761 }
2762}
2763
Jeff Brown9c3cda02010-06-15 01:31:58 -07002764void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002765 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002766}
2767
Jeff Brown9c3cda02010-06-15 01:31:58 -07002768void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002769 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002770}
2771
Jeff Brown9c3cda02010-06-15 01:31:58 -07002772void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002773 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002774 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2775 connection->getInputChannelName());
2776
Jeff Brown9c3cda02010-06-15 01:31:58 -07002777 CommandEntry* commandEntry = postCommandLocked(
2778 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002779 commandEntry->connection = connection;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002780}
2781
Jeff Brown519e0242010-09-15 15:18:56 -07002782void InputDispatcher::onANRLocked(
2783 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2784 nsecs_t eventTime, nsecs_t waitStartTime) {
2785 LOGI("Application is not responding: %s. "
2786 "%01.1fms since event, %01.1fms since wait started",
2787 getApplicationWindowLabelLocked(application, window).string(),
2788 (currentTime - eventTime) / 1000000.0,
2789 (currentTime - waitStartTime) / 1000000.0);
2790
2791 CommandEntry* commandEntry = postCommandLocked(
2792 & InputDispatcher::doNotifyANRLockedInterruptible);
2793 if (application) {
2794 commandEntry->inputApplicationHandle = application->handle;
2795 }
2796 if (window) {
2797 commandEntry->inputChannel = window->inputChannel;
2798 }
2799}
2800
Jeff Brownb88102f2010-09-08 11:49:43 -07002801void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2802 CommandEntry* commandEntry) {
2803 mLock.unlock();
2804
2805 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2806
2807 mLock.lock();
2808}
2809
Jeff Brown9c3cda02010-06-15 01:31:58 -07002810void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2811 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002812 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07002813
Jeff Brown7fbdc842010-06-17 20:52:56 -07002814 if (connection->status != Connection::STATUS_ZOMBIE) {
2815 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002816
Jeff Brown7fbdc842010-06-17 20:52:56 -07002817 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2818
2819 mLock.lock();
2820 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07002821}
2822
Jeff Brown519e0242010-09-15 15:18:56 -07002823void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07002824 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07002825 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002826
Jeff Brown519e0242010-09-15 15:18:56 -07002827 nsecs_t newTimeout = mPolicy->notifyANR(
2828 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002829
Jeff Brown519e0242010-09-15 15:18:56 -07002830 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002831
Jeff Brown519e0242010-09-15 15:18:56 -07002832 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002833}
2834
Jeff Brownb88102f2010-09-08 11:49:43 -07002835void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2836 CommandEntry* commandEntry) {
2837 KeyEntry* entry = commandEntry->keyEntry;
2838 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2839 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2840 entry->downTime, entry->eventTime);
2841
2842 mLock.unlock();
2843
2844 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2845 & mReusableKeyEvent, entry->policyFlags);
2846
2847 mLock.lock();
2848
2849 entry->interceptKeyResult = consumed
2850 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2851 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2852 mAllocator.releaseKeyEntry(entry);
2853}
2854
2855void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2856 mLock.unlock();
2857
Jeff Brown01ce2e92010-09-26 22:20:12 -07002858 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07002859
2860 mLock.lock();
2861}
2862
Jeff Brown519e0242010-09-15 15:18:56 -07002863void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
2864 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
2865 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07002866}
2867
2868void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002869 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002870 dumpDispatchStateLocked(dump);
2871}
2872
Jeff Brown9c3cda02010-06-15 01:31:58 -07002873
Jeff Brown519e0242010-09-15 15:18:56 -07002874// --- InputDispatcher::Queue ---
2875
2876template <typename T>
2877uint32_t InputDispatcher::Queue<T>::count() const {
2878 uint32_t result = 0;
2879 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
2880 result += 1;
2881 }
2882 return result;
2883}
2884
2885
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002886// --- InputDispatcher::Allocator ---
2887
2888InputDispatcher::Allocator::Allocator() {
2889}
2890
Jeff Brown01ce2e92010-09-26 22:20:12 -07002891InputDispatcher::InjectionState*
2892InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
2893 InjectionState* injectionState = mInjectionStatePool.alloc();
2894 injectionState->refCount = 1;
2895 injectionState->injectorPid = injectorPid;
2896 injectionState->injectorUid = injectorUid;
2897 injectionState->injectionIsAsync = false;
2898 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
2899 injectionState->pendingForegroundDispatches = 0;
2900 return injectionState;
2901}
2902
Jeff Brown7fbdc842010-06-17 20:52:56 -07002903void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
2904 nsecs_t eventTime) {
2905 entry->type = type;
2906 entry->refCount = 1;
2907 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07002908 entry->eventTime = eventTime;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002909 entry->injectionState = NULL;
2910}
2911
2912void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
2913 if (entry->injectionState) {
2914 releaseInjectionState(entry->injectionState);
2915 entry->injectionState = NULL;
2916 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002917}
2918
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002919InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07002920InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002921 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002922 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002923 return entry;
2924}
2925
Jeff Brown7fbdc842010-06-17 20:52:56 -07002926InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002927 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002928 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
2929 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002930 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002931 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime);
2932
2933 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07002934 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002935 entry->policyFlags = policyFlags;
2936 entry->action = action;
2937 entry->flags = flags;
2938 entry->keyCode = keyCode;
2939 entry->scanCode = scanCode;
2940 entry->metaState = metaState;
2941 entry->repeatCount = repeatCount;
2942 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07002943 entry->syntheticRepeat = false;
2944 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002945 return entry;
2946}
2947
Jeff Brown7fbdc842010-06-17 20:52:56 -07002948InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002949 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002950 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
2951 nsecs_t downTime, uint32_t pointerCount,
2952 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002953 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002954 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime);
2955
2956 entry->eventTime = eventTime;
2957 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07002958 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002959 entry->policyFlags = policyFlags;
2960 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07002961 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002962 entry->metaState = metaState;
2963 entry->edgeFlags = edgeFlags;
2964 entry->xPrecision = xPrecision;
2965 entry->yPrecision = yPrecision;
2966 entry->downTime = downTime;
2967 entry->pointerCount = pointerCount;
2968 entry->firstSample.eventTime = eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002969 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002970 entry->lastSample = & entry->firstSample;
2971 for (uint32_t i = 0; i < pointerCount; i++) {
2972 entry->pointerIds[i] = pointerIds[i];
2973 entry->firstSample.pointerCoords[i] = pointerCoords[i];
2974 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002975 return entry;
2976}
2977
2978InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07002979 EventEntry* eventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07002980 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002981 DispatchEntry* entry = mDispatchEntryPool.alloc();
2982 entry->eventEntry = eventEntry;
2983 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07002984 entry->targetFlags = targetFlags;
2985 entry->xOffset = xOffset;
2986 entry->yOffset = yOffset;
Jeff Brownb88102f2010-09-08 11:49:43 -07002987 entry->inProgress = false;
2988 entry->headMotionSample = NULL;
2989 entry->tailMotionSample = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002990 return entry;
2991}
2992
Jeff Brown9c3cda02010-06-15 01:31:58 -07002993InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
2994 CommandEntry* entry = mCommandEntryPool.alloc();
2995 entry->command = command;
2996 return entry;
2997}
2998
Jeff Brown01ce2e92010-09-26 22:20:12 -07002999void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3000 injectionState->refCount -= 1;
3001 if (injectionState->refCount == 0) {
3002 mInjectionStatePool.free(injectionState);
3003 } else {
3004 assert(injectionState->refCount > 0);
3005 }
3006}
3007
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003008void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3009 switch (entry->type) {
3010 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3011 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3012 break;
3013 case EventEntry::TYPE_KEY:
3014 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3015 break;
3016 case EventEntry::TYPE_MOTION:
3017 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3018 break;
3019 default:
3020 assert(false);
3021 break;
3022 }
3023}
3024
3025void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3026 ConfigurationChangedEntry* entry) {
3027 entry->refCount -= 1;
3028 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003029 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003030 mConfigurationChangeEntryPool.free(entry);
3031 } else {
3032 assert(entry->refCount > 0);
3033 }
3034}
3035
3036void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3037 entry->refCount -= 1;
3038 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003039 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003040 mKeyEntryPool.free(entry);
3041 } else {
3042 assert(entry->refCount > 0);
3043 }
3044}
3045
3046void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3047 entry->refCount -= 1;
3048 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003049 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003050 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3051 MotionSample* next = sample->next;
3052 mMotionSamplePool.free(sample);
3053 sample = next;
3054 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003055 mMotionEntryPool.free(entry);
3056 } else {
3057 assert(entry->refCount > 0);
3058 }
3059}
3060
3061void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3062 releaseEventEntry(entry->eventEntry);
3063 mDispatchEntryPool.free(entry);
3064}
3065
Jeff Brown9c3cda02010-06-15 01:31:58 -07003066void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3067 mCommandEntryPool.free(entry);
3068}
3069
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003070void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003071 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003072 MotionSample* sample = mMotionSamplePool.alloc();
3073 sample->eventTime = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003074 uint32_t pointerCount = motionEntry->pointerCount;
3075 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003076 sample->pointerCoords[i] = pointerCoords[i];
3077 }
3078
3079 sample->next = NULL;
3080 motionEntry->lastSample->next = sample;
3081 motionEntry->lastSample = sample;
3082}
3083
Jeff Brown01ce2e92010-09-26 22:20:12 -07003084void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3085 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003086
Jeff Brown01ce2e92010-09-26 22:20:12 -07003087 keyEntry->dispatchInProgress = false;
3088 keyEntry->syntheticRepeat = false;
3089 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003090}
3091
3092
Jeff Brownae9fc032010-08-18 15:51:08 -07003093// --- InputDispatcher::MotionEntry ---
3094
3095uint32_t InputDispatcher::MotionEntry::countSamples() const {
3096 uint32_t count = 1;
3097 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3098 count += 1;
3099 }
3100 return count;
3101}
3102
Jeff Brownb88102f2010-09-08 11:49:43 -07003103
3104// --- InputDispatcher::InputState ---
3105
3106InputDispatcher::InputState::InputState() :
3107 mIsOutOfSync(false) {
3108}
3109
3110InputDispatcher::InputState::~InputState() {
3111}
3112
3113bool InputDispatcher::InputState::isNeutral() const {
3114 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3115}
3116
3117bool InputDispatcher::InputState::isOutOfSync() const {
3118 return mIsOutOfSync;
3119}
3120
3121void InputDispatcher::InputState::setOutOfSync() {
3122 if (! isNeutral()) {
3123 mIsOutOfSync = true;
3124 }
3125}
3126
3127void InputDispatcher::InputState::resetOutOfSync() {
3128 mIsOutOfSync = false;
3129}
3130
3131InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3132 const EventEntry* entry) {
3133 switch (entry->type) {
3134 case EventEntry::TYPE_KEY:
3135 return trackKey(static_cast<const KeyEntry*>(entry));
3136
3137 case EventEntry::TYPE_MOTION:
3138 return trackMotion(static_cast<const MotionEntry*>(entry));
3139
3140 default:
3141 return CONSISTENT;
3142 }
3143}
3144
3145InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3146 const KeyEntry* entry) {
3147 int32_t action = entry->action;
3148 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3149 KeyMemento& memento = mKeyMementos.editItemAt(i);
3150 if (memento.deviceId == entry->deviceId
3151 && memento.source == entry->source
3152 && memento.keyCode == entry->keyCode
3153 && memento.scanCode == entry->scanCode) {
3154 switch (action) {
3155 case AKEY_EVENT_ACTION_UP:
3156 mKeyMementos.removeAt(i);
3157 if (isNeutral()) {
3158 mIsOutOfSync = false;
3159 }
3160 return CONSISTENT;
3161
3162 case AKEY_EVENT_ACTION_DOWN:
3163 return TOLERABLE;
3164
3165 default:
3166 return BROKEN;
3167 }
3168 }
3169 }
3170
3171 switch (action) {
3172 case AKEY_EVENT_ACTION_DOWN: {
3173 mKeyMementos.push();
3174 KeyMemento& memento = mKeyMementos.editTop();
3175 memento.deviceId = entry->deviceId;
3176 memento.source = entry->source;
3177 memento.keyCode = entry->keyCode;
3178 memento.scanCode = entry->scanCode;
3179 memento.downTime = entry->downTime;
3180 return CONSISTENT;
3181 }
3182
3183 default:
3184 return BROKEN;
3185 }
3186}
3187
3188InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3189 const MotionEntry* entry) {
3190 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3191 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3192 MotionMemento& memento = mMotionMementos.editItemAt(i);
3193 if (memento.deviceId == entry->deviceId
3194 && memento.source == entry->source) {
3195 switch (action) {
3196 case AMOTION_EVENT_ACTION_UP:
3197 case AMOTION_EVENT_ACTION_CANCEL:
3198 mMotionMementos.removeAt(i);
3199 if (isNeutral()) {
3200 mIsOutOfSync = false;
3201 }
3202 return CONSISTENT;
3203
3204 case AMOTION_EVENT_ACTION_DOWN:
3205 return TOLERABLE;
3206
3207 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3208 if (entry->pointerCount == memento.pointerCount + 1) {
3209 memento.setPointers(entry);
3210 return CONSISTENT;
3211 }
3212 return BROKEN;
3213
3214 case AMOTION_EVENT_ACTION_POINTER_UP:
3215 if (entry->pointerCount == memento.pointerCount - 1) {
3216 memento.setPointers(entry);
3217 return CONSISTENT;
3218 }
3219 return BROKEN;
3220
3221 case AMOTION_EVENT_ACTION_MOVE:
3222 if (entry->pointerCount == memento.pointerCount) {
3223 return CONSISTENT;
3224 }
3225 return BROKEN;
3226
3227 default:
3228 return BROKEN;
3229 }
3230 }
3231 }
3232
3233 switch (action) {
3234 case AMOTION_EVENT_ACTION_DOWN: {
3235 mMotionMementos.push();
3236 MotionMemento& memento = mMotionMementos.editTop();
3237 memento.deviceId = entry->deviceId;
3238 memento.source = entry->source;
3239 memento.xPrecision = entry->xPrecision;
3240 memento.yPrecision = entry->yPrecision;
3241 memento.downTime = entry->downTime;
3242 memento.setPointers(entry);
3243 return CONSISTENT;
3244 }
3245
3246 default:
3247 return BROKEN;
3248 }
3249}
3250
3251void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3252 pointerCount = entry->pointerCount;
3253 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3254 pointerIds[i] = entry->pointerIds[i];
3255 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3256 }
3257}
3258
3259void InputDispatcher::InputState::synthesizeCancelationEvents(
3260 Allocator* allocator, Vector<EventEntry*>& outEvents) const {
3261 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3262 const KeyMemento& memento = mKeyMementos.itemAt(i);
3263 outEvents.push(allocator->obtainKeyEntry(now(),
3264 memento.deviceId, memento.source, 0,
3265 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3266 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3267 }
3268
3269 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3270 const MotionMemento& memento = mMotionMementos.itemAt(i);
3271 outEvents.push(allocator->obtainMotionEntry(now(),
3272 memento.deviceId, memento.source, 0,
3273 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3274 memento.xPrecision, memento.yPrecision, memento.downTime,
3275 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3276 }
3277}
3278
3279void InputDispatcher::InputState::clear() {
3280 mKeyMementos.clear();
3281 mMotionMementos.clear();
3282 mIsOutOfSync = false;
3283}
3284
3285
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003286// --- InputDispatcher::Connection ---
3287
3288InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3289 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown519e0242010-09-15 15:18:56 -07003290 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003291}
3292
3293InputDispatcher::Connection::~Connection() {
3294}
3295
3296status_t InputDispatcher::Connection::initialize() {
3297 return inputPublisher.initialize();
3298}
3299
Jeff Brown9c3cda02010-06-15 01:31:58 -07003300const char* InputDispatcher::Connection::getStatusLabel() const {
3301 switch (status) {
3302 case STATUS_NORMAL:
3303 return "NORMAL";
3304
3305 case STATUS_BROKEN:
3306 return "BROKEN";
3307
Jeff Brown9c3cda02010-06-15 01:31:58 -07003308 case STATUS_ZOMBIE:
3309 return "ZOMBIE";
3310
3311 default:
3312 return "UNKNOWN";
3313 }
3314}
3315
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003316InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3317 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07003318 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3319 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003320 if (dispatchEntry->eventEntry == eventEntry) {
3321 return dispatchEntry;
3322 }
3323 }
3324 return NULL;
3325}
3326
Jeff Brownb88102f2010-09-08 11:49:43 -07003327
Jeff Brown9c3cda02010-06-15 01:31:58 -07003328// --- InputDispatcher::CommandEntry ---
3329
Jeff Brownb88102f2010-09-08 11:49:43 -07003330InputDispatcher::CommandEntry::CommandEntry() :
3331 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003332}
3333
3334InputDispatcher::CommandEntry::~CommandEntry() {
3335}
3336
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003337
Jeff Brown01ce2e92010-09-26 22:20:12 -07003338// --- InputDispatcher::TouchState ---
3339
3340InputDispatcher::TouchState::TouchState() :
3341 down(false), split(false) {
3342}
3343
3344InputDispatcher::TouchState::~TouchState() {
3345}
3346
3347void InputDispatcher::TouchState::reset() {
3348 down = false;
3349 split = false;
3350 windows.clear();
3351}
3352
3353void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3354 down = other.down;
3355 split = other.split;
3356 windows.clear();
3357 windows.appendVector(other.windows);
3358}
3359
3360void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3361 int32_t targetFlags, BitSet32 pointerIds) {
3362 if (targetFlags & InputTarget::FLAG_SPLIT) {
3363 split = true;
3364 }
3365
3366 for (size_t i = 0; i < windows.size(); i++) {
3367 TouchedWindow& touchedWindow = windows.editItemAt(i);
3368 if (touchedWindow.window == window) {
3369 touchedWindow.targetFlags |= targetFlags;
3370 touchedWindow.pointerIds.value |= pointerIds.value;
3371 return;
3372 }
3373 }
3374
3375 windows.push();
3376
3377 TouchedWindow& touchedWindow = windows.editTop();
3378 touchedWindow.window = window;
3379 touchedWindow.targetFlags = targetFlags;
3380 touchedWindow.pointerIds = pointerIds;
3381 touchedWindow.channel = window->inputChannel;
3382}
3383
3384void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3385 for (size_t i = 0 ; i < windows.size(); ) {
3386 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3387 windows.removeAt(i);
3388 } else {
3389 i += 1;
3390 }
3391 }
3392}
3393
3394const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3395 for (size_t i = 0; i < windows.size(); i++) {
3396 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3397 return windows[i].window;
3398 }
3399 }
3400 return NULL;
3401}
3402
3403
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003404// --- InputDispatcherThread ---
3405
3406InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3407 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3408}
3409
3410InputDispatcherThread::~InputDispatcherThread() {
3411}
3412
3413bool InputDispatcherThread::threadLoop() {
3414 mDispatcher->dispatchOnce();
3415 return true;
3416}
3417
3418} // namespace android