blob: aa54f82e91f11ee0ba4e9d817c1af91bfc840c65 [file] [log] [blame]
Jeff Browne839a582010-04-22 18:58:52 -07001//
2// Copyright 2010 The Android Open Source Project
3//
4// The input dispatcher.
5//
6#define LOG_TAG "InputDispatcher"
7
8//#define LOG_NDEBUG 0
9
10// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown50de30a2010-06-22 01:27:15 -070011#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Browne839a582010-04-22 18:58:52 -070012
13// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown50de30a2010-06-22 01:27:15 -070014#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Browne839a582010-04-22 18:58:52 -070015
16// Log debug messages about batching.
Jeff Brown50de30a2010-06-22 01:27:15 -070017#define DEBUG_BATCHING 0
Jeff Browne839a582010-04-22 18:58:52 -070018
19// Log debug messages about the dispatch cycle.
Jeff Brown50de30a2010-06-22 01:27:15 -070020#define DEBUG_DISPATCH_CYCLE 0
Jeff Browne839a582010-04-22 18:58:52 -070021
Jeff Brown54bc2812010-06-15 01:31:58 -070022// Log debug messages about registrations.
Jeff Brown50de30a2010-06-22 01:27:15 -070023#define DEBUG_REGISTRATION 0
Jeff Brown54bc2812010-06-15 01:31:58 -070024
Jeff Browne839a582010-04-22 18:58:52 -070025// Log debug messages about performance statistics.
Jeff Brown50de30a2010-06-22 01:27:15 -070026#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Browne839a582010-04-22 18:58:52 -070027
Jeff Brown51d45a72010-06-17 20:52:56 -070028// Log debug messages about input event injection.
Jeff Brown50de30a2010-06-22 01:27:15 -070029#define DEBUG_INJECTION 0
Jeff Brown51d45a72010-06-17 20:52:56 -070030
Jeff Brown542412c2010-08-18 15:51:08 -070031// Log debug messages about input event throttling.
32#define DEBUG_THROTTLING 0
33
Jeff Browna665ca82010-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 Browne839a582010-04-22 18:58:52 -070040#include <cutils/log.h>
41#include <ui/InputDispatcher.h>
Jeff Browna665ca82010-09-08 11:49:43 -070042#include <ui/PowerManager.h>
Jeff Browne839a582010-04-22 18:58:52 -070043
44#include <stddef.h>
45#include <unistd.h>
Jeff Browne839a582010-04-22 18:58:52 -070046#include <errno.h>
47#include <limits.h>
Jeff Browne839a582010-04-22 18:58:52 -070048
Jeff Brown2806e382010-10-01 17:46:21 -070049#define INDENT " "
50#define INDENT2 " "
51
Jeff Browne839a582010-04-22 18:58:52 -070052namespace android {
53
Jeff Browna665ca82010-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 Browne839a582010-04-22 18:58:52 -070066
Jeff Brown51d45a72010-06-17 20:52:56 -070067static inline nsecs_t now() {
68 return systemTime(SYSTEM_TIME_MONOTONIC);
69}
70
Jeff Browna665ca82010-09-08 11:49:43 -070071static inline const char* toString(bool value) {
72 return value ? "true" : "false";
73}
74
Jeff Brownd1b0a2b2010-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 Browna665ca82010-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 Browne839a582010-04-22 18:58:52 -0700150// --- InputDispatcher ---
151
Jeff Brown54bc2812010-06-15 01:31:58 -0700152InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Browna665ca82010-09-08 11:49:43 -0700153 mPolicy(policy),
154 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
155 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700156 mFocusedWindow(NULL),
Jeff Browna665ca82010-09-08 11:49:43 -0700157 mFocusedApplication(NULL),
158 mCurrentInputTargetsValid(false),
159 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown59abe7e2010-09-13 23:17:30 -0700160 mLooper = new Looper(false);
Jeff Browne839a582010-04-22 18:58:52 -0700161
Jeff Browna665ca82010-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 Browne839a582010-04-22 18:58:52 -0700165
Jeff Browna665ca82010-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 Browne839a582010-04-22 18:58:52 -0700169
170 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown54bc2812010-06-15 01:31:58 -0700171
Jeff Brown542412c2010-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 Browne839a582010-04-22 18:58:52 -0700180}
181
182InputDispatcher::~InputDispatcher() {
Jeff Browna665ca82010-09-08 11:49:43 -0700183 { // acquire lock
184 AutoMutex _l(mLock);
185
186 resetKeyRepeatLocked();
Jeff Brownd8816c32010-09-16 14:07:33 -0700187 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700188 drainInboundQueueLocked();
189 }
Jeff Browne839a582010-04-22 18:58:52 -0700190
191 while (mConnectionsByReceiveFd.size() != 0) {
192 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
193 }
Jeff Browne839a582010-04-22 18:58:52 -0700194}
195
196void InputDispatcher::dispatchOnce() {
Jeff Brown54bc2812010-06-15 01:31:58 -0700197 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brown61ce3982010-09-07 10:44:57 -0700198 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Browne839a582010-04-22 18:58:52 -0700199
Jeff Browne839a582010-04-22 18:58:52 -0700200 nsecs_t nextWakeupTime = LONG_LONG_MAX;
201 { // acquire lock
202 AutoMutex _l(mLock);
Jeff Browna665ca82010-09-08 11:49:43 -0700203 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Browne839a582010-04-22 18:58:52 -0700204
Jeff Browna665ca82010-09-08 11:49:43 -0700205 if (runCommandsLockedInterruptible()) {
206 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Browne839a582010-04-22 18:58:52 -0700207 }
Jeff Browne839a582010-04-22 18:58:52 -0700208 } // release lock
209
Jeff Browna665ca82010-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 Brown59abe7e2010-09-13 23:17:30 -0700221 mLooper->pollOnce(timeoutMillis);
Jeff Browna665ca82010-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 Brownd8816c32010-09-16 14:07:33 -0700239 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700240 drainInboundQueueLocked();
241 }
Jeff Brown54bc2812010-06-15 01:31:58 -0700242 return;
243 }
244
Jeff Browna665ca82010-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 Browna665ca82010-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 Brownd8816c32010-09-16 14:07:33 -0700346 bool done = false;
Jeff Browna665ca82010-09-08 11:49:43 -0700347 switch (mPendingEvent->type) {
348 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
349 ConfigurationChangedEntry* typedEntry =
350 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brownd8816c32010-09-16 14:07:33 -0700351 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Browna665ca82010-09-08 11:49:43 -0700352 break;
353 }
354
355 case EventEntry::TYPE_KEY: {
356 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brownd8816c32010-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 Browna665ca82010-09-08 11:49:43 -0700365 resetPendingAppSwitchLocked(true);
Jeff Browna665ca82010-09-08 11:49:43 -0700366 }
367 }
Jeff Browna665ca82010-09-08 11:49:43 -0700368 break;
369 }
370
371 case EventEntry::TYPE_MOTION: {
372 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brownd8816c32010-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 Browna665ca82010-09-08 11:49:43 -0700379 }
Jeff Browna665ca82010-09-08 11:49:43 -0700380 break;
381 }
382
383 default:
384 assert(false);
Jeff Browna665ca82010-09-08 11:49:43 -0700385 break;
386 }
387
Jeff Brownd8816c32010-09-16 14:07:33 -0700388 if (done) {
389 releasePendingEventLocked();
Jeff Browna665ca82010-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 Browne839a582010-04-22 18:58:52 -0700439}
440
Jeff Brown54bc2812010-06-15 01:31:58 -0700441bool InputDispatcher::runCommandsLockedInterruptible() {
442 if (mCommandQueue.isEmpty()) {
443 return false;
444 }
Jeff Browne839a582010-04-22 18:58:52 -0700445
Jeff Brown54bc2812010-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 Brown51d45a72010-06-17 20:52:56 -0700452 commandEntry->connection.clear();
Jeff Brown54bc2812010-06-15 01:31:58 -0700453 mAllocator.releaseCommandEntry(commandEntry);
454 } while (! mCommandQueue.isEmpty());
455 return true;
Jeff Browne839a582010-04-22 18:58:52 -0700456}
457
Jeff Brown54bc2812010-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 Browna665ca82010-09-08 11:49:43 -0700464void InputDispatcher::drainInboundQueueLocked() {
465 while (! mInboundQueue.isEmpty()) {
466 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brownd8816c32010-09-16 14:07:33 -0700467 releaseInboundEventLocked(entry);
Jeff Browne839a582010-04-22 18:58:52 -0700468 }
Jeff Browne839a582010-04-22 18:58:52 -0700469}
470
Jeff Brownd8816c32010-09-16 14:07:33 -0700471void InputDispatcher::releasePendingEventLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700472 if (mPendingEvent) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700473 releaseInboundEventLocked(mPendingEvent);
Jeff Browna665ca82010-09-08 11:49:43 -0700474 mPendingEvent = NULL;
475 }
476}
477
Jeff Brownd8816c32010-09-16 14:07:33 -0700478void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700479 InjectionState* injectionState = entry->injectionState;
480 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Browna665ca82010-09-08 11:49:43 -0700481#if DEBUG_DISPATCH_CYCLE
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700482 LOGD("Injected inbound event was dropped.");
Jeff Browna665ca82010-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 Brownd1b0a2b2010-09-26 22:20:12 -0700490 InjectionState* injectionState = entry->injectionState;
491 return ! injectionState
492 || injectionState->injectorUid == 0
Jeff Browna665ca82010-09-08 11:49:43 -0700493 || mPolicy->checkInjectEventsPermissionNonReentrant(
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700494 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-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 Brown61ce3982010-09-07 10:44:57 -0700505 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown50de30a2010-06-22 01:27:15 -0700506 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
507
Jeff Brown50de30a2010-06-22 01:27:15 -0700508 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown51d45a72010-06-17 20:52:56 -0700509 uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK;
Jeff Browne839a582010-04-22 18:58:52 -0700510 if (entry->refCount == 1) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700511 mAllocator.recycleKeyEntry(entry);
Jeff Brown51d45a72010-06-17 20:52:56 -0700512 entry->eventTime = currentTime;
Jeff Brown51d45a72010-06-17 20:52:56 -0700513 entry->policyFlags = policyFlags;
Jeff Browne839a582010-04-22 18:58:52 -0700514 entry->repeatCount += 1;
515 } else {
Jeff Brown51d45a72010-06-17 20:52:56 -0700516 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700517 entry->deviceId, entry->source, policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700518 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brownf16c26d2010-07-02 15:37:36 -0700519 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Browne839a582010-04-22 18:58:52 -0700520
521 mKeyRepeatState.lastKeyEntry = newEntry;
522 mAllocator.releaseKeyEntry(entry);
523
524 entry = newEntry;
525 }
Jeff Browna665ca82010-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 Browne839a582010-04-22 18:58:52 -0700531
Jeff Brownf16c26d2010-07-02 15:37:36 -0700532 if (entry->repeatCount == 1) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700533 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brownf16c26d2010-07-02 15:37:36 -0700534 }
535
Jeff Brown61ce3982010-09-07 10:44:57 -0700536 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Browna665ca82010-09-08 11:49:43 -0700537 return entry;
Jeff Browne839a582010-04-22 18:58:52 -0700538}
539
Jeff Browna665ca82010-09-08 11:49:43 -0700540bool InputDispatcher::dispatchConfigurationChangedLocked(
541 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Browne839a582010-04-22 18:58:52 -0700542#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Browna665ca82010-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 Brownd8816c32010-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 Brownd1b0a2b2010-09-26 22:20:12 -0700563 trusted = checkInjectionPermission(mFocusedWindow, entry->injectionState);
Jeff Brownd8816c32010-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 Browna665ca82010-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 Brownd8816c32010-09-16 14:07:33 -0700620 resetTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700621 }
622
623 // Identify targets.
624 if (! mCurrentInputTargetsValid) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700625 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
626 entry, nextWakeupTime);
Jeff Browna665ca82010-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 Brownd1b0a2b2010-09-26 22:20:12 -0700637 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700638 }
639
640 // Dispatch the key.
641 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
642
643 // Poke user activity.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700644 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
645 pokeUserActivityLocked(entry->eventTime, POWER_MANAGER_BUTTON_EVENT);
646 }
Jeff Browna665ca82010-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 Brownd8816c32010-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 Browna665ca82010-09-08 11:49:43 -0700671 // Preprocessing.
672 if (! entry->dispatchInProgress) {
673 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
674
675 entry->dispatchInProgress = true;
Jeff Brownd8816c32010-09-16 14:07:33 -0700676 resetTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700677 }
678
679 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
680
681 // Identify targets.
682 if (! mCurrentInputTargetsValid) {
Jeff Browna665ca82010-09-08 11:49:43 -0700683 int32_t injectionResult;
684 if (isPointerEvent) {
685 // Pointer event. (eg. touchscreen)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700686 injectionResult = findTouchedWindowTargetsLocked(currentTime,
687 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700688 } else {
689 // Non touch event. (eg. trackball)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700690 injectionResult = findFocusedWindowTargetsLocked(currentTime,
691 entry, nextWakeupTime);
Jeff Browna665ca82010-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 Brownd1b0a2b2010-09-26 22:20:12 -0700703 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700704 }
705
706 // Dispatch the motion.
707 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
708
709 // Poke user activity.
Jeff Brownd1b0a2b2010-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 Browna665ca82010-09-08 11:49:43 -0700715 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brownd1b0a2b2010-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 Browna665ca82010-09-08 11:49:43 -0700727 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700728 } else {
729 eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Browna665ca82010-09-08 11:49:43 -0700730 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700731 pokeUserActivityLocked(entry->eventTime, eventType);
Jeff Browna665ca82010-09-08 11:49:43 -0700732 }
Jeff Browna665ca82010-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 Brownaf30ff62010-09-01 17:01:00 -0700740 "action=0x%x, flags=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700741 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700742 prefix,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700743 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
744 entry->action, entry->flags,
Jeff Browne839a582010-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 Browna665ca82010-09-08 11:49:43 -0700750 const MotionSample* sample = & entry->firstSample;
Jeff Browne839a582010-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 Brown38a7fab2010-08-30 03:02:23 -0700755 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700756 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -0700757 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -0700758 i, entry->pointerIds[i],
Jeff Brown38a7fab2010-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 Browne839a582010-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 Brown5c1ed842010-07-14 18:48:53 -0700768 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -0700769 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
770 }
771#endif
Jeff Browne839a582010-04-22 18:58:52 -0700772}
773
774void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
775 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
776#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700777 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700778 "resumeWithAppendedMotionSample=%s",
Jeff Browna665ca82010-09-08 11:49:43 -0700779 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -0700780#endif
781
Jeff Brown54bc2812010-06-15 01:31:58 -0700782 assert(eventEntry->dispatchInProgress); // should already have been set to true
783
Jeff Browne839a582010-04-22 18:58:52 -0700784 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
785 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
786
Jeff Brown53a415e2010-09-15 15:18:56 -0700787 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -0700788 if (connectionIndex >= 0) {
789 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown51d45a72010-06-17 20:52:56 -0700790 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Browne839a582010-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 Brownd8816c32010-09-16 14:07:33 -0700800void InputDispatcher::resetTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700801 mCurrentInputTargetsValid = false;
802 mCurrentInputTargets.clear();
Jeff Browna665ca82010-09-08 11:49:43 -0700803 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
804}
805
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700806void InputDispatcher::commitTargetsLocked() {
Jeff Browna665ca82010-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 Brown53a415e2010-09-15 15:18:56 -0700826 LOGD("Waiting for application to become ready for input: %s",
827 getApplicationWindowLabelLocked(application, window).string());
Jeff Browna665ca82010-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 Brown53a415e2010-09-15 15:18:56 -0700844 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Browna665ca82010-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 Brown53a415e2010-09-15 15:18:56 -0700859void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
860 const sp<InputChannel>& inputChannel) {
Jeff Browna665ca82010-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 Brown53a415e2010-09-15 15:18:56 -0700867
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700868 // Release the touch targets.
869 mTouchState.reset();
Jeff Brown405a1d32010-09-16 12:31:46 -0700870
Jeff Brown53a415e2010-09-15 15:18:56 -0700871 // Input state will not be realistic. Mark it out of sync.
Jeff Brown40ad4702010-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 Brown53a415e2010-09-15 15:18:56 -0700878 }
Jeff Browna665ca82010-09-08 11:49:43 -0700879 }
880}
881
Jeff Brown53a415e2010-09-15 15:18:56 -0700882nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Browna665ca82010-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 Browna665ca82010-09-08 11:49:43 -0700895 // Reset input target wait timeout.
896 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
897}
898
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700899int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
900 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-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 Brown53a415e2010-09-15 15:18:56 -0700911 "focused application that may eventually add a window: %s.",
912 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-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 Brownd1b0a2b2010-09-26 22:20:12 -0700925 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Browna665ca82010-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 Brown53a415e2010-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 Browna665ca82010-09-08 11:49:43 -0700950 // Success! Output targets.
951 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700952 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -0700953
954 // Done.
955Failed:
956Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -0700957 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
958 updateDispatchStatisticsLocked(currentTime, entry,
959 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -0700960#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700961 LOGD("findFocusedWindow finished: injectionResult=%d, "
962 "timeSpendWaitingForApplication=%0.1fms",
963 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -0700964#endif
965 return injectionResult;
966}
967
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700968int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
969 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -0700970 enum InjectionPermission {
971 INJECTION_PERMISSION_UNKNOWN,
972 INJECTION_PERMISSION_GRANTED,
973 INJECTION_PERMISSION_DENIED
974 };
975
Jeff Browna665ca82010-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 Brownd1b0a2b2010-09-26 22:20:12 -07001007 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Browna665ca82010-09-08 11:49:43 -07001008
1009 // Update the touch state as needed based on the properties of the touch event.
Jeff Brownd1b0a2b2010-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 Browna665ca82010-09-08 11:49:43 -07001018
Jeff Brownd1b0a2b2010-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 Browna665ca82010-09-08 11:49:43 -07001023
Jeff Brownd1b0a2b2010-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 Browna665ca82010-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 Brownd1b0a2b2010-09-26 22:20:12 -07001033 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Browna665ca82010-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 Browna665ca82010-09-08 11:49:43 -07001049 }
1050 break; // found touched window, exit window loop
1051 }
1052 }
1053
Jeff Brownd1b0a2b2010-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 Browna665ca82010-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 Brownd1b0a2b2010-09-26 22:20:12 -07001075 // Figure out whether splitting will be allowed for this window.
Jeff Brown1c322582010-09-28 13:24:41 -07001076 if (newTouchedWindow
1077 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brownd1b0a2b2010-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 Browna665ca82010-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 Brown53a415e2010-09-15 15:18:56 -07001096 "focused application that may eventually add a new window: %s.",
1097 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -07001098#endif
1099 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1100 mFocusedApplication, NULL, nextWakeupTime);
Jeff Browna665ca82010-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 Browna665ca82010-09-08 11:49:43 -07001106 goto Failed;
1107 }
1108
Jeff Brownd1b0a2b2010-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 Browna665ca82010-09-08 11:49:43 -07001114 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001115 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001116 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001117 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001118
1119 // If the pointer is not currently down, then ignore the event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001120 if (! mTempTouchState.down) {
Jeff Browna665ca82010-09-08 11:49:43 -07001121 LOGI("Dropping event because the pointer is not down.");
1122 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001123 goto Failed;
1124 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001125 }
Jeff Browna665ca82010-09-08 11:49:43 -07001126
Jeff Brownd1b0a2b2010-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 Browna665ca82010-09-08 11:49:43 -07001143#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001144 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Browna665ca82010-09-08 11:49:43 -07001145#endif
1146 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001147 goto Failed;
1148 }
1149
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001150 // Permission granted to injection into all touched foreground windows.
1151 injectionPermission = INJECTION_PERMISSION_GRANTED;
1152 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001153
Jeff Brownd1b0a2b2010-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 Brown53a415e2010-09-15 15:18:56 -07001162#endif
Jeff Brownd1b0a2b2010-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 Brown53a415e2010-09-15 15:18:56 -07001203 }
Jeff Browna665ca82010-09-08 11:49:43 -07001204 }
1205
1206 // Success! Output targets.
1207 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Browna665ca82010-09-08 11:49:43 -07001208
Jeff Brownd1b0a2b2010-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 Browna665ca82010-09-08 11:49:43 -07001213 }
1214
Jeff Brownd1b0a2b2010-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 Browna665ca82010-09-08 11:49:43 -07001218Failed:
1219 // Check injection permission once and for all.
1220 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001221 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Browna665ca82010-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 Brownd1b0a2b2010-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 Browna665ca82010-09-08 11:49:43 -07001237 LOGW("Pointer down received while already down.");
Jeff Browna665ca82010-09-08 11:49:43 -07001238 }
Jeff Brownd1b0a2b2010-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 Browna665ca82010-09-08 11:49:43 -07001244
Jeff Brownd1b0a2b2010-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 Browna665ca82010-09-08 11:49:43 -07001256 }
Jeff Browna665ca82010-09-08 11:49:43 -07001257 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001258
1259 // Save changes to touch state.
1260 mTouchState.copyFrom(mTempTouchState);
Jeff Browna665ca82010-09-08 11:49:43 -07001261 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001262#if DEBUG_FOCUS
1263 LOGD("Not updating touch focus because injection was denied.");
1264#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001265 }
1266
1267Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -07001268 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1269 updateDispatchStatisticsLocked(currentTime, entry,
1270 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001271#if DEBUG_FOCUS
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001272 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1273 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown53a415e2010-09-15 15:18:56 -07001274 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001275#endif
1276 return injectionResult;
1277}
1278
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001279void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1280 BitSet32 pointerIds) {
Jeff Browna665ca82010-09-08 11:49:43 -07001281 mCurrentInputTargets.push();
1282
1283 InputTarget& target = mCurrentInputTargets.editTop();
1284 target.inputChannel = window->inputChannel;
1285 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001286 target.xOffset = - window->frameLeft;
1287 target.yOffset = - window->frameTop;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001288 target.windowType = window->layoutParamsType;
1289 target.pointerIds = pointerIds;
Jeff Browna665ca82010-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 Browna665ca82010-09-08 11:49:43 -07001299 target.xOffset = 0;
1300 target.yOffset = 0;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001301 target.windowType = InputWindow::TYPE_SYSTEM_OVERLAY;
Jeff Browna665ca82010-09-08 11:49:43 -07001302 }
1303}
1304
1305bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brownd1b0a2b2010-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 Browna665ca82010-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 Brownd1b0a2b2010-09-26 22:20:12 -07001316 injectionState->injectorPid, injectionState->injectorUid,
1317 window->inputChannel->getName().string(),
Jeff Browna665ca82010-09-08 11:49:43 -07001318 window->ownerUid);
1319 } else {
1320 LOGW("Permission denied: injecting event from pid %d uid %d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001321 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-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 Brown53a415e2010-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 Brownd1b0a2b2010-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 Browna665ca82010-09-08 11:49:43 -07001381 CommandEntry* commandEntry = postCommandLocked(
1382 & InputDispatcher::doPokeUserActivityLockedInterruptible);
1383 commandEntry->eventTime = eventTime;
Jeff Browna665ca82010-09-08 11:49:43 -07001384 commandEntry->userActivityEventType = eventType;
1385}
1386
Jeff Brown51d45a72010-06-17 20:52:56 -07001387void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1388 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -07001389 bool resumeWithAppendedMotionSample) {
1390#if DEBUG_DISPATCH_CYCLE
Jeff Brown53a415e2010-09-15 15:18:56 -07001391 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001392 "xOffset=%f, yOffset=%f, "
1393 "windowType=%d, pointerIds=0x%x, "
1394 "resumeWithAppendedMotionSample=%s",
Jeff Brown53a415e2010-09-15 15:18:56 -07001395 connection->getInputChannelName(), inputTarget->flags,
Jeff Browne839a582010-04-22 18:58:52 -07001396 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001397 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Browna665ca82010-09-08 11:49:43 -07001398 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -07001399#endif
1400
Jeff Brownd1b0a2b2010-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 Browne839a582010-04-22 18:58:52 -07001405 // Skip this event if the connection status is not normal.
Jeff Brown53a415e2010-09-15 15:18:56 -07001406 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Browne839a582010-04-22 18:58:52 -07001407 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Browna665ca82010-09-08 11:49:43 -07001408 LOGW("channel '%s' ~ Dropping event because the channel status is %s",
1409 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Browne839a582010-04-22 18:58:52 -07001410 return;
1411 }
1412
Jeff Brownd1b0a2b2010-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 Browne839a582010-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 Brownd1b0a2b2010-09-26 22:20:12 -07001471 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1472 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Browne839a582010-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 Brown50de30a2010-06-22 01:27:15 -07001491 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-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 Browna665ca82010-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 Brown53a415e2010-09-15 15:18:56 -07001534 0, inputTarget->xOffset, inputTarget->yOffset); // increments ref
Jeff Browna665ca82010-09-08 11:49:43 -07001535 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1536
1537 mAllocator.releaseEventEntry(cancelationEventEntry);
1538 }
1539 }
1540 }
1541
Jeff Browne839a582010-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 Browna665ca82010-09-08 11:49:43 -07001544 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown53a415e2010-09-15 15:18:56 -07001545 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1546 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001547 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001548 }
1549
Jeff Browne839a582010-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 Brown51d45a72010-06-17 20:52:56 -07001569 activateConnectionLocked(connection.get());
Jeff Brown53a415e2010-09-15 15:18:56 -07001570 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001571 }
1572}
1573
Jeff Brown51d45a72010-06-17 20:52:56 -07001574void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown53a415e2010-09-15 15:18:56 -07001575 const sp<Connection>& connection) {
Jeff Browne839a582010-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 Browna665ca82010-09-08 11:49:43 -07001584 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001585 assert(! dispatchEntry->inProgress);
1586
Jeff Browna665ca82010-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 Brownd1b0a2b2010-09-26 22:20:12 -07001591 EventEntry* eventEntry = dispatchEntry->eventEntry;
1592 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Browna665ca82010-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 Browne839a582010-04-22 18:58:52 -07001615
1616 // Publish the event.
1617 status_t status;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001618 switch (eventEntry->type) {
Jeff Browne839a582010-04-22 18:58:52 -07001619 case EventEntry::TYPE_KEY: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001620 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001621
1622 // Apply target flags.
1623 int32_t action = keyEntry->action;
1624 int32_t flags = keyEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001625
1626 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001627 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-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 Brownd1b0a2b2010-09-26 22:20:12 -07001642 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001643
1644 // Apply target flags.
1645 int32_t action = motionEntry->action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07001646 int32_t flags = motionEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001647 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001648 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -07001649 }
Jeff Brownaf30ff62010-09-01 17:01:00 -07001650 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1651 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1652 }
Jeff Browne839a582010-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 Brownf26db0d2010-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 Browne839a582010-04-22 18:58:52 -07001673 // Publish the motion event and the first motion sample.
1674 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001675 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -07001676 xOffset, yOffset,
Jeff Browne839a582010-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 Brownd1b0a2b2010-09-26 22:20:12 -07001732 connection->lastEventTime = eventEntry->eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07001733 connection->lastDispatchTime = currentTime;
1734
Jeff Browne839a582010-04-22 18:58:52 -07001735 // Notify other system components.
1736 onDispatchCycleStartedLocked(currentTime, connection);
1737}
1738
Jeff Brown51d45a72010-06-17 20:52:56 -07001739void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1740 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001741#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001742 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-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 Brown54bc2812010-06-15 01:31:58 -07001749 if (connection->status == Connection::STATUS_BROKEN
1750 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001751 return;
1752 }
1753
Jeff Brown53a415e2010-09-15 15:18:56 -07001754 // Notify other system components.
1755 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Browne839a582010-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 Browna665ca82010-09-08 11:49:43 -07001768 startNextDispatchCycleLocked(currentTime, connection);
1769}
1770
1771void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1772 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001773 // Start the next dispatch cycle for this connection.
1774 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001775 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-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 Brown53a415e2010-09-15 15:18:56 -07001784 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001785 return;
1786 }
1787 // Finished.
1788 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001789 if (dispatchEntry->hasForegroundTarget()) {
1790 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001791 }
Jeff Browne839a582010-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 Brown53a415e2010-09-15 15:18:56 -07001795 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001796 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001797 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001798 return;
1799 }
1800 }
1801
1802 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001803 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001804}
1805
Jeff Brown51d45a72010-06-17 20:52:56 -07001806void InputDispatcher::abortDispatchCycleLocked(nsecs_t currentTime,
1807 const sp<Connection>& connection, bool broken) {
Jeff Browne839a582010-04-22 18:58:52 -07001808#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001809 LOGD("channel '%s' ~ abortDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001810 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001811#endif
1812
Jeff Browna665ca82010-09-08 11:49:43 -07001813 // Input state will no longer be realistic.
1814 connection->inputState.setOutOfSync();
Jeff Browne839a582010-04-22 18:58:52 -07001815
Jeff Browna665ca82010-09-08 11:49:43 -07001816 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001817 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001818
1819 // Handle the case where the connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001820 // Ignore already broken or zombie connections.
Jeff Browne839a582010-04-22 18:58:52 -07001821 if (broken) {
Jeff Brown53a415e2010-09-15 15:18:56 -07001822 if (connection->status == Connection::STATUS_NORMAL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001823 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001824
Jeff Brown54bc2812010-06-15 01:31:58 -07001825 // Notify other system components.
1826 onDispatchCycleBrokenLocked(currentTime, connection);
1827 }
Jeff Browne839a582010-04-22 18:58:52 -07001828 }
Jeff Browne839a582010-04-22 18:58:52 -07001829}
1830
Jeff Brown53a415e2010-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 Browna665ca82010-09-08 11:49:43 -07001836 }
1837 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001838 }
1839
Jeff Brown53a415e2010-09-15 15:18:56 -07001840 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001841}
1842
Jeff Brown59abe7e2010-09-13 23:17:30 -07001843int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-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 Brown59abe7e2010-09-13 23:17:30 -07001853 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001854 }
1855
Jeff Brown51d45a72010-06-17 20:52:56 -07001856 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001857
1858 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001859 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-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 Brown51d45a72010-06-17 20:52:56 -07001862 d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -07001863 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001864 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001865 }
1866
Jeff Brown59abe7e2010-09-13 23:17:30 -07001867 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001868 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1869 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001870 return 1;
Jeff Browne839a582010-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 Brown51d45a72010-06-17 20:52:56 -07001877 d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -07001878 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001879 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001880 }
1881
Jeff Brown51d45a72010-06-17 20:52:56 -07001882 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001883 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001884 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001885 } // release lock
1886}
1887
Jeff Brownd1b0a2b2010-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 Brownffb16d62010-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 Brownd1b0a2b2010-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 Brown54bc2812010-06-15 01:31:58 -07001968void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07001969#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -07001970 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07001971#endif
1972
Jeff Browna665ca82010-09-08 11:49:43 -07001973 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07001974 { // acquire lock
1975 AutoMutex _l(mLock);
1976
Jeff Brown51d45a72010-06-17 20:52:56 -07001977 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browna665ca82010-09-08 11:49:43 -07001978 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001979 } // release lock
1980
Jeff Browna665ca82010-09-08 11:49:43 -07001981 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07001982 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07001983 }
1984}
1985
Jeff Brown5c1ed842010-07-14 18:48:53 -07001986void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-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 Brown5c1ed842010-07-14 18:48:53 -07001990 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07001991 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07001992 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -07001993 keyCode, scanCode, metaState, downTime);
1994#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001995 if (! validateKeyEvent(action)) {
1996 return;
1997 }
Jeff Browne839a582010-04-22 18:58:52 -07001998
Jeff Browna665ca82010-09-08 11:49:43 -07001999 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002000 { // acquire lock
2001 AutoMutex _l(mLock);
2002
Jeff Brown51d45a72010-06-17 20:52:56 -07002003 int32_t repeatCount = 0;
2004 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002005 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07002006 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07002007
Jeff Browna665ca82010-09-08 11:49:43 -07002008 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002009 } // release lock
2010
Jeff Browna665ca82010-09-08 11:49:43 -07002011 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002012 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002013 }
2014}
2015
Jeff Brown5c1ed842010-07-14 18:48:53 -07002016void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002017 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-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 Brown5c1ed842010-07-14 18:48:53 -07002021 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-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 Browne839a582010-04-22 18:58:52 -07002025 xPrecision, yPrecision, downTime);
2026 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07002027 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002028 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07002029 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07002030 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-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 Browne839a582010-04-22 18:58:52 -07002035 }
2036#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002037 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2038 return;
2039 }
Jeff Browne839a582010-04-22 18:58:52 -07002040
Jeff Browna665ca82010-09-08 11:49:43 -07002041 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002042 { // acquire lock
2043 AutoMutex _l(mLock);
2044
2045 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07002046 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-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 Browna665ca82010-09-08 11:49:43 -07002052 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2053 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-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 Brown5c1ed842010-07-14 18:48:53 -07002065 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07002066 || motionEntry->pointerCount != pointerCount
2067 || motionEntry->isInjected()) {
Jeff Browne839a582010-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 Brown54bc2812010-06-15 01:31:58 -07002074 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07002075 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-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 Brown54bc2812010-06-15 01:31:58 -07002080 return; // done!
Jeff Browne839a582010-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 Brown53a415e2010-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 Brown54bc2812010-06-15 01:31:58 -07002091 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-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 Browne839a582010-04-22 18:58:52 -07002098 }
Jeff Brown53a415e2010-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 Brownd1b0a2b2010-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 Brown53a415e2010-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 Browne839a582010-04-22 18:58:52 -07002145 }
2146 }
2147
2148NoBatchingOrStreaming:;
2149 }
2150
2151 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07002152 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002153 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002154 xPrecision, yPrecision, downTime,
2155 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002156
Jeff Browna665ca82010-09-08 11:49:43 -07002157 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002158 } // release lock
2159
Jeff Browna665ca82010-09-08 11:49:43 -07002160 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002161 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002162 }
2163}
2164
Jeff Brown51d45a72010-06-17 20:52:56 -07002165int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07002166 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002167#if DEBUG_INBOUND_EVENT_DETAILS
2168 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002169 "syncMode=%d, timeoutMillis=%d",
2170 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07002171#endif
2172
2173 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2174
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002175 InjectionState* injectionState;
Jeff Browna665ca82010-09-08 11:49:43 -07002176 bool needWake;
Jeff Brown51d45a72010-06-17 20:52:56 -07002177 { // acquire lock
2178 AutoMutex _l(mLock);
2179
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002180 EventEntry* injectedEntry = createEntryFromInjectedInputEventLocked(event);
Jeff Browna665ca82010-09-08 11:49:43 -07002181 if (! injectedEntry) {
2182 return INPUT_EVENT_INJECTION_FAILED;
2183 }
2184
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002185 injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002186 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002187 injectionState->injectionIsAsync = true;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002188 }
2189
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002190 injectionState->refCount += 1;
2191 injectedEntry->injectionState = injectionState;
2192
Jeff Browna665ca82010-09-08 11:49:43 -07002193 needWake = enqueueInboundEventLocked(injectedEntry);
Jeff Brown51d45a72010-06-17 20:52:56 -07002194 } // release lock
2195
Jeff Browna665ca82010-09-08 11:49:43 -07002196 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002197 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07002198 }
2199
2200 int32_t injectionResult;
2201 { // acquire lock
2202 AutoMutex _l(mLock);
2203
Jeff Brownf67c53e2010-07-28 15:48:59 -07002204 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2205 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2206 } else {
2207 for (;;) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002208 injectionResult = injectionState->injectionResult;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002209 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2210 break;
2211 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002212
Jeff Brown51d45a72010-06-17 20:52:56 -07002213 nsecs_t remainingTimeout = endTime - now();
2214 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-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 Brown51d45a72010-06-17 20:52:56 -07002219 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2220 break;
2221 }
2222
Jeff Brownf67c53e2010-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 Brownd1b0a2b2010-09-26 22:20:12 -07002228 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002229#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002230 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002231 injectionState->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002232#endif
2233 nsecs_t remainingTimeout = endTime - now();
2234 if (remainingTimeout <= 0) {
2235#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002236 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-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 Brown51d45a72010-06-17 20:52:56 -07002245 }
2246 }
2247
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002248 mAllocator.releaseInjectionState(injectionState);
Jeff Brown51d45a72010-06-17 20:52:56 -07002249 } // release lock
2250
Jeff Brownf67c53e2010-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 Brown51d45a72010-06-17 20:52:56 -07002257 return injectionResult;
2258}
2259
2260void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002261 InjectionState* injectionState = entry->injectionState;
2262 if (injectionState) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002263#if DEBUG_INJECTION
2264 LOGD("Setting input event injection result to %d. "
2265 "injectorPid=%d, injectorUid=%d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002266 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002267#endif
2268
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002269 if (injectionState->injectionIsAsync) {
Jeff Brownf67c53e2010-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 Brownd1b0a2b2010-09-26 22:20:12 -07002287 injectionState->injectionResult = injectionResult;
Jeff Brown51d45a72010-06-17 20:52:56 -07002288 mInjectionResultAvailableCondition.broadcast();
2289 }
2290}
2291
Jeff Brownd1b0a2b2010-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 Brown53a415e2010-09-15 15:18:56 -07002299void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002300 InjectionState* injectionState = entry->injectionState;
2301 if (injectionState) {
2302 injectionState->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002303
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002304 if (injectionState->pendingForegroundDispatches == 0) {
2305 mInjectionSyncFinishedCondition.broadcast();
2306 }
Jeff Browna665ca82010-09-08 11:49:43 -07002307 }
2308}
2309
2310InputDispatcher::EventEntry* InputDispatcher::createEntryFromInjectedInputEventLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002311 const InputEvent* event) {
2312 switch (event->getType()) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07002313 case AINPUT_EVENT_TYPE_KEY: {
Jeff Brown51d45a72010-06-17 20:52:56 -07002314 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002315 if (! validateKeyEvent(keyEvent->getAction())) {
Jeff Browna665ca82010-09-08 11:49:43 -07002316 return NULL;
2317 }
2318
Jeff Brownaf30ff62010-09-01 17:01:00 -07002319 uint32_t policyFlags = POLICY_FLAG_INJECTED;
Jeff Brown51d45a72010-06-17 20:52:56 -07002320
2321 KeyEntry* keyEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
Jeff Brown5c1ed842010-07-14 18:48:53 -07002322 keyEvent->getDeviceId(), keyEvent->getSource(), policyFlags,
Jeff Brown51d45a72010-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 Brown5c1ed842010-07-14 18:48:53 -07002329 case AINPUT_EVENT_TYPE_MOTION: {
Jeff Brown51d45a72010-06-17 20:52:56 -07002330 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002331 if (! validateMotionEvent(motionEvent->getAction(),
2332 motionEvent->getPointerCount(), motionEvent->getPointerIds())) {
Jeff Browna665ca82010-09-08 11:49:43 -07002333 return NULL;
2334 }
Jeff Browna665ca82010-09-08 11:49:43 -07002335
Jeff Brownaf30ff62010-09-01 17:01:00 -07002336 uint32_t policyFlags = POLICY_FLAG_INJECTED;
Jeff Brown51d45a72010-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 Brown5c1ed842010-07-14 18:48:53 -07002343 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002344 motionEvent->getAction(), motionEvent->getFlags(),
2345 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
Jeff Brown51d45a72010-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 Brownd1b0a2b2010-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 Browna665ca82010-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 Brownd1b0a2b2010-09-26 22:20:12 -07002380 // Clear old window pointers.
Jeff Brown405a1d32010-09-16 12:31:46 -07002381 mFocusedWindow = NULL;
Jeff Browna665ca82010-09-08 11:49:43 -07002382 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002383
2384 // Loop over new windows and rebuild the necessary window pointers for
2385 // tracking focus and touch.
Jeff Browna665ca82010-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 Brownd1b0a2b2010-09-26 22:20:12 -07002390 const InputWindow* window = & mWindows.itemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07002391 if (window->hasFocus) {
2392 mFocusedWindow = window;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002393 break;
Jeff Browna665ca82010-09-08 11:49:43 -07002394 }
2395 }
Jeff Brownd1b0a2b2010-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 Browna665ca82010-09-08 11:49:43 -07002407
Jeff Browna665ca82010-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 Brown59abe7e2010-09-13 23:17:30 -07002414 mLooper->wake();
Jeff Browna665ca82010-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 Brown59abe7e2010-09-13 23:17:30 -07002437 mLooper->wake();
Jeff Browna665ca82010-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 Brown59abe7e2010-09-13 23:17:30 -07002475 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002476 }
2477}
2478
Jeff Browna665ca82010-09-08 11:49:43 -07002479void InputDispatcher::logDispatchStateLocked() {
2480 String8 dump;
2481 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-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 Browna665ca82010-09-08 11:49:43 -07002493}
2494
2495void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002496 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2497 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002498
2499 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002500 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002501 mFocusedApplication->name.string(),
2502 mFocusedApplication->dispatchingTimeout / 1000000.0);
2503 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002504 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002505 }
Jeff Brown2806e382010-10-01 17:46:21 -07002506 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002507 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-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 Browna665ca82010-09-08 11:49:43 -07002521 }
2522
Jeff Brown2806e382010-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 Browna665ca82010-09-08 11:49:43 -07002552 }
2553
Jeff Brown2806e382010-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 Brown53a415e2010-09-15 15:18:56 -07002563
Jeff Brown2806e382010-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 Browna665ca82010-09-08 11:49:43 -07002579 }
2580
2581 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002582 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002583 (mAppSwitchDueTime - now()) / 1000000.0);
2584 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002585 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002586 }
2587}
2588
2589status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002590#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002591 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2592 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002593#endif
2594
Jeff Browne839a582010-04-22 18:58:52 -07002595 { // acquire lock
2596 AutoMutex _l(mLock);
2597
Jeff Brown53a415e2010-09-15 15:18:56 -07002598 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-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 Brown0cacb872010-08-17 15:59:26 -07002612 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002613 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002614
Jeff Browna665ca82010-09-08 11:49:43 -07002615 if (monitor) {
2616 mMonitoringChannels.push(inputChannel);
2617 }
2618
Jeff Brown59abe7e2010-09-13 23:17:30 -07002619 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002620
Jeff Brown54bc2812010-06-15 01:31:58 -07002621 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002622 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002623 return OK;
2624}
2625
2626status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002627#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002628 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002629#endif
2630
Jeff Browne839a582010-04-22 18:58:52 -07002631 { // acquire lock
2632 AutoMutex _l(mLock);
2633
Jeff Brown53a415e2010-09-15 15:18:56 -07002634 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-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 Browna665ca82010-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 Brown59abe7e2010-09-13 23:17:30 -07002653 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002654
Jeff Brown51d45a72010-06-17 20:52:56 -07002655 nsecs_t currentTime = now();
2656 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -07002657
2658 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002659 } // release lock
2660
Jeff Browne839a582010-04-22 18:58:52 -07002661 // Wake the poll loop because removing the connection may have changed the current
2662 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002663 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002664 return OK;
2665}
2666
Jeff Brown53a415e2010-09-15 15:18:56 -07002667ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-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 Browne839a582010-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 Brown54bc2812010-06-15 01:31:58 -07002697void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002698 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002699}
2700
Jeff Brown54bc2812010-06-15 01:31:58 -07002701void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002702 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002703}
2704
Jeff Brown54bc2812010-06-15 01:31:58 -07002705void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002706 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002707 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2708 connection->getInputChannelName());
2709
Jeff Brown54bc2812010-06-15 01:31:58 -07002710 CommandEntry* commandEntry = postCommandLocked(
2711 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002712 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002713}
2714
Jeff Brown53a415e2010-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 Browna665ca82010-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 Brown54bc2812010-06-15 01:31:58 -07002743void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2744 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002745 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002746
Jeff Brown51d45a72010-06-17 20:52:56 -07002747 if (connection->status != Connection::STATUS_ZOMBIE) {
2748 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002749
Jeff Brown51d45a72010-06-17 20:52:56 -07002750 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2751
2752 mLock.lock();
2753 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002754}
2755
Jeff Brown53a415e2010-09-15 15:18:56 -07002756void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002757 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002758 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002759
Jeff Brown53a415e2010-09-15 15:18:56 -07002760 nsecs_t newTimeout = mPolicy->notifyANR(
2761 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002762
Jeff Brown53a415e2010-09-15 15:18:56 -07002763 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002764
Jeff Brown53a415e2010-09-15 15:18:56 -07002765 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002766}
2767
Jeff Browna665ca82010-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 Brownd1b0a2b2010-09-26 22:20:12 -07002791 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07002792
2793 mLock.lock();
2794}
2795
Jeff Brown53a415e2010-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 Browna665ca82010-09-08 11:49:43 -07002799}
2800
2801void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002802 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002803 dumpDispatchStateLocked(dump);
2804}
2805
Jeff Brown54bc2812010-06-15 01:31:58 -07002806
Jeff Brown53a415e2010-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 Browne839a582010-04-22 18:58:52 -07002819// --- InputDispatcher::Allocator ---
2820
2821InputDispatcher::Allocator::Allocator() {
2822}
2823
Jeff Brownd1b0a2b2010-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 Brown51d45a72010-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 Tated974e002010-06-23 16:50:30 -07002841 entry->eventTime = eventTime;
Jeff Brownd1b0a2b2010-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 Brown51d45a72010-06-17 20:52:56 -07002850}
2851
Jeff Browne839a582010-04-22 18:58:52 -07002852InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07002853InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002854 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown51d45a72010-06-17 20:52:56 -07002855 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07002856 return entry;
2857}
2858
Jeff Brown51d45a72010-06-17 20:52:56 -07002859InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002860 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-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 Browne839a582010-04-22 18:58:52 -07002863 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown51d45a72010-06-17 20:52:56 -07002864 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime);
2865
2866 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07002867 entry->source = source;
Jeff Brown51d45a72010-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 Browna665ca82010-09-08 11:49:43 -07002876 entry->syntheticRepeat = false;
2877 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07002878 return entry;
2879}
2880
Jeff Brown51d45a72010-06-17 20:52:56 -07002881InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002882 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-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 Browne839a582010-04-22 18:58:52 -07002886 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown51d45a72010-06-17 20:52:56 -07002887 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime);
2888
2889 entry->eventTime = eventTime;
2890 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07002891 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07002892 entry->policyFlags = policyFlags;
2893 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07002894 entry->flags = flags;
Jeff Brown51d45a72010-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 Browne839a582010-04-22 18:58:52 -07002902 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-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 Browne839a582010-04-22 18:58:52 -07002908 return entry;
2909}
2910
2911InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07002912 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07002913 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07002914 DispatchEntry* entry = mDispatchEntryPool.alloc();
2915 entry->eventEntry = eventEntry;
2916 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07002917 entry->targetFlags = targetFlags;
2918 entry->xOffset = xOffset;
2919 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07002920 entry->inProgress = false;
2921 entry->headMotionSample = NULL;
2922 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07002923 return entry;
2924}
2925
Jeff Brown54bc2812010-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 Brownd1b0a2b2010-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 Browne839a582010-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 Brownd1b0a2b2010-09-26 22:20:12 -07002962 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-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 Brownd1b0a2b2010-09-26 22:20:12 -07002972 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-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 Brownd1b0a2b2010-09-26 22:20:12 -07002982 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-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 Browne839a582010-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 Brown54bc2812010-06-15 01:31:58 -07002999void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3000 mCommandEntryPool.free(entry);
3001}
3002
Jeff Browne839a582010-04-22 18:58:52 -07003003void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003004 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003005 MotionSample* sample = mMotionSamplePool.alloc();
3006 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003007 uint32_t pointerCount = motionEntry->pointerCount;
3008 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-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 Brownd1b0a2b2010-09-26 22:20:12 -07003017void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3018 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003019
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003020 keyEntry->dispatchInProgress = false;
3021 keyEntry->syntheticRepeat = false;
3022 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003023}
3024
3025
Jeff Brown542412c2010-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 Browna665ca82010-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 Browne839a582010-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 Brown53a415e2010-09-15 15:18:56 -07003223 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003224}
3225
3226InputDispatcher::Connection::~Connection() {
3227}
3228
3229status_t InputDispatcher::Connection::initialize() {
3230 return inputPublisher.initialize();
3231}
3232
Jeff Brown54bc2812010-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 Brown54bc2812010-06-15 01:31:58 -07003241 case STATUS_ZOMBIE:
3242 return "ZOMBIE";
3243
3244 default:
3245 return "UNKNOWN";
3246 }
3247}
3248
Jeff Browne839a582010-04-22 18:58:52 -07003249InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3250 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003251 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3252 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003253 if (dispatchEntry->eventEntry == eventEntry) {
3254 return dispatchEntry;
3255 }
3256 }
3257 return NULL;
3258}
3259
Jeff Browna665ca82010-09-08 11:49:43 -07003260
Jeff Brown54bc2812010-06-15 01:31:58 -07003261// --- InputDispatcher::CommandEntry ---
3262
Jeff Browna665ca82010-09-08 11:49:43 -07003263InputDispatcher::CommandEntry::CommandEntry() :
3264 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003265}
3266
3267InputDispatcher::CommandEntry::~CommandEntry() {
3268}
3269
Jeff Browne839a582010-04-22 18:58:52 -07003270
Jeff Brownd1b0a2b2010-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 Browne839a582010-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