blob: aa54f82e91f11ee0ba4e9d817c1af91bfc840c65 [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
137bool InputWindow::visibleFrameIntersects(const InputWindow* other) const {
138 return visibleFrameRight > other->visibleFrameLeft
139 && visibleFrameLeft < other->visibleFrameRight
140 && visibleFrameBottom > other->visibleFrameTop
141 && visibleFrameTop < other->visibleFrameBottom;
142}
143
144bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
145 return x >= touchableAreaLeft && x <= touchableAreaRight
146 && y >= touchableAreaTop && y <= touchableAreaBottom;
147}
148
149
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700150// --- InputDispatcher ---
151
Jeff Brown9c3cda02010-06-15 01:31:58 -0700152InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Brownb88102f2010-09-08 11:49:43 -0700153 mPolicy(policy),
154 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
155 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brown01ce2e92010-09-26 22:20:12 -0700156 mFocusedWindow(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700157 mFocusedApplication(NULL),
158 mCurrentInputTargetsValid(false),
159 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700160 mLooper = new Looper(false);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700161
Jeff Brownb88102f2010-09-08 11:49:43 -0700162 mInboundQueue.headSentinel.refCount = -1;
163 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
164 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700165
Jeff Brownb88102f2010-09-08 11:49:43 -0700166 mInboundQueue.tailSentinel.refCount = -1;
167 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
168 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700169
170 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700171
Jeff Brownae9fc032010-08-18 15:51:08 -0700172 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
173 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
174 mThrottleState.lastDeviceId = -1;
175
176#if DEBUG_THROTTLING
177 mThrottleState.originalSampleCount = 0;
178 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
179#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700180}
181
182InputDispatcher::~InputDispatcher() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700183 { // acquire lock
184 AutoMutex _l(mLock);
185
186 resetKeyRepeatLocked();
Jeff Brown54a18252010-09-16 14:07:33 -0700187 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700188 drainInboundQueueLocked();
189 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700190
191 while (mConnectionsByReceiveFd.size() != 0) {
192 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
193 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700194}
195
196void InputDispatcher::dispatchOnce() {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700197 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700198 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700199
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700200 nsecs_t nextWakeupTime = LONG_LONG_MAX;
201 { // acquire lock
202 AutoMutex _l(mLock);
Jeff Brownb88102f2010-09-08 11:49:43 -0700203 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700204
Jeff Brownb88102f2010-09-08 11:49:43 -0700205 if (runCommandsLockedInterruptible()) {
206 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700207 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700208 } // release lock
209
Jeff Brownb88102f2010-09-08 11:49:43 -0700210 // Wait for callback or timeout or wake. (make sure we round up, not down)
211 nsecs_t currentTime = now();
212 int32_t timeoutMillis;
213 if (nextWakeupTime > currentTime) {
214 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
215 timeout = (timeout + 999999LL) / 1000000LL;
216 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
217 } else {
218 timeoutMillis = 0;
219 }
220
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700221 mLooper->pollOnce(timeoutMillis);
Jeff Brownb88102f2010-09-08 11:49:43 -0700222}
223
224void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
225 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
226 nsecs_t currentTime = now();
227
228 // Reset the key repeat timer whenever we disallow key events, even if the next event
229 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
230 // out of sleep.
231 if (keyRepeatTimeout < 0) {
232 resetKeyRepeatLocked();
233 }
234
235 // If dispatching is disabled, drop all events in the queue.
236 if (! mDispatchEnabled) {
237 if (mPendingEvent || ! mInboundQueue.isEmpty()) {
238 LOGI("Dropping pending events because input dispatch is disabled.");
Jeff Brown54a18252010-09-16 14:07:33 -0700239 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700240 drainInboundQueueLocked();
241 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700242 return;
243 }
244
Jeff Brownb88102f2010-09-08 11:49:43 -0700245 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
246 if (mDispatchFrozen) {
247#if DEBUG_FOCUS
248 LOGD("Dispatch frozen. Waiting some more.");
249#endif
250 return;
251 }
252
253 // Optimize latency of app switches.
254 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
255 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
256 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
257 if (mAppSwitchDueTime < *nextWakeupTime) {
258 *nextWakeupTime = mAppSwitchDueTime;
259 }
260
Jeff Brownb88102f2010-09-08 11:49:43 -0700261 // Ready to start a new event.
262 // If we don't already have a pending event, go grab one.
263 if (! mPendingEvent) {
264 if (mInboundQueue.isEmpty()) {
265 if (isAppSwitchDue) {
266 // The inbound queue is empty so the app switch key we were waiting
267 // for will never arrive. Stop waiting for it.
268 resetPendingAppSwitchLocked(false);
269 isAppSwitchDue = false;
270 }
271
272 // Synthesize a key repeat if appropriate.
273 if (mKeyRepeatState.lastKeyEntry) {
274 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
275 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
276 } else {
277 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
278 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
279 }
280 }
281 }
282 if (! mPendingEvent) {
283 return;
284 }
285 } else {
286 // Inbound queue has at least one entry.
287 EventEntry* entry = mInboundQueue.headSentinel.next;
288
289 // Throttle the entry if it is a move event and there are no
290 // other events behind it in the queue. Due to movement batching, additional
291 // samples may be appended to this event by the time the throttling timeout
292 // expires.
293 // TODO Make this smarter and consider throttling per device independently.
294 if (entry->type == EventEntry::TYPE_MOTION) {
295 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
296 int32_t deviceId = motionEntry->deviceId;
297 uint32_t source = motionEntry->source;
298 if (! isAppSwitchDue
299 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
300 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
301 && deviceId == mThrottleState.lastDeviceId
302 && source == mThrottleState.lastSource) {
303 nsecs_t nextTime = mThrottleState.lastEventTime
304 + mThrottleState.minTimeBetweenEvents;
305 if (currentTime < nextTime) {
306 // Throttle it!
307#if DEBUG_THROTTLING
308 LOGD("Throttling - Delaying motion event for "
309 "device 0x%x, source 0x%08x by up to %0.3fms.",
310 deviceId, source, (nextTime - currentTime) * 0.000001);
311#endif
312 if (nextTime < *nextWakeupTime) {
313 *nextWakeupTime = nextTime;
314 }
315 if (mThrottleState.originalSampleCount == 0) {
316 mThrottleState.originalSampleCount =
317 motionEntry->countSamples();
318 }
319 return;
320 }
321 }
322
323#if DEBUG_THROTTLING
324 if (mThrottleState.originalSampleCount != 0) {
325 uint32_t count = motionEntry->countSamples();
326 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
327 count - mThrottleState.originalSampleCount,
328 mThrottleState.originalSampleCount, count);
329 mThrottleState.originalSampleCount = 0;
330 }
331#endif
332
333 mThrottleState.lastEventTime = entry->eventTime < currentTime
334 ? entry->eventTime : currentTime;
335 mThrottleState.lastDeviceId = deviceId;
336 mThrottleState.lastSource = source;
337 }
338
339 mInboundQueue.dequeue(entry);
340 mPendingEvent = entry;
341 }
342 }
343
344 // Now we have an event to dispatch.
345 assert(mPendingEvent != NULL);
Jeff Brown54a18252010-09-16 14:07:33 -0700346 bool done = false;
Jeff Brownb88102f2010-09-08 11:49:43 -0700347 switch (mPendingEvent->type) {
348 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
349 ConfigurationChangedEntry* typedEntry =
350 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700351 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -0700352 break;
353 }
354
355 case EventEntry::TYPE_KEY: {
356 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700357 bool appSwitchKey = isAppSwitchKey(typedEntry->keyCode);
358 bool dropEvent = isAppSwitchDue && ! appSwitchKey;
359 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout, dropEvent,
360 nextWakeupTime);
361 if (done) {
362 if (dropEvent) {
363 LOGI("Dropped key because of pending overdue app switch.");
364 } else if (appSwitchKey) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700365 resetPendingAppSwitchLocked(true);
Jeff Brownb88102f2010-09-08 11:49:43 -0700366 }
367 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700368 break;
369 }
370
371 case EventEntry::TYPE_MOTION: {
372 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700373 bool dropEvent = isAppSwitchDue;
374 done = dispatchMotionLocked(currentTime, typedEntry, dropEvent, nextWakeupTime);
375 if (done) {
376 if (dropEvent) {
377 LOGI("Dropped motion because of pending overdue app switch.");
378 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700379 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700380 break;
381 }
382
383 default:
384 assert(false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700385 break;
386 }
387
Jeff Brown54a18252010-09-16 14:07:33 -0700388 if (done) {
389 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700390 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
391 }
392}
393
394bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
395 bool needWake = mInboundQueue.isEmpty();
396 mInboundQueue.enqueueAtTail(entry);
397
398 switch (entry->type) {
399 case EventEntry::TYPE_KEY:
400 needWake |= detectPendingAppSwitchLocked(static_cast<KeyEntry*>(entry));
401 break;
402 }
403
404 return needWake;
405}
406
407bool InputDispatcher::isAppSwitchKey(int32_t keyCode) {
408 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
409}
410
411bool InputDispatcher::isAppSwitchPendingLocked() {
412 return mAppSwitchDueTime != LONG_LONG_MAX;
413}
414
415bool InputDispatcher::detectPendingAppSwitchLocked(KeyEntry* inboundKeyEntry) {
416 if (inboundKeyEntry->action == AKEY_EVENT_ACTION_UP
417 && ! (inboundKeyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
418 && isAppSwitchKey(inboundKeyEntry->keyCode)
419 && isEventFromReliableSourceLocked(inboundKeyEntry)) {
420#if DEBUG_APP_SWITCH
421 LOGD("App switch is pending!");
422#endif
423 mAppSwitchDueTime = inboundKeyEntry->eventTime + APP_SWITCH_TIMEOUT;
424 return true; // need wake
425 }
426 return false;
427}
428
429void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
430 mAppSwitchDueTime = LONG_LONG_MAX;
431
432#if DEBUG_APP_SWITCH
433 if (handled) {
434 LOGD("App switch has arrived.");
435 } else {
436 LOGD("App switch was abandoned.");
437 }
438#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700439}
440
Jeff Brown9c3cda02010-06-15 01:31:58 -0700441bool InputDispatcher::runCommandsLockedInterruptible() {
442 if (mCommandQueue.isEmpty()) {
443 return false;
444 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700445
Jeff Brown9c3cda02010-06-15 01:31:58 -0700446 do {
447 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
448
449 Command command = commandEntry->command;
450 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
451
Jeff Brown7fbdc842010-06-17 20:52:56 -0700452 commandEntry->connection.clear();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700453 mAllocator.releaseCommandEntry(commandEntry);
454 } while (! mCommandQueue.isEmpty());
455 return true;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700456}
457
Jeff Brown9c3cda02010-06-15 01:31:58 -0700458InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
459 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
460 mCommandQueue.enqueueAtTail(commandEntry);
461 return commandEntry;
462}
463
Jeff Brownb88102f2010-09-08 11:49:43 -0700464void InputDispatcher::drainInboundQueueLocked() {
465 while (! mInboundQueue.isEmpty()) {
466 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700467 releaseInboundEventLocked(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700468 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700469}
470
Jeff Brown54a18252010-09-16 14:07:33 -0700471void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700472 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700473 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700474 mPendingEvent = NULL;
475 }
476}
477
Jeff Brown54a18252010-09-16 14:07:33 -0700478void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700479 InjectionState* injectionState = entry->injectionState;
480 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700481#if DEBUG_DISPATCH_CYCLE
Jeff Brown01ce2e92010-09-26 22:20:12 -0700482 LOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700483#endif
484 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
485 }
486 mAllocator.releaseEventEntry(entry);
487}
488
489bool InputDispatcher::isEventFromReliableSourceLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700490 InjectionState* injectionState = entry->injectionState;
491 return ! injectionState
492 || injectionState->injectorUid == 0
Jeff Brownb88102f2010-09-08 11:49:43 -0700493 || mPolicy->checkInjectEventsPermissionNonReentrant(
Jeff Brown01ce2e92010-09-26 22:20:12 -0700494 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -0700495}
496
497void InputDispatcher::resetKeyRepeatLocked() {
498 if (mKeyRepeatState.lastKeyEntry) {
499 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
500 mKeyRepeatState.lastKeyEntry = NULL;
501 }
502}
503
504InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brownb21fb102010-09-07 10:44:57 -0700505 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown349703e2010-06-22 01:27:15 -0700506 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
507
Jeff Brown349703e2010-06-22 01:27:15 -0700508 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700509 uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700510 if (entry->refCount == 1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700511 mAllocator.recycleKeyEntry(entry);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700512 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700513 entry->policyFlags = policyFlags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700514 entry->repeatCount += 1;
515 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700516 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700517 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700518 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700519 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700520
521 mKeyRepeatState.lastKeyEntry = newEntry;
522 mAllocator.releaseKeyEntry(entry);
523
524 entry = newEntry;
525 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700526 entry->syntheticRepeat = true;
527
528 // Increment reference count since we keep a reference to the event in
529 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
530 entry->refCount += 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700531
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700532 if (entry->repeatCount == 1) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700533 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700534 }
535
Jeff Brownb21fb102010-09-07 10:44:57 -0700536 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700537 return entry;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700538}
539
Jeff Brownb88102f2010-09-08 11:49:43 -0700540bool InputDispatcher::dispatchConfigurationChangedLocked(
541 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700542#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownb88102f2010-09-08 11:49:43 -0700543 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
544#endif
545
546 // Reset key repeating in case a keyboard device was added or removed or something.
547 resetKeyRepeatLocked();
548
549 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
550 CommandEntry* commandEntry = postCommandLocked(
551 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
552 commandEntry->eventTime = entry->eventTime;
553 return true;
554}
555
556bool InputDispatcher::dispatchKeyLocked(
557 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brown54a18252010-09-16 14:07:33 -0700558 bool dropEvent, nsecs_t* nextWakeupTime) {
559 // Give the policy a chance to intercept the key.
560 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
561 bool trusted;
562 if (! dropEvent && mFocusedWindow) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700563 trusted = checkInjectionPermission(mFocusedWindow, entry->injectionState);
Jeff Brown54a18252010-09-16 14:07:33 -0700564 } else {
565 trusted = isEventFromReliableSourceLocked(entry);
566 }
567 if (trusted) {
568 CommandEntry* commandEntry = postCommandLocked(
569 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
570 if (! dropEvent && mFocusedWindow) {
571 commandEntry->inputChannel = mFocusedWindow->inputChannel;
572 }
573 commandEntry->keyEntry = entry;
574 entry->refCount += 1;
575 return false; // wait for the command to run
576 } else {
577 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
578 }
579 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
580 resetTargetsLocked();
581 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
582 return true;
583 }
584
585 // Clean up if dropping the event.
586 if (dropEvent) {
587 resetTargetsLocked();
588 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
589 return true;
590 }
591
Jeff Brownb88102f2010-09-08 11:49:43 -0700592 // Preprocessing.
593 if (! entry->dispatchInProgress) {
594 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
595
596 if (entry->repeatCount == 0
597 && entry->action == AKEY_EVENT_ACTION_DOWN
598 && ! entry->isInjected()) {
599 if (mKeyRepeatState.lastKeyEntry
600 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
601 // We have seen two identical key downs in a row which indicates that the device
602 // driver is automatically generating key repeats itself. We take note of the
603 // repeat here, but we disable our own next key repeat timer since it is clear that
604 // we will not need to synthesize key repeats ourselves.
605 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
606 resetKeyRepeatLocked();
607 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
608 } else {
609 // Not a repeat. Save key down state in case we do see a repeat later.
610 resetKeyRepeatLocked();
611 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
612 }
613 mKeyRepeatState.lastKeyEntry = entry;
614 entry->refCount += 1;
615 } else if (! entry->syntheticRepeat) {
616 resetKeyRepeatLocked();
617 }
618
619 entry->dispatchInProgress = true;
Jeff Brown54a18252010-09-16 14:07:33 -0700620 resetTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700621 }
622
623 // Identify targets.
624 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700625 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
626 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700627 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
628 return false;
629 }
630
631 setInjectionResultLocked(entry, injectionResult);
632 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
633 return true;
634 }
635
636 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700637 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700638 }
639
640 // Dispatch the key.
641 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
642
643 // Poke user activity.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700644 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
645 pokeUserActivityLocked(entry->eventTime, POWER_MANAGER_BUTTON_EVENT);
646 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700647 return true;
648}
649
650void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
651#if DEBUG_OUTBOUND_EVENT_DETAILS
652 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
653 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
654 "downTime=%lld",
655 prefix,
656 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
657 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
658 entry->downTime);
659#endif
660}
661
662bool InputDispatcher::dispatchMotionLocked(
Jeff Brown54a18252010-09-16 14:07:33 -0700663 nsecs_t currentTime, MotionEntry* entry, bool dropEvent, nsecs_t* nextWakeupTime) {
664 // Clean up if dropping the event.
665 if (dropEvent) {
666 resetTargetsLocked();
667 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
668 return true;
669 }
670
Jeff Brownb88102f2010-09-08 11:49:43 -0700671 // Preprocessing.
672 if (! entry->dispatchInProgress) {
673 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
674
675 entry->dispatchInProgress = true;
Jeff Brown54a18252010-09-16 14:07:33 -0700676 resetTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700677 }
678
679 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
680
681 // Identify targets.
682 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700683 int32_t injectionResult;
684 if (isPointerEvent) {
685 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700686 injectionResult = findTouchedWindowTargetsLocked(currentTime,
687 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700688 } else {
689 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700690 injectionResult = findFocusedWindowTargetsLocked(currentTime,
691 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700692 }
693 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
694 return false;
695 }
696
697 setInjectionResultLocked(entry, injectionResult);
698 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
699 return true;
700 }
701
702 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700703 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700704 }
705
706 // Dispatch the motion.
707 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
708
709 // Poke user activity.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700710 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
711 int32_t eventType;
712 if (isPointerEvent) {
713 switch (entry->action) {
714 case AMOTION_EVENT_ACTION_DOWN:
Jeff Brownb88102f2010-09-08 11:49:43 -0700715 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700716 break;
717 case AMOTION_EVENT_ACTION_UP:
718 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
719 break;
720 default:
721 if (entry->eventTime - entry->downTime >= EVENT_IGNORE_DURATION) {
722 eventType = POWER_MANAGER_TOUCH_EVENT;
723 } else {
724 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
725 }
726 break;
Jeff Brownb88102f2010-09-08 11:49:43 -0700727 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700728 } else {
729 eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brownb88102f2010-09-08 11:49:43 -0700730 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700731 pokeUserActivityLocked(entry->eventTime, eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700732 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700733 return true;
734}
735
736
737void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
738#if DEBUG_OUTBOUND_EVENT_DETAILS
739 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700740 "action=0x%x, flags=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700741 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700742 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700743 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
744 entry->action, entry->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700745 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
746 entry->downTime);
747
748 // Print the most recent sample that we have available, this may change due to batching.
749 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700750 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700751 for (; sample->next != NULL; sample = sample->next) {
752 sampleCount += 1;
753 }
754 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -0700755 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700756 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700757 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700758 i, entry->pointerIds[i],
Jeff Brown8d608662010-08-30 03:02:23 -0700759 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
760 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
761 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
762 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
763 sample->pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700764 }
765
766 // Keep in mind that due to batching, it is possible for the number of samples actually
767 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700768 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700769 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
770 }
771#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700772}
773
774void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
775 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
776#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -0700777 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700778 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700779 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700780#endif
781
Jeff Brown9c3cda02010-06-15 01:31:58 -0700782 assert(eventEntry->dispatchInProgress); // should already have been set to true
783
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700784 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
785 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
786
Jeff Brown519e0242010-09-15 15:18:56 -0700787 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700788 if (connectionIndex >= 0) {
789 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700790 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700791 resumeWithAppendedMotionSample);
792 } else {
793 LOGW("Framework requested delivery of an input event to channel '%s' but it "
794 "is not registered with the input dispatcher.",
795 inputTarget.inputChannel->getName().string());
796 }
797 }
798}
799
Jeff Brown54a18252010-09-16 14:07:33 -0700800void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700801 mCurrentInputTargetsValid = false;
802 mCurrentInputTargets.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700803 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
804}
805
Jeff Brown01ce2e92010-09-26 22:20:12 -0700806void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700807 mCurrentInputTargetsValid = true;
808}
809
810int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
811 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
812 nsecs_t* nextWakeupTime) {
813 if (application == NULL && window == NULL) {
814 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
815#if DEBUG_FOCUS
816 LOGD("Waiting for system to become ready for input.");
817#endif
818 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
819 mInputTargetWaitStartTime = currentTime;
820 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
821 mInputTargetWaitTimeoutExpired = false;
822 }
823 } else {
824 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
825#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700826 LOGD("Waiting for application to become ready for input: %s",
827 getApplicationWindowLabelLocked(application, window).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700828#endif
829 nsecs_t timeout = window ? window->dispatchingTimeout :
830 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
831
832 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
833 mInputTargetWaitStartTime = currentTime;
834 mInputTargetWaitTimeoutTime = currentTime + timeout;
835 mInputTargetWaitTimeoutExpired = false;
836 }
837 }
838
839 if (mInputTargetWaitTimeoutExpired) {
840 return INPUT_EVENT_INJECTION_TIMED_OUT;
841 }
842
843 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown519e0242010-09-15 15:18:56 -0700844 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700845
846 // Force poll loop to wake up immediately on next iteration once we get the
847 // ANR response back from the policy.
848 *nextWakeupTime = LONG_LONG_MIN;
849 return INPUT_EVENT_INJECTION_PENDING;
850 } else {
851 // Force poll loop to wake up when timeout is due.
852 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
853 *nextWakeupTime = mInputTargetWaitTimeoutTime;
854 }
855 return INPUT_EVENT_INJECTION_PENDING;
856 }
857}
858
Jeff Brown519e0242010-09-15 15:18:56 -0700859void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
860 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700861 if (newTimeout > 0) {
862 // Extend the timeout.
863 mInputTargetWaitTimeoutTime = now() + newTimeout;
864 } else {
865 // Give up.
866 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -0700867
Jeff Brown01ce2e92010-09-26 22:20:12 -0700868 // Release the touch targets.
869 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -0700870
Jeff Brown519e0242010-09-15 15:18:56 -0700871 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -0700872 if (inputChannel.get()) {
873 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
874 if (connectionIndex >= 0) {
875 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
876 connection->inputState.setOutOfSync();
877 }
Jeff Brown519e0242010-09-15 15:18:56 -0700878 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700879 }
880}
881
Jeff Brown519e0242010-09-15 15:18:56 -0700882nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -0700883 nsecs_t currentTime) {
884 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
885 return currentTime - mInputTargetWaitStartTime;
886 }
887 return 0;
888}
889
890void InputDispatcher::resetANRTimeoutsLocked() {
891#if DEBUG_FOCUS
892 LOGD("Resetting ANR timeouts.");
893#endif
894
Jeff Brownb88102f2010-09-08 11:49:43 -0700895 // Reset input target wait timeout.
896 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
897}
898
Jeff Brown01ce2e92010-09-26 22:20:12 -0700899int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
900 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700901 mCurrentInputTargets.clear();
902
903 int32_t injectionResult;
904
905 // If there is no currently focused window and no focused application
906 // then drop the event.
907 if (! mFocusedWindow) {
908 if (mFocusedApplication) {
909#if DEBUG_FOCUS
910 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -0700911 "focused application that may eventually add a window: %s.",
912 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700913#endif
914 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
915 mFocusedApplication, NULL, nextWakeupTime);
916 goto Unresponsive;
917 }
918
919 LOGI("Dropping event because there is no focused window or focused application.");
920 injectionResult = INPUT_EVENT_INJECTION_FAILED;
921 goto Failed;
922 }
923
924 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700925 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700926 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
927 goto Failed;
928 }
929
930 // If the currently focused window is paused then keep waiting.
931 if (mFocusedWindow->paused) {
932#if DEBUG_FOCUS
933 LOGD("Waiting because focused window is paused.");
934#endif
935 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
936 mFocusedApplication, mFocusedWindow, nextWakeupTime);
937 goto Unresponsive;
938 }
939
Jeff Brown519e0242010-09-15 15:18:56 -0700940 // If the currently focused window is still working on previous events then keep waiting.
941 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
942#if DEBUG_FOCUS
943 LOGD("Waiting because focused window still processing previous input.");
944#endif
945 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
946 mFocusedApplication, mFocusedWindow, nextWakeupTime);
947 goto Unresponsive;
948 }
949
Jeff Brownb88102f2010-09-08 11:49:43 -0700950 // Success! Output targets.
951 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700952 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -0700953
954 // Done.
955Failed:
956Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -0700957 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
958 updateDispatchStatisticsLocked(currentTime, entry,
959 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -0700960#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700961 LOGD("findFocusedWindow finished: injectionResult=%d, "
962 "timeSpendWaitingForApplication=%0.1fms",
963 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -0700964#endif
965 return injectionResult;
966}
967
Jeff Brown01ce2e92010-09-26 22:20:12 -0700968int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
969 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700970 enum InjectionPermission {
971 INJECTION_PERMISSION_UNKNOWN,
972 INJECTION_PERMISSION_GRANTED,
973 INJECTION_PERMISSION_DENIED
974 };
975
Jeff Brownb88102f2010-09-08 11:49:43 -0700976 mCurrentInputTargets.clear();
977
978 nsecs_t startTime = now();
979
980 // For security reasons, we defer updating the touch state until we are sure that
981 // event injection will be allowed.
982 //
983 // FIXME In the original code, screenWasOff could never be set to true.
984 // The reason is that the POLICY_FLAG_WOKE_HERE
985 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
986 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
987 // actually enqueued using the policyFlags that appeared in the final EV_SYN
988 // events upon which no preprocessing took place. So policyFlags was always 0.
989 // In the new native input dispatcher we're a bit more careful about event
990 // preprocessing so the touches we receive can actually have non-zero policyFlags.
991 // Unfortunately we obtain undesirable behavior.
992 //
993 // Here's what happens:
994 //
995 // When the device dims in anticipation of going to sleep, touches
996 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
997 // the device to brighten and reset the user activity timer.
998 // Touches on other windows (such as the launcher window)
999 // are dropped. Then after a moment, the device goes to sleep. Oops.
1000 //
1001 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1002 // instead of POLICY_FLAG_WOKE_HERE...
1003 //
1004 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1005
1006 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001007 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001008
1009 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001010 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1011 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1012 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1013 mTempTouchState.reset();
1014 mTempTouchState.down = true;
1015 } else {
1016 mTempTouchState.copyFrom(mTouchState);
1017 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001018
Jeff Brown01ce2e92010-09-26 22:20:12 -07001019 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1020 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1021 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1022 /* Case 1: New splittable pointer going down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001023
Jeff Brown01ce2e92010-09-26 22:20:12 -07001024 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1025 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1026 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1027 const InputWindow* newTouchedWindow = NULL;
1028 const InputWindow* topErrorWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07001029
1030 // Traverse windows from front to back to find touched window and outside targets.
1031 size_t numWindows = mWindows.size();
1032 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001033 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001034 int32_t flags = window->layoutParamsFlags;
1035
1036 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1037 if (! topErrorWindow) {
1038 topErrorWindow = window;
1039 }
1040 }
1041
1042 if (window->visible) {
1043 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1044 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1045 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1046 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1047 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1048 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001049 }
1050 break; // found touched window, exit window loop
1051 }
1052 }
1053
Jeff Brown01ce2e92010-09-26 22:20:12 -07001054 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1055 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
1056 mTempTouchState.addOrUpdateWindow(window,
1057 InputTarget::FLAG_OUTSIDE, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001058 }
1059 }
1060 }
1061
1062 // If there is an error window but it is not taking focus (typically because
1063 // it is invisible) then wait for it. Any other focused window may in
1064 // fact be in ANR state.
1065 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1066#if DEBUG_FOCUS
1067 LOGD("Waiting because system error window is pending.");
1068#endif
1069 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1070 NULL, NULL, nextWakeupTime);
1071 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1072 goto Unresponsive;
1073 }
1074
Jeff Brown01ce2e92010-09-26 22:20:12 -07001075 // Figure out whether splitting will be allowed for this window.
Jeff Brownaeec2bf2010-09-28 13:24:41 -07001076 if (newTouchedWindow
1077 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001078 // New window supports splitting.
1079 isSplit = true;
1080 } else if (isSplit) {
1081 // New window does not support splitting but we have already split events.
1082 // Assign the pointer to the first foreground window we find.
1083 // (May be NULL which is why we put this code block before the next check.)
1084 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1085 }
1086 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1087 if (isSplit) {
1088 targetFlags |= InputTarget::FLAG_SPLIT;
1089 }
1090
Jeff Brownb88102f2010-09-08 11:49:43 -07001091 // If we did not find a touched window then fail.
1092 if (! newTouchedWindow) {
1093 if (mFocusedApplication) {
1094#if DEBUG_FOCUS
1095 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001096 "focused application that may eventually add a new window: %s.",
1097 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001098#endif
1099 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1100 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001101 goto Unresponsive;
1102 }
1103
1104 LOGI("Dropping event because there is no touched window or focused application.");
1105 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001106 goto Failed;
1107 }
1108
Jeff Brown01ce2e92010-09-26 22:20:12 -07001109 // Update the temporary touch state.
1110 BitSet32 pointerIds;
1111 if (isSplit) {
1112 uint32_t pointerId = entry->pointerIds[pointerIndex];
1113 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001114 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001115 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001116 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001117 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001118
1119 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001120 if (! mTempTouchState.down) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001121 LOGI("Dropping event because the pointer is not down.");
1122 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001123 goto Failed;
1124 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001125 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001126
Jeff Brown01ce2e92010-09-26 22:20:12 -07001127 // Check permission to inject into all touched foreground windows and ensure there
1128 // is at least one touched foreground window.
1129 {
1130 bool haveForegroundWindow = false;
1131 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1132 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1133 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1134 haveForegroundWindow = true;
1135 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1136 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1137 injectionPermission = INJECTION_PERMISSION_DENIED;
1138 goto Failed;
1139 }
1140 }
1141 }
1142 if (! haveForegroundWindow) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001143#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown01ce2e92010-09-26 22:20:12 -07001144 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001145#endif
1146 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001147 goto Failed;
1148 }
1149
Jeff Brown01ce2e92010-09-26 22:20:12 -07001150 // Permission granted to injection into all touched foreground windows.
1151 injectionPermission = INJECTION_PERMISSION_GRANTED;
1152 }
Jeff Brown519e0242010-09-15 15:18:56 -07001153
Jeff Brown01ce2e92010-09-26 22:20:12 -07001154 // Ensure all touched foreground windows are ready for new input.
1155 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1156 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1157 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1158 // If the touched window is paused then keep waiting.
1159 if (touchedWindow.window->paused) {
1160#if DEBUG_INPUT_DISPATCHER_POLICY
1161 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001162#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001163 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1164 NULL, touchedWindow.window, nextWakeupTime);
1165 goto Unresponsive;
1166 }
1167
1168 // If the touched window is still working on previous events then keep waiting.
1169 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1170#if DEBUG_FOCUS
1171 LOGD("Waiting because touched window still processing previous input.");
1172#endif
1173 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1174 NULL, touchedWindow.window, nextWakeupTime);
1175 goto Unresponsive;
1176 }
1177 }
1178 }
1179
1180 // If this is the first pointer going down and the touched window has a wallpaper
1181 // then also add the touched wallpaper windows so they are locked in for the duration
1182 // of the touch gesture.
1183 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1184 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1185 if (foregroundWindow->hasWallpaper) {
1186 for (size_t i = 0; i < mWindows.size(); i++) {
1187 const InputWindow* window = & mWindows[i];
1188 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
1189 mTempTouchState.addOrUpdateWindow(window, 0, BitSet32(0));
1190 }
1191 }
1192 }
1193 }
1194
1195 // If a touched window has been obscured at any point during the touch gesture, set
1196 // the appropriate flag so we remember it for the entire gesture.
1197 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1198 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1199 if ((touchedWindow.targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) == 0) {
1200 if (isWindowObscuredLocked(touchedWindow.window)) {
1201 touchedWindow.targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1202 }
Jeff Brown519e0242010-09-15 15:18:56 -07001203 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001204 }
1205
1206 // Success! Output targets.
1207 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001208
Jeff Brown01ce2e92010-09-26 22:20:12 -07001209 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1210 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1211 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1212 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001213 }
1214
Jeff Brown01ce2e92010-09-26 22:20:12 -07001215 // Drop the outside touch window since we will not care about them in the next iteration.
1216 mTempTouchState.removeOutsideTouchWindows();
1217
Jeff Brownb88102f2010-09-08 11:49:43 -07001218Failed:
1219 // Check injection permission once and for all.
1220 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001221 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001222 injectionPermission = INJECTION_PERMISSION_GRANTED;
1223 } else {
1224 injectionPermission = INJECTION_PERMISSION_DENIED;
1225 }
1226 }
1227
1228 // Update final pieces of touch state if the injector had permission.
1229 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001230 if (maskedAction == AMOTION_EVENT_ACTION_UP
1231 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1232 // All pointers up or canceled.
1233 mTempTouchState.reset();
1234 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1235 // First pointer went down.
1236 if (mTouchState.down) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001237 LOGW("Pointer down received while already down.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001238 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001239 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1240 // One pointer went up.
1241 if (isSplit) {
1242 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1243 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001244
Jeff Brown01ce2e92010-09-26 22:20:12 -07001245 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1246 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1247 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1248 touchedWindow.pointerIds.clearBit(pointerId);
1249 if (touchedWindow.pointerIds.isEmpty()) {
1250 mTempTouchState.windows.removeAt(i);
1251 continue;
1252 }
1253 }
1254 i += 1;
1255 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001256 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001257 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001258
1259 // Save changes to touch state.
1260 mTouchState.copyFrom(mTempTouchState);
Jeff Brownb88102f2010-09-08 11:49:43 -07001261 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001262#if DEBUG_FOCUS
1263 LOGD("Not updating touch focus because injection was denied.");
1264#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001265 }
1266
1267Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001268 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1269 updateDispatchStatisticsLocked(currentTime, entry,
1270 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001271#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001272 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1273 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001274 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001275#endif
1276 return injectionResult;
1277}
1278
Jeff Brown01ce2e92010-09-26 22:20:12 -07001279void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1280 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001281 mCurrentInputTargets.push();
1282
1283 InputTarget& target = mCurrentInputTargets.editTop();
1284 target.inputChannel = window->inputChannel;
1285 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001286 target.xOffset = - window->frameLeft;
1287 target.yOffset = - window->frameTop;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001288 target.windowType = window->layoutParamsType;
1289 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001290}
1291
1292void InputDispatcher::addMonitoringTargetsLocked() {
1293 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1294 mCurrentInputTargets.push();
1295
1296 InputTarget& target = mCurrentInputTargets.editTop();
1297 target.inputChannel = mMonitoringChannels[i];
1298 target.flags = 0;
Jeff Brownb88102f2010-09-08 11:49:43 -07001299 target.xOffset = 0;
1300 target.yOffset = 0;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001301 target.windowType = InputWindow::TYPE_SYSTEM_OVERLAY;
Jeff Brownb88102f2010-09-08 11:49:43 -07001302 }
1303}
1304
1305bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001306 const InjectionState* injectionState) {
1307 if (injectionState
1308 && injectionState->injectorUid > 0
1309 && (window == NULL || window->ownerUid != injectionState->injectorUid)) {
1310 bool result = mPolicy->checkInjectEventsPermissionNonReentrant(
1311 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001312 if (! result) {
1313 if (window) {
1314 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1315 "with input channel %s owned by uid %d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07001316 injectionState->injectorPid, injectionState->injectorUid,
1317 window->inputChannel->getName().string(),
Jeff Brownb88102f2010-09-08 11:49:43 -07001318 window->ownerUid);
1319 } else {
1320 LOGW("Permission denied: injecting event from pid %d uid %d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07001321 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001322 }
1323 return false;
1324 }
1325 }
1326 return true;
1327}
1328
1329bool InputDispatcher::isWindowObscuredLocked(const InputWindow* window) {
1330 size_t numWindows = mWindows.size();
1331 for (size_t i = 0; i < numWindows; i++) {
1332 const InputWindow* other = & mWindows.itemAt(i);
1333 if (other == window) {
1334 break;
1335 }
1336 if (other->visible && window->visibleFrameIntersects(other)) {
1337 return true;
1338 }
1339 }
1340 return false;
1341}
1342
Jeff Brown519e0242010-09-15 15:18:56 -07001343bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1344 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1345 if (connectionIndex >= 0) {
1346 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1347 return connection->outboundQueue.isEmpty();
1348 } else {
1349 return true;
1350 }
1351}
1352
1353String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1354 const InputWindow* window) {
1355 if (application) {
1356 if (window) {
1357 String8 label(application->name);
1358 label.append(" - ");
1359 label.append(window->name);
1360 return label;
1361 } else {
1362 return application->name;
1363 }
1364 } else if (window) {
1365 return window->name;
1366 } else {
1367 return String8("<unknown application or window>");
1368 }
1369}
1370
Jeff Brown01ce2e92010-09-26 22:20:12 -07001371bool InputDispatcher::shouldPokeUserActivityForCurrentInputTargetsLocked() {
1372 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
1373 if (mCurrentInputTargets[i].windowType == InputWindow::TYPE_KEYGUARD) {
1374 return false;
1375 }
1376 }
1377 return true;
1378}
1379
1380void InputDispatcher::pokeUserActivityLocked(nsecs_t eventTime, int32_t eventType) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001381 CommandEntry* commandEntry = postCommandLocked(
1382 & InputDispatcher::doPokeUserActivityLockedInterruptible);
1383 commandEntry->eventTime = eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001384 commandEntry->userActivityEventType = eventType;
1385}
1386
Jeff Brown7fbdc842010-06-17 20:52:56 -07001387void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1388 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001389 bool resumeWithAppendedMotionSample) {
1390#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001391 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001392 "xOffset=%f, yOffset=%f, "
1393 "windowType=%d, pointerIds=0x%x, "
1394 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001395 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001396 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001397 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001398 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001399#endif
1400
Jeff Brown01ce2e92010-09-26 22:20:12 -07001401 // Make sure we are never called for streaming when splitting across multiple windows.
1402 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1403 assert(! (resumeWithAppendedMotionSample && isSplit));
1404
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001405 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001406 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001407 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001408 LOGW("channel '%s' ~ Dropping event because the channel status is %s",
1409 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001410 return;
1411 }
1412
Jeff Brown01ce2e92010-09-26 22:20:12 -07001413 // Split a motion event if needed.
1414 if (isSplit) {
1415 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1416
1417 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1418 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1419 MotionEntry* splitMotionEntry = splitMotionEvent(
1420 originalMotionEntry, inputTarget->pointerIds);
1421#if DEBUG_FOCUS
1422 LOGD("channel '%s' ~ Split motion event.",
1423 connection->getInputChannelName());
1424 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1425#endif
1426 eventEntry = splitMotionEntry;
1427 }
1428 }
1429
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001430 // Resume the dispatch cycle with a freshly appended motion sample.
1431 // First we check that the last dispatch entry in the outbound queue is for the same
1432 // motion event to which we appended the motion sample. If we find such a dispatch
1433 // entry, and if it is currently in progress then we try to stream the new sample.
1434 bool wasEmpty = connection->outboundQueue.isEmpty();
1435
1436 if (! wasEmpty && resumeWithAppendedMotionSample) {
1437 DispatchEntry* motionEventDispatchEntry =
1438 connection->findQueuedDispatchEntryForEvent(eventEntry);
1439 if (motionEventDispatchEntry) {
1440 // If the dispatch entry is not in progress, then we must be busy dispatching an
1441 // earlier event. Not a problem, the motion event is on the outbound queue and will
1442 // be dispatched later.
1443 if (! motionEventDispatchEntry->inProgress) {
1444#if DEBUG_BATCHING
1445 LOGD("channel '%s' ~ Not streaming because the motion event has "
1446 "not yet been dispatched. "
1447 "(Waiting for earlier events to be consumed.)",
1448 connection->getInputChannelName());
1449#endif
1450 return;
1451 }
1452
1453 // If the dispatch entry is in progress but it already has a tail of pending
1454 // motion samples, then it must mean that the shared memory buffer filled up.
1455 // Not a problem, when this dispatch cycle is finished, we will eventually start
1456 // a new dispatch cycle to process the tail and that tail includes the newly
1457 // appended motion sample.
1458 if (motionEventDispatchEntry->tailMotionSample) {
1459#if DEBUG_BATCHING
1460 LOGD("channel '%s' ~ Not streaming because no new samples can "
1461 "be appended to the motion event in this dispatch cycle. "
1462 "(Waiting for next dispatch cycle to start.)",
1463 connection->getInputChannelName());
1464#endif
1465 return;
1466 }
1467
1468 // The dispatch entry is in progress and is still potentially open for streaming.
1469 // Try to stream the new motion sample. This might fail if the consumer has already
1470 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001471 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1472 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001473 status_t status = connection->inputPublisher.appendMotionSample(
1474 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1475 if (status == OK) {
1476#if DEBUG_BATCHING
1477 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1478 connection->getInputChannelName());
1479#endif
1480 return;
1481 }
1482
1483#if DEBUG_BATCHING
1484 if (status == NO_MEMORY) {
1485 LOGD("channel '%s' ~ Could not append motion sample to currently "
1486 "dispatched move event because the shared memory buffer is full. "
1487 "(Waiting for next dispatch cycle to start.)",
1488 connection->getInputChannelName());
1489 } else if (status == status_t(FAILED_TRANSACTION)) {
1490 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001491 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001492 "(Waiting for next dispatch cycle to start.)",
1493 connection->getInputChannelName());
1494 } else {
1495 LOGD("channel '%s' ~ Could not append motion sample to currently "
1496 "dispatched move event due to an error, status=%d. "
1497 "(Waiting for next dispatch cycle to start.)",
1498 connection->getInputChannelName(), status);
1499 }
1500#endif
1501 // Failed to stream. Start a new tail of pending motion samples to dispatch
1502 // in the next cycle.
1503 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1504 return;
1505 }
1506 }
1507
Jeff Brownb88102f2010-09-08 11:49:43 -07001508 // Bring the input state back in line with reality in case it drifted off during an ANR.
1509 if (connection->inputState.isOutOfSync()) {
1510 mTempCancelationEvents.clear();
1511 connection->inputState.synthesizeCancelationEvents(& mAllocator, mTempCancelationEvents);
1512 connection->inputState.resetOutOfSync();
1513
1514 if (! mTempCancelationEvents.isEmpty()) {
1515 LOGI("channel '%s' ~ Generated %d cancelation events to bring channel back in sync "
1516 "with reality.",
1517 connection->getInputChannelName(), mTempCancelationEvents.size());
1518
1519 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1520 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1521 switch (cancelationEventEntry->type) {
1522 case EventEntry::TYPE_KEY:
1523 logOutboundKeyDetailsLocked(" ",
1524 static_cast<KeyEntry*>(cancelationEventEntry));
1525 break;
1526 case EventEntry::TYPE_MOTION:
1527 logOutboundMotionDetailsLocked(" ",
1528 static_cast<MotionEntry*>(cancelationEventEntry));
1529 break;
1530 }
1531
1532 DispatchEntry* cancelationDispatchEntry =
1533 mAllocator.obtainDispatchEntry(cancelationEventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07001534 0, inputTarget->xOffset, inputTarget->yOffset); // increments ref
Jeff Brownb88102f2010-09-08 11:49:43 -07001535 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1536
1537 mAllocator.releaseEventEntry(cancelationEventEntry);
1538 }
1539 }
1540 }
1541
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001542 // This is a new event.
1543 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001544 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown519e0242010-09-15 15:18:56 -07001545 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1546 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001547 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001548 }
1549
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001550 // Handle the case where we could not stream a new motion sample because the consumer has
1551 // already consumed the motion event (otherwise the corresponding dispatch entry would
1552 // still be in the outbound queue for this connection). We set the head motion sample
1553 // to the list starting with the newly appended motion sample.
1554 if (resumeWithAppendedMotionSample) {
1555#if DEBUG_BATCHING
1556 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1557 "that cannot be streamed because the motion event has already been consumed.",
1558 connection->getInputChannelName());
1559#endif
1560 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1561 dispatchEntry->headMotionSample = appendedMotionSample;
1562 }
1563
1564 // Enqueue the dispatch entry.
1565 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1566
1567 // If the outbound queue was previously empty, start the dispatch cycle going.
1568 if (wasEmpty) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001569 activateConnectionLocked(connection.get());
Jeff Brown519e0242010-09-15 15:18:56 -07001570 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001571 }
1572}
1573
Jeff Brown7fbdc842010-06-17 20:52:56 -07001574void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001575 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001576#if DEBUG_DISPATCH_CYCLE
1577 LOGD("channel '%s' ~ startDispatchCycle",
1578 connection->getInputChannelName());
1579#endif
1580
1581 assert(connection->status == Connection::STATUS_NORMAL);
1582 assert(! connection->outboundQueue.isEmpty());
1583
Jeff Brownb88102f2010-09-08 11:49:43 -07001584 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001585 assert(! dispatchEntry->inProgress);
1586
Jeff Brownb88102f2010-09-08 11:49:43 -07001587 // Mark the dispatch entry as in progress.
1588 dispatchEntry->inProgress = true;
1589
1590 // Update the connection's input state.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001591 EventEntry* eventEntry = dispatchEntry->eventEntry;
1592 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001593
1594#if FILTER_INPUT_EVENTS
1595 // Filter out inconsistent sequences of input events.
1596 // The input system may drop or inject events in a way that could violate implicit
1597 // invariants on input state and potentially cause an application to crash
1598 // or think that a key or pointer is stuck down. Technically we make no guarantees
1599 // of consistency but it would be nice to improve on this where possible.
1600 // XXX: This code is a proof of concept only. Not ready for prime time.
1601 if (consistency == InputState::TOLERABLE) {
1602#if DEBUG_DISPATCH_CYCLE
1603 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1604 "current input state but that is likely to be tolerated by the application.",
1605 connection->getInputChannelName());
1606#endif
1607 } else if (consistency == InputState::BROKEN) {
1608 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1609 "current input state and that is likely to cause the application to crash.",
1610 connection->getInputChannelName());
1611 startNextDispatchCycleLocked(currentTime, connection);
1612 return;
1613 }
1614#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001615
1616 // Publish the event.
1617 status_t status;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001618 switch (eventEntry->type) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001619 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001620 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001621
1622 // Apply target flags.
1623 int32_t action = keyEntry->action;
1624 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001625
1626 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001627 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001628 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1629 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1630 keyEntry->eventTime);
1631
1632 if (status) {
1633 LOGE("channel '%s' ~ Could not publish key event, "
1634 "status=%d", connection->getInputChannelName(), status);
1635 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1636 return;
1637 }
1638 break;
1639 }
1640
1641 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001642 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001643
1644 // Apply target flags.
1645 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001646 int32_t flags = motionEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001647 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001648 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001649 }
Jeff Brown85a31762010-09-01 17:01:00 -07001650 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1651 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1652 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001653
1654 // If headMotionSample is non-NULL, then it points to the first new sample that we
1655 // were unable to dispatch during the previous cycle so we resume dispatching from
1656 // that point in the list of motion samples.
1657 // Otherwise, we just start from the first sample of the motion event.
1658 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1659 if (! firstMotionSample) {
1660 firstMotionSample = & motionEntry->firstSample;
1661 }
1662
Jeff Brownd3616592010-07-16 17:21:06 -07001663 // Set the X and Y offset depending on the input source.
1664 float xOffset, yOffset;
1665 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1666 xOffset = dispatchEntry->xOffset;
1667 yOffset = dispatchEntry->yOffset;
1668 } else {
1669 xOffset = 0.0f;
1670 yOffset = 0.0f;
1671 }
1672
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001673 // Publish the motion event and the first motion sample.
1674 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07001675 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownd3616592010-07-16 17:21:06 -07001676 xOffset, yOffset,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001677 motionEntry->xPrecision, motionEntry->yPrecision,
1678 motionEntry->downTime, firstMotionSample->eventTime,
1679 motionEntry->pointerCount, motionEntry->pointerIds,
1680 firstMotionSample->pointerCoords);
1681
1682 if (status) {
1683 LOGE("channel '%s' ~ Could not publish motion event, "
1684 "status=%d", connection->getInputChannelName(), status);
1685 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1686 return;
1687 }
1688
1689 // Append additional motion samples.
1690 MotionSample* nextMotionSample = firstMotionSample->next;
1691 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1692 status = connection->inputPublisher.appendMotionSample(
1693 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1694 if (status == NO_MEMORY) {
1695#if DEBUG_DISPATCH_CYCLE
1696 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1697 "be sent in the next dispatch cycle.",
1698 connection->getInputChannelName());
1699#endif
1700 break;
1701 }
1702 if (status != OK) {
1703 LOGE("channel '%s' ~ Could not append motion sample "
1704 "for a reason other than out of memory, status=%d",
1705 connection->getInputChannelName(), status);
1706 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1707 return;
1708 }
1709 }
1710
1711 // Remember the next motion sample that we could not dispatch, in case we ran out
1712 // of space in the shared memory buffer.
1713 dispatchEntry->tailMotionSample = nextMotionSample;
1714 break;
1715 }
1716
1717 default: {
1718 assert(false);
1719 }
1720 }
1721
1722 // Send the dispatch signal.
1723 status = connection->inputPublisher.sendDispatchSignal();
1724 if (status) {
1725 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1726 connection->getInputChannelName(), status);
1727 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1728 return;
1729 }
1730
1731 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001732 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001733 connection->lastDispatchTime = currentTime;
1734
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001735 // Notify other system components.
1736 onDispatchCycleStartedLocked(currentTime, connection);
1737}
1738
Jeff Brown7fbdc842010-06-17 20:52:56 -07001739void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1740 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001741#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001742 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001743 "%01.1fms since dispatch",
1744 connection->getInputChannelName(),
1745 connection->getEventLatencyMillis(currentTime),
1746 connection->getDispatchLatencyMillis(currentTime));
1747#endif
1748
Jeff Brown9c3cda02010-06-15 01:31:58 -07001749 if (connection->status == Connection::STATUS_BROKEN
1750 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001751 return;
1752 }
1753
Jeff Brown519e0242010-09-15 15:18:56 -07001754 // Notify other system components.
1755 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001756
1757 // Reset the publisher since the event has been consumed.
1758 // We do this now so that the publisher can release some of its internal resources
1759 // while waiting for the next dispatch cycle to begin.
1760 status_t status = connection->inputPublisher.reset();
1761 if (status) {
1762 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1763 connection->getInputChannelName(), status);
1764 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1765 return;
1766 }
1767
Jeff Brownb88102f2010-09-08 11:49:43 -07001768 startNextDispatchCycleLocked(currentTime, connection);
1769}
1770
1771void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1772 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001773 // Start the next dispatch cycle for this connection.
1774 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001775 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001776 if (dispatchEntry->inProgress) {
1777 // Finish or resume current event in progress.
1778 if (dispatchEntry->tailMotionSample) {
1779 // We have a tail of undispatched motion samples.
1780 // Reuse the same DispatchEntry and start a new cycle.
1781 dispatchEntry->inProgress = false;
1782 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1783 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07001784 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001785 return;
1786 }
1787 // Finished.
1788 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07001789 if (dispatchEntry->hasForegroundTarget()) {
1790 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001791 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001792 mAllocator.releaseDispatchEntry(dispatchEntry);
1793 } else {
1794 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07001795 // progress event, which means we actually aborted it.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001796 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07001797 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001798 return;
1799 }
1800 }
1801
1802 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07001803 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001804}
1805
Jeff Brown7fbdc842010-06-17 20:52:56 -07001806void InputDispatcher::abortDispatchCycleLocked(nsecs_t currentTime,
1807 const sp<Connection>& connection, bool broken) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001808#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001809 LOGD("channel '%s' ~ abortDispatchCycle - broken=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001810 connection->getInputChannelName(), toString(broken));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001811#endif
1812
Jeff Brownb88102f2010-09-08 11:49:43 -07001813 // Input state will no longer be realistic.
1814 connection->inputState.setOutOfSync();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001815
Jeff Brownb88102f2010-09-08 11:49:43 -07001816 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07001817 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001818
1819 // Handle the case where the connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07001820 // Ignore already broken or zombie connections.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001821 if (broken) {
Jeff Brown519e0242010-09-15 15:18:56 -07001822 if (connection->status == Connection::STATUS_NORMAL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07001823 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001824
Jeff Brown9c3cda02010-06-15 01:31:58 -07001825 // Notify other system components.
1826 onDispatchCycleBrokenLocked(currentTime, connection);
1827 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001828 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001829}
1830
Jeff Brown519e0242010-09-15 15:18:56 -07001831void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1832 while (! connection->outboundQueue.isEmpty()) {
1833 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1834 if (dispatchEntry->hasForegroundTarget()) {
1835 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001836 }
1837 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001838 }
1839
Jeff Brown519e0242010-09-15 15:18:56 -07001840 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07001841}
1842
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001843int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001844 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1845
1846 { // acquire lock
1847 AutoMutex _l(d->mLock);
1848
1849 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1850 if (connectionIndex < 0) {
1851 LOGE("Received spurious receive callback for unknown input channel. "
1852 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001853 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001854 }
1855
Jeff Brown7fbdc842010-06-17 20:52:56 -07001856 nsecs_t currentTime = now();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001857
1858 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001859 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001860 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1861 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001862 d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001863 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001864 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001865 }
1866
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001867 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001868 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1869 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001870 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001871 }
1872
1873 status_t status = connection->inputPublisher.receiveFinishedSignal();
1874 if (status) {
1875 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1876 connection->getInputChannelName(), status);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001877 d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001878 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001879 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001880 }
1881
Jeff Brown7fbdc842010-06-17 20:52:56 -07001882 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001883 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001884 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001885 } // release lock
1886}
1887
Jeff Brown01ce2e92010-09-26 22:20:12 -07001888InputDispatcher::MotionEntry*
1889InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1890 assert(pointerIds.value != 0);
1891
1892 uint32_t splitPointerIndexMap[MAX_POINTERS];
1893 int32_t splitPointerIds[MAX_POINTERS];
1894 PointerCoords splitPointerCoords[MAX_POINTERS];
1895
1896 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1897 uint32_t splitPointerCount = 0;
1898
1899 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1900 originalPointerIndex++) {
1901 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1902 if (pointerIds.hasBit(pointerId)) {
1903 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1904 splitPointerIds[splitPointerCount] = pointerId;
1905 splitPointerCoords[splitPointerCount] =
1906 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1907 splitPointerCount += 1;
1908 }
1909 }
1910 assert(splitPointerCount == pointerIds.count());
1911
1912 int32_t action = originalMotionEntry->action;
1913 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1914 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
1915 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1916 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
1917 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
1918 if (pointerIds.hasBit(pointerId)) {
1919 if (pointerIds.count() == 1) {
1920 // The first/last pointer went down/up.
1921 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
1922 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07001923 } else {
1924 // A secondary pointer went down/up.
1925 uint32_t splitPointerIndex = 0;
1926 while (pointerId != splitPointerIds[splitPointerIndex]) {
1927 splitPointerIndex += 1;
1928 }
1929 action = maskedAction | (splitPointerIndex
1930 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07001931 }
1932 } else {
1933 // An unrelated pointer changed.
1934 action = AMOTION_EVENT_ACTION_MOVE;
1935 }
1936 }
1937
1938 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
1939 originalMotionEntry->eventTime,
1940 originalMotionEntry->deviceId,
1941 originalMotionEntry->source,
1942 originalMotionEntry->policyFlags,
1943 action,
1944 originalMotionEntry->flags,
1945 originalMotionEntry->metaState,
1946 originalMotionEntry->edgeFlags,
1947 originalMotionEntry->xPrecision,
1948 originalMotionEntry->yPrecision,
1949 originalMotionEntry->downTime,
1950 splitPointerCount, splitPointerIds, splitPointerCoords);
1951
1952 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
1953 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
1954 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
1955 splitPointerIndex++) {
1956 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
1957 splitPointerCoords[splitPointerIndex] =
1958 originalMotionSample->pointerCoords[originalPointerIndex];
1959 }
1960
1961 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
1962 splitPointerCoords);
1963 }
1964
1965 return splitMotionEntry;
1966}
1967
Jeff Brown9c3cda02010-06-15 01:31:58 -07001968void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001969#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07001970 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001971#endif
1972
Jeff Brownb88102f2010-09-08 11:49:43 -07001973 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001974 { // acquire lock
1975 AutoMutex _l(mLock);
1976
Jeff Brown7fbdc842010-06-17 20:52:56 -07001977 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001978 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001979 } // release lock
1980
Jeff Brownb88102f2010-09-08 11:49:43 -07001981 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001982 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001983 }
1984}
1985
Jeff Brownc5ed5912010-07-14 18:48:53 -07001986void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001987 uint32_t policyFlags, int32_t action, int32_t flags,
1988 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
1989#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brownc5ed5912010-07-14 18:48:53 -07001990 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001991 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07001992 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001993 keyCode, scanCode, metaState, downTime);
1994#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001995 if (! validateKeyEvent(action)) {
1996 return;
1997 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001998
Jeff Brownb88102f2010-09-08 11:49:43 -07001999 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002000 { // acquire lock
2001 AutoMutex _l(mLock);
2002
Jeff Brown7fbdc842010-06-17 20:52:56 -07002003 int32_t repeatCount = 0;
2004 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002005 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002006 metaState, repeatCount, downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002007
Jeff Brownb88102f2010-09-08 11:49:43 -07002008 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002009 } // release lock
2010
Jeff Brownb88102f2010-09-08 11:49:43 -07002011 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002012 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002013 }
2014}
2015
Jeff Brownc5ed5912010-07-14 18:48:53 -07002016void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002017 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002018 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2019 float xPrecision, float yPrecision, nsecs_t downTime) {
2020#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brownc5ed5912010-07-14 18:48:53 -07002021 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002022 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2023 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2024 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002025 xPrecision, yPrecision, downTime);
2026 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002027 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002028 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002029 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002030 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown8d608662010-08-30 03:02:23 -07002031 pointerCoords[i].pressure, pointerCoords[i].size,
2032 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2033 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2034 pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002035 }
2036#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002037 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2038 return;
2039 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002040
Jeff Brownb88102f2010-09-08 11:49:43 -07002041 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002042 { // acquire lock
2043 AutoMutex _l(mLock);
2044
2045 // Attempt batching and streaming of move events.
Jeff Brownc5ed5912010-07-14 18:48:53 -07002046 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002047 // BATCHING CASE
2048 //
2049 // Try to append a move sample to the tail of the inbound queue for this device.
2050 // Give up if we encounter a non-move motion event for this device since that
2051 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002052 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2053 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002054 if (entry->type != EventEntry::TYPE_MOTION) {
2055 // Keep looking for motion events.
2056 continue;
2057 }
2058
2059 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2060 if (motionEntry->deviceId != deviceId) {
2061 // Keep looking for this device.
2062 continue;
2063 }
2064
Jeff Brownc5ed5912010-07-14 18:48:53 -07002065 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown7fbdc842010-06-17 20:52:56 -07002066 || motionEntry->pointerCount != pointerCount
2067 || motionEntry->isInjected()) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002068 // Last motion event in the queue for this device is not compatible for
2069 // appending new samples. Stop here.
2070 goto NoBatchingOrStreaming;
2071 }
2072
2073 // The last motion event is a move and is compatible for appending.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002074 // Do the batching magic.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002075 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002076#if DEBUG_BATCHING
2077 LOGD("Appended motion sample onto batch for most recent "
2078 "motion event for this device in the inbound queue.");
2079#endif
Jeff Brown9c3cda02010-06-15 01:31:58 -07002080 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002081 }
2082
2083 // STREAMING CASE
2084 //
2085 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002086 // Search the outbound queue for the current foreground targets to find a dispatched
2087 // motion event that is still in progress. If found, then, appen the new sample to
2088 // that event and push it out to all current targets. The logic in
2089 // prepareDispatchCycleLocked takes care of the case where some targets may
2090 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002091 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002092 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2093 const InputTarget& inputTarget = mCurrentInputTargets[i];
2094 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2095 // Skip non-foreground targets. We only want to stream if there is at
2096 // least one foreground target whose dispatch is still in progress.
2097 continue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002098 }
Jeff Brown519e0242010-09-15 15:18:56 -07002099
2100 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2101 if (connectionIndex < 0) {
2102 // Connection must no longer be valid.
2103 continue;
2104 }
2105
2106 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2107 if (connection->outboundQueue.isEmpty()) {
2108 // This foreground target has an empty outbound queue.
2109 continue;
2110 }
2111
2112 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2113 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002114 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2115 || dispatchEntry->isSplit()) {
2116 // No motion event is being dispatched, or it is being split across
2117 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002118 continue;
2119 }
2120
2121 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2122 dispatchEntry->eventEntry);
2123 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2124 || motionEntry->deviceId != deviceId
2125 || motionEntry->pointerCount != pointerCount
2126 || motionEntry->isInjected()) {
2127 // The motion event is not compatible with this move.
2128 continue;
2129 }
2130
2131 // Hurray! This foreground target is currently dispatching a move event
2132 // that we can stream onto. Append the motion sample and resume dispatch.
2133 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2134#if DEBUG_BATCHING
2135 LOGD("Appended motion sample onto batch for most recently dispatched "
2136 "motion event for this device in the outbound queues. "
2137 "Attempting to stream the motion sample.");
2138#endif
2139 nsecs_t currentTime = now();
2140 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2141 true /*resumeWithAppendedMotionSample*/);
2142
2143 runCommandsLockedInterruptible();
2144 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002145 }
2146 }
2147
2148NoBatchingOrStreaming:;
2149 }
2150
2151 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002152 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002153 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002154 xPrecision, yPrecision, downTime,
2155 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002156
Jeff Brownb88102f2010-09-08 11:49:43 -07002157 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002158 } // release lock
2159
Jeff Brownb88102f2010-09-08 11:49:43 -07002160 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002161 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002162 }
2163}
2164
Jeff Brown7fbdc842010-06-17 20:52:56 -07002165int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002166 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002167#if DEBUG_INBOUND_EVENT_DETAILS
2168 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002169 "syncMode=%d, timeoutMillis=%d",
2170 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002171#endif
2172
2173 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2174
Jeff Brown01ce2e92010-09-26 22:20:12 -07002175 InjectionState* injectionState;
Jeff Brownb88102f2010-09-08 11:49:43 -07002176 bool needWake;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002177 { // acquire lock
2178 AutoMutex _l(mLock);
2179
Jeff Brown01ce2e92010-09-26 22:20:12 -07002180 EventEntry* injectedEntry = createEntryFromInjectedInputEventLocked(event);
Jeff Brownb88102f2010-09-08 11:49:43 -07002181 if (! injectedEntry) {
2182 return INPUT_EVENT_INJECTION_FAILED;
2183 }
2184
Jeff Brown01ce2e92010-09-26 22:20:12 -07002185 injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002186 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002187 injectionState->injectionIsAsync = true;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002188 }
2189
Jeff Brown01ce2e92010-09-26 22:20:12 -07002190 injectionState->refCount += 1;
2191 injectedEntry->injectionState = injectionState;
2192
Jeff Brownb88102f2010-09-08 11:49:43 -07002193 needWake = enqueueInboundEventLocked(injectedEntry);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002194 } // release lock
2195
Jeff Brownb88102f2010-09-08 11:49:43 -07002196 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002197 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002198 }
2199
2200 int32_t injectionResult;
2201 { // acquire lock
2202 AutoMutex _l(mLock);
2203
Jeff Brown6ec402b2010-07-28 15:48:59 -07002204 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2205 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2206 } else {
2207 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002208 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002209 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2210 break;
2211 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002212
Jeff Brown7fbdc842010-06-17 20:52:56 -07002213 nsecs_t remainingTimeout = endTime - now();
2214 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002215#if DEBUG_INJECTION
2216 LOGD("injectInputEvent - Timed out waiting for injection result "
2217 "to become available.");
2218#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002219 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2220 break;
2221 }
2222
Jeff Brown6ec402b2010-07-28 15:48:59 -07002223 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2224 }
2225
2226 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2227 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002228 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002229#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002230 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002231 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002232#endif
2233 nsecs_t remainingTimeout = endTime - now();
2234 if (remainingTimeout <= 0) {
2235#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002236 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002237 "dispatches to finish.");
2238#endif
2239 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2240 break;
2241 }
2242
2243 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2244 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002245 }
2246 }
2247
Jeff Brown01ce2e92010-09-26 22:20:12 -07002248 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002249 } // release lock
2250
Jeff Brown6ec402b2010-07-28 15:48:59 -07002251#if DEBUG_INJECTION
2252 LOGD("injectInputEvent - Finished with result %d. "
2253 "injectorPid=%d, injectorUid=%d",
2254 injectionResult, injectorPid, injectorUid);
2255#endif
2256
Jeff Brown7fbdc842010-06-17 20:52:56 -07002257 return injectionResult;
2258}
2259
2260void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002261 InjectionState* injectionState = entry->injectionState;
2262 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002263#if DEBUG_INJECTION
2264 LOGD("Setting input event injection result to %d. "
2265 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002266 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002267#endif
2268
Jeff Brown01ce2e92010-09-26 22:20:12 -07002269 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002270 // Log the outcome since the injector did not wait for the injection result.
2271 switch (injectionResult) {
2272 case INPUT_EVENT_INJECTION_SUCCEEDED:
2273 LOGV("Asynchronous input event injection succeeded.");
2274 break;
2275 case INPUT_EVENT_INJECTION_FAILED:
2276 LOGW("Asynchronous input event injection failed.");
2277 break;
2278 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2279 LOGW("Asynchronous input event injection permission denied.");
2280 break;
2281 case INPUT_EVENT_INJECTION_TIMED_OUT:
2282 LOGW("Asynchronous input event injection timed out.");
2283 break;
2284 }
2285 }
2286
Jeff Brown01ce2e92010-09-26 22:20:12 -07002287 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002288 mInjectionResultAvailableCondition.broadcast();
2289 }
2290}
2291
Jeff Brown01ce2e92010-09-26 22:20:12 -07002292void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2293 InjectionState* injectionState = entry->injectionState;
2294 if (injectionState) {
2295 injectionState->pendingForegroundDispatches += 1;
2296 }
2297}
2298
Jeff Brown519e0242010-09-15 15:18:56 -07002299void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002300 InjectionState* injectionState = entry->injectionState;
2301 if (injectionState) {
2302 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002303
Jeff Brown01ce2e92010-09-26 22:20:12 -07002304 if (injectionState->pendingForegroundDispatches == 0) {
2305 mInjectionSyncFinishedCondition.broadcast();
2306 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002307 }
2308}
2309
2310InputDispatcher::EventEntry* InputDispatcher::createEntryFromInjectedInputEventLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002311 const InputEvent* event) {
2312 switch (event->getType()) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07002313 case AINPUT_EVENT_TYPE_KEY: {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002314 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002315 if (! validateKeyEvent(keyEvent->getAction())) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002316 return NULL;
2317 }
2318
Jeff Brown85a31762010-09-01 17:01:00 -07002319 uint32_t policyFlags = POLICY_FLAG_INJECTED;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002320
2321 KeyEntry* keyEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
Jeff Brownc5ed5912010-07-14 18:48:53 -07002322 keyEvent->getDeviceId(), keyEvent->getSource(), policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002323 keyEvent->getAction(), keyEvent->getFlags(),
2324 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
2325 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2326 return keyEntry;
2327 }
2328
Jeff Brownc5ed5912010-07-14 18:48:53 -07002329 case AINPUT_EVENT_TYPE_MOTION: {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002330 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002331 if (! validateMotionEvent(motionEvent->getAction(),
2332 motionEvent->getPointerCount(), motionEvent->getPointerIds())) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002333 return NULL;
2334 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002335
Jeff Brown85a31762010-09-01 17:01:00 -07002336 uint32_t policyFlags = POLICY_FLAG_INJECTED;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002337
2338 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2339 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2340 size_t pointerCount = motionEvent->getPointerCount();
2341
2342 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002343 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
Jeff Brown85a31762010-09-01 17:01:00 -07002344 motionEvent->getAction(), motionEvent->getFlags(),
2345 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
Jeff Brown7fbdc842010-06-17 20:52:56 -07002346 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2347 motionEvent->getDownTime(), uint32_t(pointerCount),
2348 motionEvent->getPointerIds(), samplePointerCoords);
2349 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2350 sampleEventTimes += 1;
2351 samplePointerCoords += pointerCount;
2352 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2353 }
2354 return motionEntry;
2355 }
2356
2357 default:
2358 assert(false);
2359 return NULL;
2360 }
2361}
2362
Jeff Brown01ce2e92010-09-26 22:20:12 -07002363const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2364 for (size_t i = 0; i < mWindows.size(); i++) {
2365 const InputWindow* window = & mWindows[i];
2366 if (window->inputChannel == inputChannel) {
2367 return window;
2368 }
2369 }
2370 return NULL;
2371}
2372
Jeff Brownb88102f2010-09-08 11:49:43 -07002373void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2374#if DEBUG_FOCUS
2375 LOGD("setInputWindows");
2376#endif
2377 { // acquire lock
2378 AutoMutex _l(mLock);
2379
Jeff Brown01ce2e92010-09-26 22:20:12 -07002380 // Clear old window pointers.
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002381 mFocusedWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07002382 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002383
2384 // Loop over new windows and rebuild the necessary window pointers for
2385 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002386 mWindows.appendVector(inputWindows);
2387
2388 size_t numWindows = mWindows.size();
2389 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002390 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002391 if (window->hasFocus) {
2392 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002393 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002394 }
2395 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002396
2397 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2398 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2399 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2400 if (window) {
2401 touchedWindow.window = window;
2402 i += 1;
2403 } else {
2404 mTouchState.windows.removeAt(i);
2405 }
2406 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002407
Jeff Brownb88102f2010-09-08 11:49:43 -07002408#if DEBUG_FOCUS
2409 logDispatchStateLocked();
2410#endif
2411 } // release lock
2412
2413 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002414 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002415}
2416
2417void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2418#if DEBUG_FOCUS
2419 LOGD("setFocusedApplication");
2420#endif
2421 { // acquire lock
2422 AutoMutex _l(mLock);
2423
2424 releaseFocusedApplicationLocked();
2425
2426 if (inputApplication) {
2427 mFocusedApplicationStorage = *inputApplication;
2428 mFocusedApplication = & mFocusedApplicationStorage;
2429 }
2430
2431#if DEBUG_FOCUS
2432 logDispatchStateLocked();
2433#endif
2434 } // release lock
2435
2436 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002437 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002438}
2439
2440void InputDispatcher::releaseFocusedApplicationLocked() {
2441 if (mFocusedApplication) {
2442 mFocusedApplication = NULL;
2443 mFocusedApplicationStorage.handle.clear();
2444 }
2445}
2446
2447void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2448#if DEBUG_FOCUS
2449 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2450#endif
2451
2452 bool changed;
2453 { // acquire lock
2454 AutoMutex _l(mLock);
2455
2456 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2457 if (mDispatchFrozen && ! frozen) {
2458 resetANRTimeoutsLocked();
2459 }
2460
2461 mDispatchEnabled = enabled;
2462 mDispatchFrozen = frozen;
2463 changed = true;
2464 } else {
2465 changed = false;
2466 }
2467
2468#if DEBUG_FOCUS
2469 logDispatchStateLocked();
2470#endif
2471 } // release lock
2472
2473 if (changed) {
2474 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002475 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002476 }
2477}
2478
Jeff Brownb88102f2010-09-08 11:49:43 -07002479void InputDispatcher::logDispatchStateLocked() {
2480 String8 dump;
2481 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002482
2483 char* text = dump.lockBuffer(dump.size());
2484 char* start = text;
2485 while (*start != '\0') {
2486 char* end = strchr(start, '\n');
2487 if (*end == '\n') {
2488 *(end++) = '\0';
2489 }
2490 LOGD("%s", start);
2491 start = end;
2492 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002493}
2494
2495void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002496 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2497 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07002498
2499 if (mFocusedApplication) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002500 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002501 mFocusedApplication->name.string(),
2502 mFocusedApplication->dispatchingTimeout / 1000000.0);
2503 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002504 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002505 }
Jeff Brownf2f487182010-10-01 17:46:21 -07002506 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002507 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f487182010-10-01 17:46:21 -07002508
2509 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2510 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2511 if (!mTouchState.windows.isEmpty()) {
2512 dump.append(INDENT "TouchedWindows:\n");
2513 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2514 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2515 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2516 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2517 touchedWindow.targetFlags);
2518 }
2519 } else {
2520 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002521 }
2522
Jeff Brownf2f487182010-10-01 17:46:21 -07002523 if (!mWindows.isEmpty()) {
2524 dump.append(INDENT "Windows:\n");
2525 for (size_t i = 0; i < mWindows.size(); i++) {
2526 const InputWindow& window = mWindows[i];
2527 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2528 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2529 "frame=[%d,%d][%d,%d], "
2530 "visibleFrame=[%d,%d][%d,%d], "
2531 "touchableArea=[%d,%d][%d,%d], "
2532 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2533 i, window.name.string(),
2534 toString(window.paused),
2535 toString(window.hasFocus),
2536 toString(window.hasWallpaper),
2537 toString(window.visible),
2538 toString(window.canReceiveKeys),
2539 window.layoutParamsFlags, window.layoutParamsType,
2540 window.layer,
2541 window.frameLeft, window.frameTop,
2542 window.frameRight, window.frameBottom,
2543 window.visibleFrameLeft, window.visibleFrameTop,
2544 window.visibleFrameRight, window.visibleFrameBottom,
2545 window.touchableAreaLeft, window.touchableAreaTop,
2546 window.touchableAreaRight, window.touchableAreaBottom,
2547 window.ownerPid, window.ownerUid,
2548 window.dispatchingTimeout / 1000000.0);
2549 }
2550 } else {
2551 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002552 }
2553
Jeff Brownf2f487182010-10-01 17:46:21 -07002554 if (!mMonitoringChannels.isEmpty()) {
2555 dump.append(INDENT "MonitoringChannels:\n");
2556 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2557 const sp<InputChannel>& channel = mMonitoringChannels[i];
2558 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2559 }
2560 } else {
2561 dump.append(INDENT "MonitoringChannels: <none>\n");
2562 }
Jeff Brown519e0242010-09-15 15:18:56 -07002563
Jeff Brownf2f487182010-10-01 17:46:21 -07002564 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2565
2566 if (!mActiveConnections.isEmpty()) {
2567 dump.append(INDENT "ActiveConnections:\n");
2568 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2569 const Connection* connection = mActiveConnections[i];
2570 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
2571 "inputState.isNeutral=%s, inputState.isOutOfSync=%s\n",
2572 i, connection->getInputChannelName(), connection->getStatusLabel(),
2573 connection->outboundQueue.count(),
2574 toString(connection->inputState.isNeutral()),
2575 toString(connection->inputState.isOutOfSync()));
2576 }
2577 } else {
2578 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002579 }
2580
2581 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002582 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002583 (mAppSwitchDueTime - now()) / 1000000.0);
2584 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002585 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002586 }
2587}
2588
2589status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002590#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07002591 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2592 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07002593#endif
2594
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002595 { // acquire lock
2596 AutoMutex _l(mLock);
2597
Jeff Brown519e0242010-09-15 15:18:56 -07002598 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002599 LOGW("Attempted to register already registered input channel '%s'",
2600 inputChannel->getName().string());
2601 return BAD_VALUE;
2602 }
2603
2604 sp<Connection> connection = new Connection(inputChannel);
2605 status_t status = connection->initialize();
2606 if (status) {
2607 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2608 inputChannel->getName().string(), status);
2609 return status;
2610 }
2611
Jeff Brown2cbecea2010-08-17 15:59:26 -07002612 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002613 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002614
Jeff Brownb88102f2010-09-08 11:49:43 -07002615 if (monitor) {
2616 mMonitoringChannels.push(inputChannel);
2617 }
2618
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002619 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07002620
Jeff Brown9c3cda02010-06-15 01:31:58 -07002621 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002622 } // release lock
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002623 return OK;
2624}
2625
2626status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002627#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07002628 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07002629#endif
2630
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002631 { // acquire lock
2632 AutoMutex _l(mLock);
2633
Jeff Brown519e0242010-09-15 15:18:56 -07002634 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002635 if (connectionIndex < 0) {
2636 LOGW("Attempted to unregister already unregistered input channel '%s'",
2637 inputChannel->getName().string());
2638 return BAD_VALUE;
2639 }
2640
2641 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2642 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2643
2644 connection->status = Connection::STATUS_ZOMBIE;
2645
Jeff Brownb88102f2010-09-08 11:49:43 -07002646 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2647 if (mMonitoringChannels[i] == inputChannel) {
2648 mMonitoringChannels.removeAt(i);
2649 break;
2650 }
2651 }
2652
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002653 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07002654
Jeff Brown7fbdc842010-06-17 20:52:56 -07002655 nsecs_t currentTime = now();
2656 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002657
2658 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002659 } // release lock
2660
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002661 // Wake the poll loop because removing the connection may have changed the current
2662 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002663 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002664 return OK;
2665}
2666
Jeff Brown519e0242010-09-15 15:18:56 -07002667ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07002668 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2669 if (connectionIndex >= 0) {
2670 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2671 if (connection->inputChannel.get() == inputChannel.get()) {
2672 return connectionIndex;
2673 }
2674 }
2675
2676 return -1;
2677}
2678
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002679void InputDispatcher::activateConnectionLocked(Connection* connection) {
2680 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2681 if (mActiveConnections.itemAt(i) == connection) {
2682 return;
2683 }
2684 }
2685 mActiveConnections.add(connection);
2686}
2687
2688void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2689 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2690 if (mActiveConnections.itemAt(i) == connection) {
2691 mActiveConnections.removeAt(i);
2692 return;
2693 }
2694 }
2695}
2696
Jeff Brown9c3cda02010-06-15 01:31:58 -07002697void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002698 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002699}
2700
Jeff Brown9c3cda02010-06-15 01:31:58 -07002701void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002702 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002703}
2704
Jeff Brown9c3cda02010-06-15 01:31:58 -07002705void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002706 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002707 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2708 connection->getInputChannelName());
2709
Jeff Brown9c3cda02010-06-15 01:31:58 -07002710 CommandEntry* commandEntry = postCommandLocked(
2711 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002712 commandEntry->connection = connection;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002713}
2714
Jeff Brown519e0242010-09-15 15:18:56 -07002715void InputDispatcher::onANRLocked(
2716 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2717 nsecs_t eventTime, nsecs_t waitStartTime) {
2718 LOGI("Application is not responding: %s. "
2719 "%01.1fms since event, %01.1fms since wait started",
2720 getApplicationWindowLabelLocked(application, window).string(),
2721 (currentTime - eventTime) / 1000000.0,
2722 (currentTime - waitStartTime) / 1000000.0);
2723
2724 CommandEntry* commandEntry = postCommandLocked(
2725 & InputDispatcher::doNotifyANRLockedInterruptible);
2726 if (application) {
2727 commandEntry->inputApplicationHandle = application->handle;
2728 }
2729 if (window) {
2730 commandEntry->inputChannel = window->inputChannel;
2731 }
2732}
2733
Jeff Brownb88102f2010-09-08 11:49:43 -07002734void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2735 CommandEntry* commandEntry) {
2736 mLock.unlock();
2737
2738 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2739
2740 mLock.lock();
2741}
2742
Jeff Brown9c3cda02010-06-15 01:31:58 -07002743void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2744 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002745 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07002746
Jeff Brown7fbdc842010-06-17 20:52:56 -07002747 if (connection->status != Connection::STATUS_ZOMBIE) {
2748 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002749
Jeff Brown7fbdc842010-06-17 20:52:56 -07002750 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2751
2752 mLock.lock();
2753 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07002754}
2755
Jeff Brown519e0242010-09-15 15:18:56 -07002756void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07002757 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07002758 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002759
Jeff Brown519e0242010-09-15 15:18:56 -07002760 nsecs_t newTimeout = mPolicy->notifyANR(
2761 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002762
Jeff Brown519e0242010-09-15 15:18:56 -07002763 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002764
Jeff Brown519e0242010-09-15 15:18:56 -07002765 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002766}
2767
Jeff Brownb88102f2010-09-08 11:49:43 -07002768void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2769 CommandEntry* commandEntry) {
2770 KeyEntry* entry = commandEntry->keyEntry;
2771 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2772 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2773 entry->downTime, entry->eventTime);
2774
2775 mLock.unlock();
2776
2777 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2778 & mReusableKeyEvent, entry->policyFlags);
2779
2780 mLock.lock();
2781
2782 entry->interceptKeyResult = consumed
2783 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2784 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2785 mAllocator.releaseKeyEntry(entry);
2786}
2787
2788void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2789 mLock.unlock();
2790
Jeff Brown01ce2e92010-09-26 22:20:12 -07002791 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07002792
2793 mLock.lock();
2794}
2795
Jeff Brown519e0242010-09-15 15:18:56 -07002796void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
2797 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
2798 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07002799}
2800
2801void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002802 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002803 dumpDispatchStateLocked(dump);
2804}
2805
Jeff Brown9c3cda02010-06-15 01:31:58 -07002806
Jeff Brown519e0242010-09-15 15:18:56 -07002807// --- InputDispatcher::Queue ---
2808
2809template <typename T>
2810uint32_t InputDispatcher::Queue<T>::count() const {
2811 uint32_t result = 0;
2812 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
2813 result += 1;
2814 }
2815 return result;
2816}
2817
2818
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002819// --- InputDispatcher::Allocator ---
2820
2821InputDispatcher::Allocator::Allocator() {
2822}
2823
Jeff Brown01ce2e92010-09-26 22:20:12 -07002824InputDispatcher::InjectionState*
2825InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
2826 InjectionState* injectionState = mInjectionStatePool.alloc();
2827 injectionState->refCount = 1;
2828 injectionState->injectorPid = injectorPid;
2829 injectionState->injectorUid = injectorUid;
2830 injectionState->injectionIsAsync = false;
2831 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
2832 injectionState->pendingForegroundDispatches = 0;
2833 return injectionState;
2834}
2835
Jeff Brown7fbdc842010-06-17 20:52:56 -07002836void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
2837 nsecs_t eventTime) {
2838 entry->type = type;
2839 entry->refCount = 1;
2840 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07002841 entry->eventTime = eventTime;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002842 entry->injectionState = NULL;
2843}
2844
2845void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
2846 if (entry->injectionState) {
2847 releaseInjectionState(entry->injectionState);
2848 entry->injectionState = NULL;
2849 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002850}
2851
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002852InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07002853InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002854 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002855 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002856 return entry;
2857}
2858
Jeff Brown7fbdc842010-06-17 20:52:56 -07002859InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002860 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002861 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
2862 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002863 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002864 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime);
2865
2866 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07002867 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002868 entry->policyFlags = policyFlags;
2869 entry->action = action;
2870 entry->flags = flags;
2871 entry->keyCode = keyCode;
2872 entry->scanCode = scanCode;
2873 entry->metaState = metaState;
2874 entry->repeatCount = repeatCount;
2875 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07002876 entry->syntheticRepeat = false;
2877 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002878 return entry;
2879}
2880
Jeff Brown7fbdc842010-06-17 20:52:56 -07002881InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002882 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002883 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
2884 nsecs_t downTime, uint32_t pointerCount,
2885 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002886 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002887 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime);
2888
2889 entry->eventTime = eventTime;
2890 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07002891 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002892 entry->policyFlags = policyFlags;
2893 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07002894 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002895 entry->metaState = metaState;
2896 entry->edgeFlags = edgeFlags;
2897 entry->xPrecision = xPrecision;
2898 entry->yPrecision = yPrecision;
2899 entry->downTime = downTime;
2900 entry->pointerCount = pointerCount;
2901 entry->firstSample.eventTime = eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002902 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002903 entry->lastSample = & entry->firstSample;
2904 for (uint32_t i = 0; i < pointerCount; i++) {
2905 entry->pointerIds[i] = pointerIds[i];
2906 entry->firstSample.pointerCoords[i] = pointerCoords[i];
2907 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002908 return entry;
2909}
2910
2911InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07002912 EventEntry* eventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07002913 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002914 DispatchEntry* entry = mDispatchEntryPool.alloc();
2915 entry->eventEntry = eventEntry;
2916 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07002917 entry->targetFlags = targetFlags;
2918 entry->xOffset = xOffset;
2919 entry->yOffset = yOffset;
Jeff Brownb88102f2010-09-08 11:49:43 -07002920 entry->inProgress = false;
2921 entry->headMotionSample = NULL;
2922 entry->tailMotionSample = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002923 return entry;
2924}
2925
Jeff Brown9c3cda02010-06-15 01:31:58 -07002926InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
2927 CommandEntry* entry = mCommandEntryPool.alloc();
2928 entry->command = command;
2929 return entry;
2930}
2931
Jeff Brown01ce2e92010-09-26 22:20:12 -07002932void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
2933 injectionState->refCount -= 1;
2934 if (injectionState->refCount == 0) {
2935 mInjectionStatePool.free(injectionState);
2936 } else {
2937 assert(injectionState->refCount > 0);
2938 }
2939}
2940
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002941void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
2942 switch (entry->type) {
2943 case EventEntry::TYPE_CONFIGURATION_CHANGED:
2944 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
2945 break;
2946 case EventEntry::TYPE_KEY:
2947 releaseKeyEntry(static_cast<KeyEntry*>(entry));
2948 break;
2949 case EventEntry::TYPE_MOTION:
2950 releaseMotionEntry(static_cast<MotionEntry*>(entry));
2951 break;
2952 default:
2953 assert(false);
2954 break;
2955 }
2956}
2957
2958void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
2959 ConfigurationChangedEntry* entry) {
2960 entry->refCount -= 1;
2961 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002962 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002963 mConfigurationChangeEntryPool.free(entry);
2964 } else {
2965 assert(entry->refCount > 0);
2966 }
2967}
2968
2969void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
2970 entry->refCount -= 1;
2971 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002972 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002973 mKeyEntryPool.free(entry);
2974 } else {
2975 assert(entry->refCount > 0);
2976 }
2977}
2978
2979void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
2980 entry->refCount -= 1;
2981 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002982 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002983 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
2984 MotionSample* next = sample->next;
2985 mMotionSamplePool.free(sample);
2986 sample = next;
2987 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002988 mMotionEntryPool.free(entry);
2989 } else {
2990 assert(entry->refCount > 0);
2991 }
2992}
2993
2994void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
2995 releaseEventEntry(entry->eventEntry);
2996 mDispatchEntryPool.free(entry);
2997}
2998
Jeff Brown9c3cda02010-06-15 01:31:58 -07002999void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3000 mCommandEntryPool.free(entry);
3001}
3002
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003003void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003004 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003005 MotionSample* sample = mMotionSamplePool.alloc();
3006 sample->eventTime = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003007 uint32_t pointerCount = motionEntry->pointerCount;
3008 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003009 sample->pointerCoords[i] = pointerCoords[i];
3010 }
3011
3012 sample->next = NULL;
3013 motionEntry->lastSample->next = sample;
3014 motionEntry->lastSample = sample;
3015}
3016
Jeff Brown01ce2e92010-09-26 22:20:12 -07003017void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3018 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003019
Jeff Brown01ce2e92010-09-26 22:20:12 -07003020 keyEntry->dispatchInProgress = false;
3021 keyEntry->syntheticRepeat = false;
3022 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003023}
3024
3025
Jeff Brownae9fc032010-08-18 15:51:08 -07003026// --- InputDispatcher::MotionEntry ---
3027
3028uint32_t InputDispatcher::MotionEntry::countSamples() const {
3029 uint32_t count = 1;
3030 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3031 count += 1;
3032 }
3033 return count;
3034}
3035
Jeff Brownb88102f2010-09-08 11:49:43 -07003036
3037// --- InputDispatcher::InputState ---
3038
3039InputDispatcher::InputState::InputState() :
3040 mIsOutOfSync(false) {
3041}
3042
3043InputDispatcher::InputState::~InputState() {
3044}
3045
3046bool InputDispatcher::InputState::isNeutral() const {
3047 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3048}
3049
3050bool InputDispatcher::InputState::isOutOfSync() const {
3051 return mIsOutOfSync;
3052}
3053
3054void InputDispatcher::InputState::setOutOfSync() {
3055 if (! isNeutral()) {
3056 mIsOutOfSync = true;
3057 }
3058}
3059
3060void InputDispatcher::InputState::resetOutOfSync() {
3061 mIsOutOfSync = false;
3062}
3063
3064InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3065 const EventEntry* entry) {
3066 switch (entry->type) {
3067 case EventEntry::TYPE_KEY:
3068 return trackKey(static_cast<const KeyEntry*>(entry));
3069
3070 case EventEntry::TYPE_MOTION:
3071 return trackMotion(static_cast<const MotionEntry*>(entry));
3072
3073 default:
3074 return CONSISTENT;
3075 }
3076}
3077
3078InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3079 const KeyEntry* entry) {
3080 int32_t action = entry->action;
3081 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3082 KeyMemento& memento = mKeyMementos.editItemAt(i);
3083 if (memento.deviceId == entry->deviceId
3084 && memento.source == entry->source
3085 && memento.keyCode == entry->keyCode
3086 && memento.scanCode == entry->scanCode) {
3087 switch (action) {
3088 case AKEY_EVENT_ACTION_UP:
3089 mKeyMementos.removeAt(i);
3090 if (isNeutral()) {
3091 mIsOutOfSync = false;
3092 }
3093 return CONSISTENT;
3094
3095 case AKEY_EVENT_ACTION_DOWN:
3096 return TOLERABLE;
3097
3098 default:
3099 return BROKEN;
3100 }
3101 }
3102 }
3103
3104 switch (action) {
3105 case AKEY_EVENT_ACTION_DOWN: {
3106 mKeyMementos.push();
3107 KeyMemento& memento = mKeyMementos.editTop();
3108 memento.deviceId = entry->deviceId;
3109 memento.source = entry->source;
3110 memento.keyCode = entry->keyCode;
3111 memento.scanCode = entry->scanCode;
3112 memento.downTime = entry->downTime;
3113 return CONSISTENT;
3114 }
3115
3116 default:
3117 return BROKEN;
3118 }
3119}
3120
3121InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3122 const MotionEntry* entry) {
3123 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3124 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3125 MotionMemento& memento = mMotionMementos.editItemAt(i);
3126 if (memento.deviceId == entry->deviceId
3127 && memento.source == entry->source) {
3128 switch (action) {
3129 case AMOTION_EVENT_ACTION_UP:
3130 case AMOTION_EVENT_ACTION_CANCEL:
3131 mMotionMementos.removeAt(i);
3132 if (isNeutral()) {
3133 mIsOutOfSync = false;
3134 }
3135 return CONSISTENT;
3136
3137 case AMOTION_EVENT_ACTION_DOWN:
3138 return TOLERABLE;
3139
3140 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3141 if (entry->pointerCount == memento.pointerCount + 1) {
3142 memento.setPointers(entry);
3143 return CONSISTENT;
3144 }
3145 return BROKEN;
3146
3147 case AMOTION_EVENT_ACTION_POINTER_UP:
3148 if (entry->pointerCount == memento.pointerCount - 1) {
3149 memento.setPointers(entry);
3150 return CONSISTENT;
3151 }
3152 return BROKEN;
3153
3154 case AMOTION_EVENT_ACTION_MOVE:
3155 if (entry->pointerCount == memento.pointerCount) {
3156 return CONSISTENT;
3157 }
3158 return BROKEN;
3159
3160 default:
3161 return BROKEN;
3162 }
3163 }
3164 }
3165
3166 switch (action) {
3167 case AMOTION_EVENT_ACTION_DOWN: {
3168 mMotionMementos.push();
3169 MotionMemento& memento = mMotionMementos.editTop();
3170 memento.deviceId = entry->deviceId;
3171 memento.source = entry->source;
3172 memento.xPrecision = entry->xPrecision;
3173 memento.yPrecision = entry->yPrecision;
3174 memento.downTime = entry->downTime;
3175 memento.setPointers(entry);
3176 return CONSISTENT;
3177 }
3178
3179 default:
3180 return BROKEN;
3181 }
3182}
3183
3184void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3185 pointerCount = entry->pointerCount;
3186 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3187 pointerIds[i] = entry->pointerIds[i];
3188 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3189 }
3190}
3191
3192void InputDispatcher::InputState::synthesizeCancelationEvents(
3193 Allocator* allocator, Vector<EventEntry*>& outEvents) const {
3194 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3195 const KeyMemento& memento = mKeyMementos.itemAt(i);
3196 outEvents.push(allocator->obtainKeyEntry(now(),
3197 memento.deviceId, memento.source, 0,
3198 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3199 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3200 }
3201
3202 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3203 const MotionMemento& memento = mMotionMementos.itemAt(i);
3204 outEvents.push(allocator->obtainMotionEntry(now(),
3205 memento.deviceId, memento.source, 0,
3206 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3207 memento.xPrecision, memento.yPrecision, memento.downTime,
3208 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3209 }
3210}
3211
3212void InputDispatcher::InputState::clear() {
3213 mKeyMementos.clear();
3214 mMotionMementos.clear();
3215 mIsOutOfSync = false;
3216}
3217
3218
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003219// --- InputDispatcher::Connection ---
3220
3221InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3222 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown519e0242010-09-15 15:18:56 -07003223 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003224}
3225
3226InputDispatcher::Connection::~Connection() {
3227}
3228
3229status_t InputDispatcher::Connection::initialize() {
3230 return inputPublisher.initialize();
3231}
3232
Jeff Brown9c3cda02010-06-15 01:31:58 -07003233const char* InputDispatcher::Connection::getStatusLabel() const {
3234 switch (status) {
3235 case STATUS_NORMAL:
3236 return "NORMAL";
3237
3238 case STATUS_BROKEN:
3239 return "BROKEN";
3240
Jeff Brown9c3cda02010-06-15 01:31:58 -07003241 case STATUS_ZOMBIE:
3242 return "ZOMBIE";
3243
3244 default:
3245 return "UNKNOWN";
3246 }
3247}
3248
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003249InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3250 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07003251 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3252 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003253 if (dispatchEntry->eventEntry == eventEntry) {
3254 return dispatchEntry;
3255 }
3256 }
3257 return NULL;
3258}
3259
Jeff Brownb88102f2010-09-08 11:49:43 -07003260
Jeff Brown9c3cda02010-06-15 01:31:58 -07003261// --- InputDispatcher::CommandEntry ---
3262
Jeff Brownb88102f2010-09-08 11:49:43 -07003263InputDispatcher::CommandEntry::CommandEntry() :
3264 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003265}
3266
3267InputDispatcher::CommandEntry::~CommandEntry() {
3268}
3269
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003270
Jeff Brown01ce2e92010-09-26 22:20:12 -07003271// --- InputDispatcher::TouchState ---
3272
3273InputDispatcher::TouchState::TouchState() :
3274 down(false), split(false) {
3275}
3276
3277InputDispatcher::TouchState::~TouchState() {
3278}
3279
3280void InputDispatcher::TouchState::reset() {
3281 down = false;
3282 split = false;
3283 windows.clear();
3284}
3285
3286void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3287 down = other.down;
3288 split = other.split;
3289 windows.clear();
3290 windows.appendVector(other.windows);
3291}
3292
3293void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3294 int32_t targetFlags, BitSet32 pointerIds) {
3295 if (targetFlags & InputTarget::FLAG_SPLIT) {
3296 split = true;
3297 }
3298
3299 for (size_t i = 0; i < windows.size(); i++) {
3300 TouchedWindow& touchedWindow = windows.editItemAt(i);
3301 if (touchedWindow.window == window) {
3302 touchedWindow.targetFlags |= targetFlags;
3303 touchedWindow.pointerIds.value |= pointerIds.value;
3304 return;
3305 }
3306 }
3307
3308 windows.push();
3309
3310 TouchedWindow& touchedWindow = windows.editTop();
3311 touchedWindow.window = window;
3312 touchedWindow.targetFlags = targetFlags;
3313 touchedWindow.pointerIds = pointerIds;
3314 touchedWindow.channel = window->inputChannel;
3315}
3316
3317void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3318 for (size_t i = 0 ; i < windows.size(); ) {
3319 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3320 windows.removeAt(i);
3321 } else {
3322 i += 1;
3323 }
3324 }
3325}
3326
3327const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3328 for (size_t i = 0; i < windows.size(); i++) {
3329 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3330 return windows[i].window;
3331 }
3332 }
3333 return NULL;
3334}
3335
3336
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003337// --- InputDispatcherThread ---
3338
3339InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3340 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3341}
3342
3343InputDispatcherThread::~InputDispatcherThread() {
3344}
3345
3346bool InputDispatcherThread::threadLoop() {
3347 mDispatcher->dispatchOnce();
3348 return true;
3349}
3350
3351} // namespace android