blob: 629234b2682cd187046d0da306ecc8f48d23ab80 [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
Jeff Brown90f0cee2010-10-08 22:31:17 -070098static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -070099 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:
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700104 case AMOTION_EVENT_ACTION_OUTSIDE:
105 return true;
Jeff Brown90f0cee2010-10-08 22:31:17 -0700106 case AMOTION_EVENT_ACTION_POINTER_DOWN:
107 case AMOTION_EVENT_ACTION_POINTER_UP: {
108 int32_t index = getMotionEventActionPointerIndex(action);
109 return index >= 0 && size_t(index) < pointerCount;
110 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700111 default:
112 return false;
113 }
114}
115
116static bool validateMotionEvent(int32_t action, size_t pointerCount,
117 const int32_t* pointerIds) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700118 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700119 LOGE("Motion event has invalid action code 0x%x", action);
120 return false;
121 }
122 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
123 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
124 pointerCount, MAX_POINTERS);
125 return false;
126 }
Jeff Brown3c3cc622010-10-20 15:33:38 -0700127 BitSet32 pointerIdBits;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700128 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brown3c3cc622010-10-20 15:33:38 -0700129 int32_t id = pointerIds[i];
130 if (id < 0 || id > MAX_POINTER_ID) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700131 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
Jeff Brown3c3cc622010-10-20 15:33:38 -0700132 id, MAX_POINTER_ID);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700133 return false;
134 }
Jeff Brown3c3cc622010-10-20 15:33:38 -0700135 if (pointerIdBits.hasBit(id)) {
136 LOGE("Motion event has duplicate pointer id %d", id);
137 return false;
138 }
139 pointerIdBits.markBit(id);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700140 }
141 return true;
142}
143
Jeff Browna665ca82010-09-08 11:49:43 -0700144
145// --- InputWindow ---
146
Jeff Browna665ca82010-09-08 11:49:43 -0700147bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
148 return x >= touchableAreaLeft && x <= touchableAreaRight
149 && y >= touchableAreaTop && y <= touchableAreaBottom;
150}
151
Jeff Brown35cf0e92010-10-05 12:26:23 -0700152bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
153 return x >= frameLeft && x <= frameRight
154 && y >= frameTop && y <= frameBottom;
155}
156
157bool InputWindow::isTrustedOverlay() const {
158 return layoutParamsType == TYPE_INPUT_METHOD
Jeff Browne68d9e02010-10-15 00:54:27 -0700159 || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
160 || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
Jeff Brown35cf0e92010-10-05 12:26:23 -0700161}
162
Jeff Browna665ca82010-09-08 11:49:43 -0700163
Jeff Browne839a582010-04-22 18:58:52 -0700164// --- InputDispatcher ---
165
Jeff Brown54bc2812010-06-15 01:31:58 -0700166InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Browna665ca82010-09-08 11:49:43 -0700167 mPolicy(policy),
168 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
169 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700170 mFocusedWindow(NULL),
Jeff Browna665ca82010-09-08 11:49:43 -0700171 mFocusedApplication(NULL),
172 mCurrentInputTargetsValid(false),
173 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown59abe7e2010-09-13 23:17:30 -0700174 mLooper = new Looper(false);
Jeff Browne839a582010-04-22 18:58:52 -0700175
Jeff Browna665ca82010-09-08 11:49:43 -0700176 mInboundQueue.headSentinel.refCount = -1;
177 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
178 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Browne839a582010-04-22 18:58:52 -0700179
Jeff Browna665ca82010-09-08 11:49:43 -0700180 mInboundQueue.tailSentinel.refCount = -1;
181 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
182 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Browne839a582010-04-22 18:58:52 -0700183
184 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown54bc2812010-06-15 01:31:58 -0700185
Jeff Brown542412c2010-08-18 15:51:08 -0700186 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
187 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
188 mThrottleState.lastDeviceId = -1;
189
190#if DEBUG_THROTTLING
191 mThrottleState.originalSampleCount = 0;
192 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
193#endif
Jeff Browne839a582010-04-22 18:58:52 -0700194}
195
196InputDispatcher::~InputDispatcher() {
Jeff Browna665ca82010-09-08 11:49:43 -0700197 { // acquire lock
198 AutoMutex _l(mLock);
199
200 resetKeyRepeatLocked();
Jeff Brownd8816c32010-09-16 14:07:33 -0700201 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700202 drainInboundQueueLocked();
203 }
Jeff Browne839a582010-04-22 18:58:52 -0700204
205 while (mConnectionsByReceiveFd.size() != 0) {
206 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
207 }
Jeff Browne839a582010-04-22 18:58:52 -0700208}
209
210void InputDispatcher::dispatchOnce() {
Jeff Brown54bc2812010-06-15 01:31:58 -0700211 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brown61ce3982010-09-07 10:44:57 -0700212 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Browne839a582010-04-22 18:58:52 -0700213
Jeff Browne839a582010-04-22 18:58:52 -0700214 nsecs_t nextWakeupTime = LONG_LONG_MAX;
215 { // acquire lock
216 AutoMutex _l(mLock);
Jeff Browna665ca82010-09-08 11:49:43 -0700217 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Browne839a582010-04-22 18:58:52 -0700218
Jeff Browna665ca82010-09-08 11:49:43 -0700219 if (runCommandsLockedInterruptible()) {
220 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Browne839a582010-04-22 18:58:52 -0700221 }
Jeff Browne839a582010-04-22 18:58:52 -0700222 } // release lock
223
Jeff Browna665ca82010-09-08 11:49:43 -0700224 // Wait for callback or timeout or wake. (make sure we round up, not down)
225 nsecs_t currentTime = now();
226 int32_t timeoutMillis;
227 if (nextWakeupTime > currentTime) {
228 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
229 timeout = (timeout + 999999LL) / 1000000LL;
230 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
231 } else {
232 timeoutMillis = 0;
233 }
234
Jeff Brown59abe7e2010-09-13 23:17:30 -0700235 mLooper->pollOnce(timeoutMillis);
Jeff Browna665ca82010-09-08 11:49:43 -0700236}
237
238void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
239 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
240 nsecs_t currentTime = now();
241
242 // Reset the key repeat timer whenever we disallow key events, even if the next event
243 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
244 // out of sleep.
245 if (keyRepeatTimeout < 0) {
246 resetKeyRepeatLocked();
247 }
248
Jeff Browna665ca82010-09-08 11:49:43 -0700249 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
250 if (mDispatchFrozen) {
251#if DEBUG_FOCUS
252 LOGD("Dispatch frozen. Waiting some more.");
253#endif
254 return;
255 }
256
257 // Optimize latency of app switches.
258 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
259 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
260 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
261 if (mAppSwitchDueTime < *nextWakeupTime) {
262 *nextWakeupTime = mAppSwitchDueTime;
263 }
264
Jeff Browna665ca82010-09-08 11:49:43 -0700265 // Ready to start a new event.
266 // If we don't already have a pending event, go grab one.
267 if (! mPendingEvent) {
268 if (mInboundQueue.isEmpty()) {
269 if (isAppSwitchDue) {
270 // The inbound queue is empty so the app switch key we were waiting
271 // for will never arrive. Stop waiting for it.
272 resetPendingAppSwitchLocked(false);
273 isAppSwitchDue = false;
274 }
275
276 // Synthesize a key repeat if appropriate.
277 if (mKeyRepeatState.lastKeyEntry) {
278 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
279 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
280 } else {
281 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
282 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
283 }
284 }
285 }
286 if (! mPendingEvent) {
287 return;
288 }
289 } else {
290 // Inbound queue has at least one entry.
291 EventEntry* entry = mInboundQueue.headSentinel.next;
292
293 // Throttle the entry if it is a move event and there are no
294 // other events behind it in the queue. Due to movement batching, additional
295 // samples may be appended to this event by the time the throttling timeout
296 // expires.
297 // TODO Make this smarter and consider throttling per device independently.
Jeff Brown90f0cee2010-10-08 22:31:17 -0700298 if (entry->type == EventEntry::TYPE_MOTION
299 && !isAppSwitchDue
300 && mDispatchEnabled
301 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
302 && !entry->isInjected()) {
Jeff Browna665ca82010-09-08 11:49:43 -0700303 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
304 int32_t deviceId = motionEntry->deviceId;
305 uint32_t source = motionEntry->source;
306 if (! isAppSwitchDue
307 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
308 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
309 && deviceId == mThrottleState.lastDeviceId
310 && source == mThrottleState.lastSource) {
311 nsecs_t nextTime = mThrottleState.lastEventTime
312 + mThrottleState.minTimeBetweenEvents;
313 if (currentTime < nextTime) {
314 // Throttle it!
315#if DEBUG_THROTTLING
316 LOGD("Throttling - Delaying motion event for "
317 "device 0x%x, source 0x%08x by up to %0.3fms.",
318 deviceId, source, (nextTime - currentTime) * 0.000001);
319#endif
320 if (nextTime < *nextWakeupTime) {
321 *nextWakeupTime = nextTime;
322 }
323 if (mThrottleState.originalSampleCount == 0) {
324 mThrottleState.originalSampleCount =
325 motionEntry->countSamples();
326 }
327 return;
328 }
329 }
330
331#if DEBUG_THROTTLING
332 if (mThrottleState.originalSampleCount != 0) {
333 uint32_t count = motionEntry->countSamples();
334 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
335 count - mThrottleState.originalSampleCount,
336 mThrottleState.originalSampleCount, count);
337 mThrottleState.originalSampleCount = 0;
338 }
339#endif
340
341 mThrottleState.lastEventTime = entry->eventTime < currentTime
342 ? entry->eventTime : currentTime;
343 mThrottleState.lastDeviceId = deviceId;
344 mThrottleState.lastSource = source;
345 }
346
347 mInboundQueue.dequeue(entry);
348 mPendingEvent = entry;
349 }
Jeff Brownef3a8232010-10-18 13:21:23 -0700350
351 // Poke user activity for this event.
352 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
353 pokeUserActivityLocked(mPendingEvent);
354 }
Jeff Browna665ca82010-09-08 11:49:43 -0700355 }
356
357 // Now we have an event to dispatch.
358 assert(mPendingEvent != NULL);
Jeff Brownd8816c32010-09-16 14:07:33 -0700359 bool done = false;
Jeff Brown90f0cee2010-10-08 22:31:17 -0700360 DropReason dropReason = DROP_REASON_NOT_DROPPED;
361 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
362 dropReason = DROP_REASON_POLICY;
363 } else if (!mDispatchEnabled) {
364 dropReason = DROP_REASON_DISABLED;
365 }
Jeff Browna665ca82010-09-08 11:49:43 -0700366 switch (mPendingEvent->type) {
367 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
368 ConfigurationChangedEntry* typedEntry =
369 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brownd8816c32010-09-16 14:07:33 -0700370 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700371 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Browna665ca82010-09-08 11:49:43 -0700372 break;
373 }
374
375 case EventEntry::TYPE_KEY: {
376 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700377 if (isAppSwitchDue) {
378 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700379 resetPendingAppSwitchLocked(true);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700380 isAppSwitchDue = false;
381 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
382 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700383 }
384 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700385 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Brown33d54ce2010-10-11 14:20:19 -0700386 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700387 break;
388 }
389
390 case EventEntry::TYPE_MOTION: {
391 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700392 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
393 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700394 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700395 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Brown33d54ce2010-10-11 14:20:19 -0700396 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700397 break;
398 }
399
400 default:
401 assert(false);
Jeff Browna665ca82010-09-08 11:49:43 -0700402 break;
403 }
404
Jeff Brownd8816c32010-09-16 14:07:33 -0700405 if (done) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700406 if (dropReason != DROP_REASON_NOT_DROPPED) {
407 dropInboundEventLocked(mPendingEvent, dropReason);
408 }
409
Jeff Brownd8816c32010-09-16 14:07:33 -0700410 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700411 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
412 }
413}
414
415bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
416 bool needWake = mInboundQueue.isEmpty();
417 mInboundQueue.enqueueAtTail(entry);
418
419 switch (entry->type) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700420 case EventEntry::TYPE_KEY: {
421 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
422 if (isAppSwitchKeyEventLocked(keyEntry)) {
423 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
424 mAppSwitchSawKeyDown = true;
425 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
426 if (mAppSwitchSawKeyDown) {
427#if DEBUG_APP_SWITCH
428 LOGD("App switch is pending!");
429#endif
430 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
431 mAppSwitchSawKeyDown = false;
432 needWake = true;
433 }
434 }
435 }
Jeff Browna665ca82010-09-08 11:49:43 -0700436 break;
437 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700438 }
Jeff Browna665ca82010-09-08 11:49:43 -0700439
440 return needWake;
441}
442
Jeff Brown90f0cee2010-10-08 22:31:17 -0700443void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
444 const char* reason;
445 switch (dropReason) {
446 case DROP_REASON_POLICY:
Jeff Brown33d54ce2010-10-11 14:20:19 -0700447#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Browna8ed8562010-10-11 23:32:49 -0700448 LOGD("Dropped event because policy consumed it.");
Jeff Brown33d54ce2010-10-11 14:20:19 -0700449#endif
Jeff Browna8ed8562010-10-11 23:32:49 -0700450 reason = "inbound event was dropped because the policy consumed it";
Jeff Brown90f0cee2010-10-08 22:31:17 -0700451 break;
452 case DROP_REASON_DISABLED:
453 LOGI("Dropped event because input dispatch is disabled.");
454 reason = "inbound event was dropped because input dispatch is disabled";
455 break;
456 case DROP_REASON_APP_SWITCH:
457 LOGI("Dropped event because of pending overdue app switch.");
458 reason = "inbound event was dropped because of pending overdue app switch";
459 break;
460 default:
461 assert(false);
462 return;
463 }
464
465 switch (entry->type) {
466 case EventEntry::TYPE_KEY:
467 synthesizeCancelationEventsForAllConnectionsLocked(
468 InputState::CANCEL_NON_POINTER_EVENTS, reason);
469 break;
470 case EventEntry::TYPE_MOTION: {
471 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
472 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
473 synthesizeCancelationEventsForAllConnectionsLocked(
474 InputState::CANCEL_POINTER_EVENTS, reason);
475 } else {
476 synthesizeCancelationEventsForAllConnectionsLocked(
477 InputState::CANCEL_NON_POINTER_EVENTS, reason);
478 }
479 break;
480 }
481 }
482}
483
484bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Browna665ca82010-09-08 11:49:43 -0700485 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
486}
487
Jeff Brown90f0cee2010-10-08 22:31:17 -0700488bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
489 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
490 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Brown33d54ce2010-10-11 14:20:19 -0700491 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brown90f0cee2010-10-08 22:31:17 -0700492 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
493}
494
Jeff Browna665ca82010-09-08 11:49:43 -0700495bool InputDispatcher::isAppSwitchPendingLocked() {
496 return mAppSwitchDueTime != LONG_LONG_MAX;
497}
498
Jeff Browna665ca82010-09-08 11:49:43 -0700499void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
500 mAppSwitchDueTime = LONG_LONG_MAX;
501
502#if DEBUG_APP_SWITCH
503 if (handled) {
504 LOGD("App switch has arrived.");
505 } else {
506 LOGD("App switch was abandoned.");
507 }
508#endif
Jeff Browne839a582010-04-22 18:58:52 -0700509}
510
Jeff Brown54bc2812010-06-15 01:31:58 -0700511bool InputDispatcher::runCommandsLockedInterruptible() {
512 if (mCommandQueue.isEmpty()) {
513 return false;
514 }
Jeff Browne839a582010-04-22 18:58:52 -0700515
Jeff Brown54bc2812010-06-15 01:31:58 -0700516 do {
517 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
518
519 Command command = commandEntry->command;
520 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
521
Jeff Brown51d45a72010-06-17 20:52:56 -0700522 commandEntry->connection.clear();
Jeff Brown54bc2812010-06-15 01:31:58 -0700523 mAllocator.releaseCommandEntry(commandEntry);
524 } while (! mCommandQueue.isEmpty());
525 return true;
Jeff Browne839a582010-04-22 18:58:52 -0700526}
527
Jeff Brown54bc2812010-06-15 01:31:58 -0700528InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
529 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
530 mCommandQueue.enqueueAtTail(commandEntry);
531 return commandEntry;
532}
533
Jeff Browna665ca82010-09-08 11:49:43 -0700534void InputDispatcher::drainInboundQueueLocked() {
535 while (! mInboundQueue.isEmpty()) {
536 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brownd8816c32010-09-16 14:07:33 -0700537 releaseInboundEventLocked(entry);
Jeff Browne839a582010-04-22 18:58:52 -0700538 }
Jeff Browne839a582010-04-22 18:58:52 -0700539}
540
Jeff Brownd8816c32010-09-16 14:07:33 -0700541void InputDispatcher::releasePendingEventLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700542 if (mPendingEvent) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700543 releaseInboundEventLocked(mPendingEvent);
Jeff Browna665ca82010-09-08 11:49:43 -0700544 mPendingEvent = NULL;
545 }
546}
547
Jeff Brownd8816c32010-09-16 14:07:33 -0700548void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700549 InjectionState* injectionState = entry->injectionState;
550 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Browna665ca82010-09-08 11:49:43 -0700551#if DEBUG_DISPATCH_CYCLE
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700552 LOGD("Injected inbound event was dropped.");
Jeff Browna665ca82010-09-08 11:49:43 -0700553#endif
554 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
555 }
556 mAllocator.releaseEventEntry(entry);
557}
558
Jeff Browna665ca82010-09-08 11:49:43 -0700559void InputDispatcher::resetKeyRepeatLocked() {
560 if (mKeyRepeatState.lastKeyEntry) {
561 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
562 mKeyRepeatState.lastKeyEntry = NULL;
563 }
564}
565
566InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brown61ce3982010-09-07 10:44:57 -0700567 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown50de30a2010-06-22 01:27:15 -0700568 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
569
Jeff Brown50de30a2010-06-22 01:27:15 -0700570 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown33d54ce2010-10-11 14:20:19 -0700571 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
572 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Browne839a582010-04-22 18:58:52 -0700573 if (entry->refCount == 1) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700574 mAllocator.recycleKeyEntry(entry);
Jeff Brown51d45a72010-06-17 20:52:56 -0700575 entry->eventTime = currentTime;
Jeff Brown51d45a72010-06-17 20:52:56 -0700576 entry->policyFlags = policyFlags;
Jeff Browne839a582010-04-22 18:58:52 -0700577 entry->repeatCount += 1;
578 } else {
Jeff Brown51d45a72010-06-17 20:52:56 -0700579 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700580 entry->deviceId, entry->source, policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700581 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brownf16c26d2010-07-02 15:37:36 -0700582 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Browne839a582010-04-22 18:58:52 -0700583
584 mKeyRepeatState.lastKeyEntry = newEntry;
585 mAllocator.releaseKeyEntry(entry);
586
587 entry = newEntry;
588 }
Jeff Browna665ca82010-09-08 11:49:43 -0700589 entry->syntheticRepeat = true;
590
591 // Increment reference count since we keep a reference to the event in
592 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
593 entry->refCount += 1;
Jeff Browne839a582010-04-22 18:58:52 -0700594
Jeff Brownf16c26d2010-07-02 15:37:36 -0700595 if (entry->repeatCount == 1) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700596 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brownf16c26d2010-07-02 15:37:36 -0700597 }
598
Jeff Brown61ce3982010-09-07 10:44:57 -0700599 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Browna665ca82010-09-08 11:49:43 -0700600 return entry;
Jeff Browne839a582010-04-22 18:58:52 -0700601}
602
Jeff Browna665ca82010-09-08 11:49:43 -0700603bool InputDispatcher::dispatchConfigurationChangedLocked(
604 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Browne839a582010-04-22 18:58:52 -0700605#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Browna665ca82010-09-08 11:49:43 -0700606 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
607#endif
608
609 // Reset key repeating in case a keyboard device was added or removed or something.
610 resetKeyRepeatLocked();
611
612 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
613 CommandEntry* commandEntry = postCommandLocked(
614 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
615 commandEntry->eventTime = entry->eventTime;
616 return true;
617}
618
619bool InputDispatcher::dispatchKeyLocked(
620 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brown33d54ce2010-10-11 14:20:19 -0700621 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700622 // Give the policy a chance to intercept the key.
623 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Brown33d54ce2010-10-11 14:20:19 -0700624 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700625 CommandEntry* commandEntry = postCommandLocked(
626 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Brown33d54ce2010-10-11 14:20:19 -0700627 if (mFocusedWindow) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700628 commandEntry->inputChannel = mFocusedWindow->inputChannel;
629 }
630 commandEntry->keyEntry = entry;
631 entry->refCount += 1;
632 return false; // wait for the command to run
633 } else {
634 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
635 }
636 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Brown33d54ce2010-10-11 14:20:19 -0700637 if (*dropReason == DROP_REASON_NOT_DROPPED) {
638 *dropReason = DROP_REASON_POLICY;
639 }
Jeff Brownd8816c32010-09-16 14:07:33 -0700640 }
641
642 // Clean up if dropping the event.
Jeff Brown33d54ce2010-10-11 14:20:19 -0700643 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700644 resetTargetsLocked();
Jeff Browna8ed8562010-10-11 23:32:49 -0700645 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
646 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brownd8816c32010-09-16 14:07:33 -0700647 return true;
648 }
649
Jeff Browna665ca82010-09-08 11:49:43 -0700650 // Preprocessing.
651 if (! entry->dispatchInProgress) {
652 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
653
654 if (entry->repeatCount == 0
655 && entry->action == AKEY_EVENT_ACTION_DOWN
Jeff Brown33d54ce2010-10-11 14:20:19 -0700656 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
657 && !entry->isInjected()) {
Jeff Browna665ca82010-09-08 11:49:43 -0700658 if (mKeyRepeatState.lastKeyEntry
659 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
660 // We have seen two identical key downs in a row which indicates that the device
661 // driver is automatically generating key repeats itself. We take note of the
662 // repeat here, but we disable our own next key repeat timer since it is clear that
663 // we will not need to synthesize key repeats ourselves.
664 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
665 resetKeyRepeatLocked();
666 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
667 } else {
668 // Not a repeat. Save key down state in case we do see a repeat later.
669 resetKeyRepeatLocked();
670 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
671 }
672 mKeyRepeatState.lastKeyEntry = entry;
673 entry->refCount += 1;
674 } else if (! entry->syntheticRepeat) {
675 resetKeyRepeatLocked();
676 }
677
678 entry->dispatchInProgress = true;
Jeff Brownd8816c32010-09-16 14:07:33 -0700679 resetTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700680 }
681
682 // Identify targets.
683 if (! mCurrentInputTargetsValid) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700684 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
685 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700686 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
687 return false;
688 }
689
690 setInjectionResultLocked(entry, injectionResult);
691 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
692 return true;
693 }
694
695 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700696 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700697 }
698
699 // Dispatch the key.
700 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Browna665ca82010-09-08 11:49:43 -0700701 return true;
702}
703
704void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
705#if DEBUG_OUTBOUND_EVENT_DETAILS
706 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
707 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
708 "downTime=%lld",
709 prefix,
710 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
711 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
712 entry->downTime);
713#endif
714}
715
716bool InputDispatcher::dispatchMotionLocked(
Jeff Brown33d54ce2010-10-11 14:20:19 -0700717 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700718 // Clean up if dropping the event.
Jeff Brown33d54ce2010-10-11 14:20:19 -0700719 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700720 resetTargetsLocked();
Jeff Browna8ed8562010-10-11 23:32:49 -0700721 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
722 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brownd8816c32010-09-16 14:07:33 -0700723 return true;
724 }
725
Jeff Browna665ca82010-09-08 11:49:43 -0700726 // Preprocessing.
727 if (! entry->dispatchInProgress) {
728 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
729
730 entry->dispatchInProgress = true;
Jeff Brownd8816c32010-09-16 14:07:33 -0700731 resetTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700732 }
733
734 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
735
736 // Identify targets.
737 if (! mCurrentInputTargetsValid) {
Jeff Browna665ca82010-09-08 11:49:43 -0700738 int32_t injectionResult;
739 if (isPointerEvent) {
740 // Pointer event. (eg. touchscreen)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700741 injectionResult = findTouchedWindowTargetsLocked(currentTime,
742 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700743 } else {
744 // Non touch event. (eg. trackball)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700745 injectionResult = findFocusedWindowTargetsLocked(currentTime,
746 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700747 }
748 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
749 return false;
750 }
751
752 setInjectionResultLocked(entry, injectionResult);
753 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
754 return true;
755 }
756
757 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700758 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700759 }
760
761 // Dispatch the motion.
762 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Browna665ca82010-09-08 11:49:43 -0700763 return true;
764}
765
766
767void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
768#if DEBUG_OUTBOUND_EVENT_DETAILS
769 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700770 "action=0x%x, flags=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700771 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700772 prefix,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700773 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
774 entry->action, entry->flags,
Jeff Browne839a582010-04-22 18:58:52 -0700775 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
776 entry->downTime);
777
778 // Print the most recent sample that we have available, this may change due to batching.
779 size_t sampleCount = 1;
Jeff Browna665ca82010-09-08 11:49:43 -0700780 const MotionSample* sample = & entry->firstSample;
Jeff Browne839a582010-04-22 18:58:52 -0700781 for (; sample->next != NULL; sample = sample->next) {
782 sampleCount += 1;
783 }
784 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -0700785 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700786 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -0700787 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -0700788 i, entry->pointerIds[i],
Jeff Brown38a7fab2010-08-30 03:02:23 -0700789 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
790 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
791 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
792 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
793 sample->pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -0700794 }
795
796 // Keep in mind that due to batching, it is possible for the number of samples actually
797 // dispatched to change before the application finally consumed them.
Jeff Brown5c1ed842010-07-14 18:48:53 -0700798 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -0700799 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
800 }
801#endif
Jeff Browne839a582010-04-22 18:58:52 -0700802}
803
804void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
805 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
806#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700807 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700808 "resumeWithAppendedMotionSample=%s",
Jeff Browna665ca82010-09-08 11:49:43 -0700809 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -0700810#endif
811
Jeff Brown54bc2812010-06-15 01:31:58 -0700812 assert(eventEntry->dispatchInProgress); // should already have been set to true
813
Jeff Brownef3a8232010-10-18 13:21:23 -0700814 pokeUserActivityLocked(eventEntry);
815
Jeff Browne839a582010-04-22 18:58:52 -0700816 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
817 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
818
Jeff Brown53a415e2010-09-15 15:18:56 -0700819 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -0700820 if (connectionIndex >= 0) {
821 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown51d45a72010-06-17 20:52:56 -0700822 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -0700823 resumeWithAppendedMotionSample);
824 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700825#if DEBUG_FOCUS
826 LOGD("Dropping event delivery to target with channel '%s' because it "
827 "is no longer registered with the input dispatcher.",
Jeff Browne839a582010-04-22 18:58:52 -0700828 inputTarget.inputChannel->getName().string());
Jeff Brown90f0cee2010-10-08 22:31:17 -0700829#endif
Jeff Browne839a582010-04-22 18:58:52 -0700830 }
831 }
832}
833
Jeff Brownd8816c32010-09-16 14:07:33 -0700834void InputDispatcher::resetTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700835 mCurrentInputTargetsValid = false;
836 mCurrentInputTargets.clear();
Jeff Browna665ca82010-09-08 11:49:43 -0700837 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
838}
839
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700840void InputDispatcher::commitTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700841 mCurrentInputTargetsValid = true;
842}
843
844int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
845 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
846 nsecs_t* nextWakeupTime) {
847 if (application == NULL && window == NULL) {
848 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
849#if DEBUG_FOCUS
850 LOGD("Waiting for system to become ready for input.");
851#endif
852 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
853 mInputTargetWaitStartTime = currentTime;
854 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
855 mInputTargetWaitTimeoutExpired = false;
856 }
857 } else {
858 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
859#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700860 LOGD("Waiting for application to become ready for input: %s",
861 getApplicationWindowLabelLocked(application, window).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700862#endif
863 nsecs_t timeout = window ? window->dispatchingTimeout :
864 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
865
866 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
867 mInputTargetWaitStartTime = currentTime;
868 mInputTargetWaitTimeoutTime = currentTime + timeout;
869 mInputTargetWaitTimeoutExpired = false;
870 }
871 }
872
873 if (mInputTargetWaitTimeoutExpired) {
874 return INPUT_EVENT_INJECTION_TIMED_OUT;
875 }
876
877 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown53a415e2010-09-15 15:18:56 -0700878 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700879
880 // Force poll loop to wake up immediately on next iteration once we get the
881 // ANR response back from the policy.
882 *nextWakeupTime = LONG_LONG_MIN;
883 return INPUT_EVENT_INJECTION_PENDING;
884 } else {
885 // Force poll loop to wake up when timeout is due.
886 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
887 *nextWakeupTime = mInputTargetWaitTimeoutTime;
888 }
889 return INPUT_EVENT_INJECTION_PENDING;
890 }
891}
892
Jeff Brown53a415e2010-09-15 15:18:56 -0700893void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
894 const sp<InputChannel>& inputChannel) {
Jeff Browna665ca82010-09-08 11:49:43 -0700895 if (newTimeout > 0) {
896 // Extend the timeout.
897 mInputTargetWaitTimeoutTime = now() + newTimeout;
898 } else {
899 // Give up.
900 mInputTargetWaitTimeoutExpired = true;
Jeff Brown53a415e2010-09-15 15:18:56 -0700901
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700902 // Release the touch targets.
903 mTouchState.reset();
Jeff Brown405a1d32010-09-16 12:31:46 -0700904
Jeff Brown53a415e2010-09-15 15:18:56 -0700905 // Input state will not be realistic. Mark it out of sync.
Jeff Brown40ad4702010-09-16 11:02:16 -0700906 if (inputChannel.get()) {
907 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
908 if (connectionIndex >= 0) {
909 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700910 synthesizeCancelationEventsForConnectionLocked(
911 connection, InputState::CANCEL_ALL_EVENTS,
912 "application not responding");
Jeff Brown40ad4702010-09-16 11:02:16 -0700913 }
Jeff Brown53a415e2010-09-15 15:18:56 -0700914 }
Jeff Browna665ca82010-09-08 11:49:43 -0700915 }
916}
917
Jeff Brown53a415e2010-09-15 15:18:56 -0700918nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Browna665ca82010-09-08 11:49:43 -0700919 nsecs_t currentTime) {
920 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
921 return currentTime - mInputTargetWaitStartTime;
922 }
923 return 0;
924}
925
926void InputDispatcher::resetANRTimeoutsLocked() {
927#if DEBUG_FOCUS
928 LOGD("Resetting ANR timeouts.");
929#endif
930
Jeff Browna665ca82010-09-08 11:49:43 -0700931 // Reset input target wait timeout.
932 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
933}
934
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700935int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
936 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -0700937 mCurrentInputTargets.clear();
938
939 int32_t injectionResult;
940
941 // If there is no currently focused window and no focused application
942 // then drop the event.
943 if (! mFocusedWindow) {
944 if (mFocusedApplication) {
945#if DEBUG_FOCUS
946 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -0700947 "focused application that may eventually add a window: %s.",
948 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700949#endif
950 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
951 mFocusedApplication, NULL, nextWakeupTime);
952 goto Unresponsive;
953 }
954
955 LOGI("Dropping event because there is no focused window or focused application.");
956 injectionResult = INPUT_EVENT_INJECTION_FAILED;
957 goto Failed;
958 }
959
960 // Check permissions.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700961 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700962 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
963 goto Failed;
964 }
965
966 // If the currently focused window is paused then keep waiting.
967 if (mFocusedWindow->paused) {
968#if DEBUG_FOCUS
969 LOGD("Waiting because focused window is paused.");
970#endif
971 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
972 mFocusedApplication, mFocusedWindow, nextWakeupTime);
973 goto Unresponsive;
974 }
975
Jeff Brown53a415e2010-09-15 15:18:56 -0700976 // If the currently focused window is still working on previous events then keep waiting.
977 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
978#if DEBUG_FOCUS
979 LOGD("Waiting because focused window still processing previous input.");
980#endif
981 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
982 mFocusedApplication, mFocusedWindow, nextWakeupTime);
983 goto Unresponsive;
984 }
985
Jeff Browna665ca82010-09-08 11:49:43 -0700986 // Success! Output targets.
987 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700988 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -0700989
990 // Done.
991Failed:
992Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -0700993 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
994 updateDispatchStatisticsLocked(currentTime, entry,
995 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -0700996#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700997 LOGD("findFocusedWindow finished: injectionResult=%d, "
998 "timeSpendWaitingForApplication=%0.1fms",
999 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001000#endif
1001 return injectionResult;
1002}
1003
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001004int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1005 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -07001006 enum InjectionPermission {
1007 INJECTION_PERMISSION_UNKNOWN,
1008 INJECTION_PERMISSION_GRANTED,
1009 INJECTION_PERMISSION_DENIED
1010 };
1011
Jeff Browna665ca82010-09-08 11:49:43 -07001012 mCurrentInputTargets.clear();
1013
1014 nsecs_t startTime = now();
1015
1016 // For security reasons, we defer updating the touch state until we are sure that
1017 // event injection will be allowed.
1018 //
1019 // FIXME In the original code, screenWasOff could never be set to true.
1020 // The reason is that the POLICY_FLAG_WOKE_HERE
1021 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1022 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1023 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1024 // events upon which no preprocessing took place. So policyFlags was always 0.
1025 // In the new native input dispatcher we're a bit more careful about event
1026 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1027 // Unfortunately we obtain undesirable behavior.
1028 //
1029 // Here's what happens:
1030 //
1031 // When the device dims in anticipation of going to sleep, touches
1032 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1033 // the device to brighten and reset the user activity timer.
1034 // Touches on other windows (such as the launcher window)
1035 // are dropped. Then after a moment, the device goes to sleep. Oops.
1036 //
1037 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1038 // instead of POLICY_FLAG_WOKE_HERE...
1039 //
1040 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1041
1042 int32_t action = entry->action;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001043 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Browna665ca82010-09-08 11:49:43 -07001044
1045 // Update the touch state as needed based on the properties of the touch event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001046 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1047 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1048 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1049 mTempTouchState.reset();
1050 mTempTouchState.down = true;
1051 } else {
1052 mTempTouchState.copyFrom(mTouchState);
1053 }
Jeff Browna665ca82010-09-08 11:49:43 -07001054
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001055 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1056 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1057 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1058 /* Case 1: New splittable pointer going down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001059
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001060 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1061 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1062 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1063 const InputWindow* newTouchedWindow = NULL;
1064 const InputWindow* topErrorWindow = NULL;
Jeff Browna665ca82010-09-08 11:49:43 -07001065
1066 // Traverse windows from front to back to find touched window and outside targets.
1067 size_t numWindows = mWindows.size();
1068 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001069 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07001070 int32_t flags = window->layoutParamsFlags;
1071
1072 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1073 if (! topErrorWindow) {
1074 topErrorWindow = window;
1075 }
1076 }
1077
1078 if (window->visible) {
1079 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1080 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1081 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1082 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1083 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1084 newTouchedWindow = window;
Jeff Browna665ca82010-09-08 11:49:43 -07001085 }
1086 break; // found touched window, exit window loop
1087 }
1088 }
1089
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001090 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1091 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001092 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1093 if (isWindowObscuredAtPointLocked(window, x, y)) {
1094 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1095 }
1096
1097 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -07001098 }
1099 }
1100 }
1101
1102 // If there is an error window but it is not taking focus (typically because
1103 // it is invisible) then wait for it. Any other focused window may in
1104 // fact be in ANR state.
1105 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1106#if DEBUG_FOCUS
1107 LOGD("Waiting because system error window is pending.");
1108#endif
1109 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1110 NULL, NULL, nextWakeupTime);
1111 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1112 goto Unresponsive;
1113 }
1114
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001115 // Figure out whether splitting will be allowed for this window.
Jeff Brown3c2450f2010-09-28 13:24:41 -07001116 if (newTouchedWindow
1117 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001118 // New window supports splitting.
1119 isSplit = true;
1120 } else if (isSplit) {
1121 // New window does not support splitting but we have already split events.
1122 // Assign the pointer to the first foreground window we find.
1123 // (May be NULL which is why we put this code block before the next check.)
1124 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1125 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001126
Jeff Browna665ca82010-09-08 11:49:43 -07001127 // If we did not find a touched window then fail.
1128 if (! newTouchedWindow) {
1129 if (mFocusedApplication) {
1130#if DEBUG_FOCUS
1131 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -07001132 "focused application that may eventually add a new window: %s.",
1133 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -07001134#endif
1135 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1136 mFocusedApplication, NULL, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -07001137 goto Unresponsive;
1138 }
1139
1140 LOGI("Dropping event because there is no touched window or focused application.");
1141 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001142 goto Failed;
1143 }
1144
Jeff Brown35cf0e92010-10-05 12:26:23 -07001145 // Set target flags.
1146 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1147 if (isSplit) {
1148 targetFlags |= InputTarget::FLAG_SPLIT;
1149 }
1150 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1151 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1152 }
1153
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001154 // Update the temporary touch state.
1155 BitSet32 pointerIds;
1156 if (isSplit) {
1157 uint32_t pointerId = entry->pointerIds[pointerIndex];
1158 pointerIds.markBit(pointerId);
Jeff Browna665ca82010-09-08 11:49:43 -07001159 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001160 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001161 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001162 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001163
1164 // If the pointer is not currently down, then ignore the event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001165 if (! mTempTouchState.down) {
Jeff Browna665ca82010-09-08 11:49:43 -07001166 LOGI("Dropping event because the pointer is not down.");
1167 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001168 goto Failed;
1169 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001170 }
Jeff Browna665ca82010-09-08 11:49:43 -07001171
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001172 // Check permission to inject into all touched foreground windows and ensure there
1173 // is at least one touched foreground window.
1174 {
1175 bool haveForegroundWindow = false;
1176 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1177 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1178 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1179 haveForegroundWindow = true;
1180 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1181 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1182 injectionPermission = INJECTION_PERMISSION_DENIED;
1183 goto Failed;
1184 }
1185 }
1186 }
1187 if (! haveForegroundWindow) {
Jeff Browna665ca82010-09-08 11:49:43 -07001188#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001189 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Browna665ca82010-09-08 11:49:43 -07001190#endif
1191 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001192 goto Failed;
1193 }
1194
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001195 // Permission granted to injection into all touched foreground windows.
1196 injectionPermission = INJECTION_PERMISSION_GRANTED;
1197 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001198
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001199 // Ensure all touched foreground windows are ready for new input.
1200 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1201 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1202 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1203 // If the touched window is paused then keep waiting.
1204 if (touchedWindow.window->paused) {
1205#if DEBUG_INPUT_DISPATCHER_POLICY
1206 LOGD("Waiting because touched window is paused.");
Jeff Brown53a415e2010-09-15 15:18:56 -07001207#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001208 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1209 NULL, touchedWindow.window, nextWakeupTime);
1210 goto Unresponsive;
1211 }
1212
1213 // If the touched window is still working on previous events then keep waiting.
1214 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1215#if DEBUG_FOCUS
1216 LOGD("Waiting because touched window still processing previous input.");
1217#endif
1218 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1219 NULL, touchedWindow.window, nextWakeupTime);
1220 goto Unresponsive;
1221 }
1222 }
1223 }
1224
1225 // If this is the first pointer going down and the touched window has a wallpaper
1226 // then also add the touched wallpaper windows so they are locked in for the duration
1227 // of the touch gesture.
1228 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1229 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1230 if (foregroundWindow->hasWallpaper) {
1231 for (size_t i = 0; i < mWindows.size(); i++) {
1232 const InputWindow* window = & mWindows[i];
1233 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001234 mTempTouchState.addOrUpdateWindow(window,
1235 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001236 }
1237 }
1238 }
1239 }
1240
Jeff Browna665ca82010-09-08 11:49:43 -07001241 // Success! Output targets.
1242 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Browna665ca82010-09-08 11:49:43 -07001243
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001244 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1245 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1246 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1247 touchedWindow.pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001248 }
1249
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001250 // Drop the outside touch window since we will not care about them in the next iteration.
1251 mTempTouchState.removeOutsideTouchWindows();
1252
Jeff Browna665ca82010-09-08 11:49:43 -07001253Failed:
1254 // Check injection permission once and for all.
1255 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001256 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001257 injectionPermission = INJECTION_PERMISSION_GRANTED;
1258 } else {
1259 injectionPermission = INJECTION_PERMISSION_DENIED;
1260 }
1261 }
1262
1263 // Update final pieces of touch state if the injector had permission.
1264 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001265 if (maskedAction == AMOTION_EVENT_ACTION_UP
1266 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1267 // All pointers up or canceled.
1268 mTempTouchState.reset();
1269 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1270 // First pointer went down.
1271 if (mTouchState.down) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001272#if DEBUG_FOCUS
1273 LOGD("Pointer down received while already down.");
1274#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001275 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001276 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1277 // One pointer went up.
1278 if (isSplit) {
1279 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1280 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Browna665ca82010-09-08 11:49:43 -07001281
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001282 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1283 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1284 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1285 touchedWindow.pointerIds.clearBit(pointerId);
1286 if (touchedWindow.pointerIds.isEmpty()) {
1287 mTempTouchState.windows.removeAt(i);
1288 continue;
1289 }
1290 }
1291 i += 1;
1292 }
Jeff Browna665ca82010-09-08 11:49:43 -07001293 }
Jeff Browna665ca82010-09-08 11:49:43 -07001294 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001295
1296 // Save changes to touch state.
1297 mTouchState.copyFrom(mTempTouchState);
Jeff Browna665ca82010-09-08 11:49:43 -07001298 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001299#if DEBUG_FOCUS
1300 LOGD("Not updating touch focus because injection was denied.");
1301#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001302 }
1303
1304Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -07001305 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1306 updateDispatchStatisticsLocked(currentTime, entry,
1307 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001308#if DEBUG_FOCUS
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001309 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1310 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown53a415e2010-09-15 15:18:56 -07001311 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001312#endif
1313 return injectionResult;
1314}
1315
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001316void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1317 BitSet32 pointerIds) {
Jeff Browna665ca82010-09-08 11:49:43 -07001318 mCurrentInputTargets.push();
1319
1320 InputTarget& target = mCurrentInputTargets.editTop();
1321 target.inputChannel = window->inputChannel;
1322 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001323 target.xOffset = - window->frameLeft;
1324 target.yOffset = - window->frameTop;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001325 target.pointerIds = pointerIds;
Jeff Browna665ca82010-09-08 11:49:43 -07001326}
1327
1328void InputDispatcher::addMonitoringTargetsLocked() {
1329 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1330 mCurrentInputTargets.push();
1331
1332 InputTarget& target = mCurrentInputTargets.editTop();
1333 target.inputChannel = mMonitoringChannels[i];
1334 target.flags = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07001335 target.xOffset = 0;
1336 target.yOffset = 0;
1337 }
1338}
1339
1340bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001341 const InjectionState* injectionState) {
1342 if (injectionState
Jeff Brown90f0cee2010-10-08 22:31:17 -07001343 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1344 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1345 if (window) {
1346 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1347 "with input channel %s owned by uid %d",
1348 injectionState->injectorPid, injectionState->injectorUid,
1349 window->inputChannel->getName().string(),
1350 window->ownerUid);
1351 } else {
1352 LOGW("Permission denied: injecting event from pid %d uid %d",
1353 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-09-08 11:49:43 -07001354 }
Jeff Brown90f0cee2010-10-08 22:31:17 -07001355 return false;
Jeff Browna665ca82010-09-08 11:49:43 -07001356 }
1357 return true;
1358}
1359
Jeff Brown35cf0e92010-10-05 12:26:23 -07001360bool InputDispatcher::isWindowObscuredAtPointLocked(
1361 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Browna665ca82010-09-08 11:49:43 -07001362 size_t numWindows = mWindows.size();
1363 for (size_t i = 0; i < numWindows; i++) {
1364 const InputWindow* other = & mWindows.itemAt(i);
1365 if (other == window) {
1366 break;
1367 }
Jeff Brown35cf0e92010-10-05 12:26:23 -07001368 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001369 return true;
1370 }
1371 }
1372 return false;
1373}
1374
Jeff Brown53a415e2010-09-15 15:18:56 -07001375bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1376 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1377 if (connectionIndex >= 0) {
1378 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1379 return connection->outboundQueue.isEmpty();
1380 } else {
1381 return true;
1382 }
1383}
1384
1385String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1386 const InputWindow* window) {
1387 if (application) {
1388 if (window) {
1389 String8 label(application->name);
1390 label.append(" - ");
1391 label.append(window->name);
1392 return label;
1393 } else {
1394 return application->name;
1395 }
1396 } else if (window) {
1397 return window->name;
1398 } else {
1399 return String8("<unknown application or window>");
1400 }
1401}
1402
Jeff Brownef3a8232010-10-18 13:21:23 -07001403void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1404 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
1405 if (eventEntry->type == EventEntry::TYPE_MOTION) {
1406 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
1407 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1408 switch (motionEntry->action) {
1409 case AMOTION_EVENT_ACTION_DOWN:
1410 eventType = POWER_MANAGER_TOUCH_EVENT;
1411 break;
1412 case AMOTION_EVENT_ACTION_UP:
1413 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
1414 break;
1415 default:
1416 if (motionEntry->eventTime - motionEntry->downTime >= EVENT_IGNORE_DURATION) {
1417 eventType = POWER_MANAGER_TOUCH_EVENT;
1418 } else {
1419 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
1420 }
1421 break;
1422 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001423 }
1424 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001425
Jeff Browna665ca82010-09-08 11:49:43 -07001426 CommandEntry* commandEntry = postCommandLocked(
1427 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Brownef3a8232010-10-18 13:21:23 -07001428 commandEntry->eventTime = eventEntry->eventTime;
Jeff Browna665ca82010-09-08 11:49:43 -07001429 commandEntry->userActivityEventType = eventType;
1430}
1431
Jeff Brown51d45a72010-06-17 20:52:56 -07001432void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1433 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -07001434 bool resumeWithAppendedMotionSample) {
1435#if DEBUG_DISPATCH_CYCLE
Jeff Brown53a415e2010-09-15 15:18:56 -07001436 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001437 "xOffset=%f, yOffset=%f, "
1438 "windowType=%d, pointerIds=0x%x, "
1439 "resumeWithAppendedMotionSample=%s",
Jeff Brown53a415e2010-09-15 15:18:56 -07001440 connection->getInputChannelName(), inputTarget->flags,
Jeff Browne839a582010-04-22 18:58:52 -07001441 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001442 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Browna665ca82010-09-08 11:49:43 -07001443 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -07001444#endif
1445
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001446 // Make sure we are never called for streaming when splitting across multiple windows.
1447 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1448 assert(! (resumeWithAppendedMotionSample && isSplit));
1449
Jeff Browne839a582010-04-22 18:58:52 -07001450 // Skip this event if the connection status is not normal.
Jeff Brown53a415e2010-09-15 15:18:56 -07001451 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Browne839a582010-04-22 18:58:52 -07001452 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001453#if DEBUG_DISPATCH_CYCLE
1454 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Browna665ca82010-09-08 11:49:43 -07001455 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown90f0cee2010-10-08 22:31:17 -07001456#endif
Jeff Browne839a582010-04-22 18:58:52 -07001457 return;
1458 }
1459
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001460 // Split a motion event if needed.
1461 if (isSplit) {
1462 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1463
1464 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1465 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1466 MotionEntry* splitMotionEntry = splitMotionEvent(
1467 originalMotionEntry, inputTarget->pointerIds);
1468#if DEBUG_FOCUS
1469 LOGD("channel '%s' ~ Split motion event.",
1470 connection->getInputChannelName());
1471 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1472#endif
1473 eventEntry = splitMotionEntry;
1474 }
1475 }
1476
Jeff Browne839a582010-04-22 18:58:52 -07001477 // Resume the dispatch cycle with a freshly appended motion sample.
1478 // First we check that the last dispatch entry in the outbound queue is for the same
1479 // motion event to which we appended the motion sample. If we find such a dispatch
1480 // entry, and if it is currently in progress then we try to stream the new sample.
1481 bool wasEmpty = connection->outboundQueue.isEmpty();
1482
1483 if (! wasEmpty && resumeWithAppendedMotionSample) {
1484 DispatchEntry* motionEventDispatchEntry =
1485 connection->findQueuedDispatchEntryForEvent(eventEntry);
1486 if (motionEventDispatchEntry) {
1487 // If the dispatch entry is not in progress, then we must be busy dispatching an
1488 // earlier event. Not a problem, the motion event is on the outbound queue and will
1489 // be dispatched later.
1490 if (! motionEventDispatchEntry->inProgress) {
1491#if DEBUG_BATCHING
1492 LOGD("channel '%s' ~ Not streaming because the motion event has "
1493 "not yet been dispatched. "
1494 "(Waiting for earlier events to be consumed.)",
1495 connection->getInputChannelName());
1496#endif
1497 return;
1498 }
1499
1500 // If the dispatch entry is in progress but it already has a tail of pending
1501 // motion samples, then it must mean that the shared memory buffer filled up.
1502 // Not a problem, when this dispatch cycle is finished, we will eventually start
1503 // a new dispatch cycle to process the tail and that tail includes the newly
1504 // appended motion sample.
1505 if (motionEventDispatchEntry->tailMotionSample) {
1506#if DEBUG_BATCHING
1507 LOGD("channel '%s' ~ Not streaming because no new samples can "
1508 "be appended to the motion event in this dispatch cycle. "
1509 "(Waiting for next dispatch cycle to start.)",
1510 connection->getInputChannelName());
1511#endif
1512 return;
1513 }
1514
1515 // The dispatch entry is in progress and is still potentially open for streaming.
1516 // Try to stream the new motion sample. This might fail if the consumer has already
1517 // consumed the motion event (or if the channel is broken).
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001518 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1519 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Browne839a582010-04-22 18:58:52 -07001520 status_t status = connection->inputPublisher.appendMotionSample(
1521 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1522 if (status == OK) {
1523#if DEBUG_BATCHING
1524 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1525 connection->getInputChannelName());
1526#endif
1527 return;
1528 }
1529
1530#if DEBUG_BATCHING
1531 if (status == NO_MEMORY) {
1532 LOGD("channel '%s' ~ Could not append motion sample to currently "
1533 "dispatched move event because the shared memory buffer is full. "
1534 "(Waiting for next dispatch cycle to start.)",
1535 connection->getInputChannelName());
1536 } else if (status == status_t(FAILED_TRANSACTION)) {
1537 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown50de30a2010-06-22 01:27:15 -07001538 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-04-22 18:58:52 -07001539 "(Waiting for next dispatch cycle to start.)",
1540 connection->getInputChannelName());
1541 } else {
1542 LOGD("channel '%s' ~ Could not append motion sample to currently "
1543 "dispatched move event due to an error, status=%d. "
1544 "(Waiting for next dispatch cycle to start.)",
1545 connection->getInputChannelName(), status);
1546 }
1547#endif
1548 // Failed to stream. Start a new tail of pending motion samples to dispatch
1549 // in the next cycle.
1550 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1551 return;
1552 }
1553 }
1554
1555 // This is a new event.
1556 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Browna665ca82010-09-08 11:49:43 -07001557 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown53a415e2010-09-15 15:18:56 -07001558 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1559 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001560 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001561 }
1562
Jeff Browne839a582010-04-22 18:58:52 -07001563 // Handle the case where we could not stream a new motion sample because the consumer has
1564 // already consumed the motion event (otherwise the corresponding dispatch entry would
1565 // still be in the outbound queue for this connection). We set the head motion sample
1566 // to the list starting with the newly appended motion sample.
1567 if (resumeWithAppendedMotionSample) {
1568#if DEBUG_BATCHING
1569 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1570 "that cannot be streamed because the motion event has already been consumed.",
1571 connection->getInputChannelName());
1572#endif
1573 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1574 dispatchEntry->headMotionSample = appendedMotionSample;
1575 }
1576
1577 // Enqueue the dispatch entry.
1578 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1579
1580 // If the outbound queue was previously empty, start the dispatch cycle going.
1581 if (wasEmpty) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001582 activateConnectionLocked(connection.get());
Jeff Brown53a415e2010-09-15 15:18:56 -07001583 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001584 }
1585}
1586
Jeff Brown51d45a72010-06-17 20:52:56 -07001587void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown53a415e2010-09-15 15:18:56 -07001588 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001589#if DEBUG_DISPATCH_CYCLE
1590 LOGD("channel '%s' ~ startDispatchCycle",
1591 connection->getInputChannelName());
1592#endif
1593
1594 assert(connection->status == Connection::STATUS_NORMAL);
1595 assert(! connection->outboundQueue.isEmpty());
1596
Jeff Browna665ca82010-09-08 11:49:43 -07001597 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001598 assert(! dispatchEntry->inProgress);
1599
Jeff Browna665ca82010-09-08 11:49:43 -07001600 // Mark the dispatch entry as in progress.
1601 dispatchEntry->inProgress = true;
1602
1603 // Update the connection's input state.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001604 EventEntry* eventEntry = dispatchEntry->eventEntry;
1605 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001606
1607#if FILTER_INPUT_EVENTS
1608 // Filter out inconsistent sequences of input events.
1609 // The input system may drop or inject events in a way that could violate implicit
1610 // invariants on input state and potentially cause an application to crash
1611 // or think that a key or pointer is stuck down. Technically we make no guarantees
1612 // of consistency but it would be nice to improve on this where possible.
1613 // XXX: This code is a proof of concept only. Not ready for prime time.
1614 if (consistency == InputState::TOLERABLE) {
1615#if DEBUG_DISPATCH_CYCLE
1616 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1617 "current input state but that is likely to be tolerated by the application.",
1618 connection->getInputChannelName());
1619#endif
1620 } else if (consistency == InputState::BROKEN) {
1621 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1622 "current input state and that is likely to cause the application to crash.",
1623 connection->getInputChannelName());
1624 startNextDispatchCycleLocked(currentTime, connection);
1625 return;
1626 }
1627#endif
Jeff Browne839a582010-04-22 18:58:52 -07001628
1629 // Publish the event.
1630 status_t status;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001631 switch (eventEntry->type) {
Jeff Browne839a582010-04-22 18:58:52 -07001632 case EventEntry::TYPE_KEY: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001633 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001634
1635 // Apply target flags.
1636 int32_t action = keyEntry->action;
1637 int32_t flags = keyEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001638
1639 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001640 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-04-22 18:58:52 -07001641 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1642 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1643 keyEntry->eventTime);
1644
1645 if (status) {
1646 LOGE("channel '%s' ~ Could not publish key event, "
1647 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001648 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001649 return;
1650 }
1651 break;
1652 }
1653
1654 case EventEntry::TYPE_MOTION: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001655 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001656
1657 // Apply target flags.
1658 int32_t action = motionEntry->action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07001659 int32_t flags = motionEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001660 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001661 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -07001662 }
Jeff Brownaf30ff62010-09-01 17:01:00 -07001663 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1664 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1665 }
Jeff Browne839a582010-04-22 18:58:52 -07001666
1667 // If headMotionSample is non-NULL, then it points to the first new sample that we
1668 // were unable to dispatch during the previous cycle so we resume dispatching from
1669 // that point in the list of motion samples.
1670 // Otherwise, we just start from the first sample of the motion event.
1671 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1672 if (! firstMotionSample) {
1673 firstMotionSample = & motionEntry->firstSample;
1674 }
1675
Jeff Brownf26db0d2010-07-16 17:21:06 -07001676 // Set the X and Y offset depending on the input source.
1677 float xOffset, yOffset;
1678 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1679 xOffset = dispatchEntry->xOffset;
1680 yOffset = dispatchEntry->yOffset;
1681 } else {
1682 xOffset = 0.0f;
1683 yOffset = 0.0f;
1684 }
1685
Jeff Browne839a582010-04-22 18:58:52 -07001686 // Publish the motion event and the first motion sample.
1687 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001688 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -07001689 xOffset, yOffset,
Jeff Browne839a582010-04-22 18:58:52 -07001690 motionEntry->xPrecision, motionEntry->yPrecision,
1691 motionEntry->downTime, firstMotionSample->eventTime,
1692 motionEntry->pointerCount, motionEntry->pointerIds,
1693 firstMotionSample->pointerCoords);
1694
1695 if (status) {
1696 LOGE("channel '%s' ~ Could not publish motion event, "
1697 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001698 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001699 return;
1700 }
1701
1702 // Append additional motion samples.
1703 MotionSample* nextMotionSample = firstMotionSample->next;
1704 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1705 status = connection->inputPublisher.appendMotionSample(
1706 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1707 if (status == NO_MEMORY) {
1708#if DEBUG_DISPATCH_CYCLE
1709 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1710 "be sent in the next dispatch cycle.",
1711 connection->getInputChannelName());
1712#endif
1713 break;
1714 }
1715 if (status != OK) {
1716 LOGE("channel '%s' ~ Could not append motion sample "
1717 "for a reason other than out of memory, status=%d",
1718 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001719 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001720 return;
1721 }
1722 }
1723
1724 // Remember the next motion sample that we could not dispatch, in case we ran out
1725 // of space in the shared memory buffer.
1726 dispatchEntry->tailMotionSample = nextMotionSample;
1727 break;
1728 }
1729
1730 default: {
1731 assert(false);
1732 }
1733 }
1734
1735 // Send the dispatch signal.
1736 status = connection->inputPublisher.sendDispatchSignal();
1737 if (status) {
1738 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1739 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001740 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001741 return;
1742 }
1743
1744 // Record information about the newly started dispatch cycle.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001745 connection->lastEventTime = eventEntry->eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07001746 connection->lastDispatchTime = currentTime;
1747
Jeff Browne839a582010-04-22 18:58:52 -07001748 // Notify other system components.
1749 onDispatchCycleStartedLocked(currentTime, connection);
1750}
1751
Jeff Brown51d45a72010-06-17 20:52:56 -07001752void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1753 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001754#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001755 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -07001756 "%01.1fms since dispatch",
1757 connection->getInputChannelName(),
1758 connection->getEventLatencyMillis(currentTime),
1759 connection->getDispatchLatencyMillis(currentTime));
1760#endif
1761
Jeff Brown54bc2812010-06-15 01:31:58 -07001762 if (connection->status == Connection::STATUS_BROKEN
1763 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001764 return;
1765 }
1766
Jeff Brown53a415e2010-09-15 15:18:56 -07001767 // Notify other system components.
1768 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001769
1770 // Reset the publisher since the event has been consumed.
1771 // We do this now so that the publisher can release some of its internal resources
1772 // while waiting for the next dispatch cycle to begin.
1773 status_t status = connection->inputPublisher.reset();
1774 if (status) {
1775 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1776 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001777 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001778 return;
1779 }
1780
Jeff Browna665ca82010-09-08 11:49:43 -07001781 startNextDispatchCycleLocked(currentTime, connection);
1782}
1783
1784void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1785 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001786 // Start the next dispatch cycle for this connection.
1787 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001788 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001789 if (dispatchEntry->inProgress) {
1790 // Finish or resume current event in progress.
1791 if (dispatchEntry->tailMotionSample) {
1792 // We have a tail of undispatched motion samples.
1793 // Reuse the same DispatchEntry and start a new cycle.
1794 dispatchEntry->inProgress = false;
1795 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1796 dispatchEntry->tailMotionSample = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07001797 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001798 return;
1799 }
1800 // Finished.
1801 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001802 if (dispatchEntry->hasForegroundTarget()) {
1803 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001804 }
Jeff Browne839a582010-04-22 18:58:52 -07001805 mAllocator.releaseDispatchEntry(dispatchEntry);
1806 } else {
1807 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown53a415e2010-09-15 15:18:56 -07001808 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001809 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001810 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001811 return;
1812 }
1813 }
1814
1815 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001816 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001817}
1818
Jeff Brown90f0cee2010-10-08 22:31:17 -07001819void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1820 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001821#if DEBUG_DISPATCH_CYCLE
Jeff Brown90f0cee2010-10-08 22:31:17 -07001822 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001823 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001824#endif
1825
Jeff Browna665ca82010-09-08 11:49:43 -07001826 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001827 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001828
Jeff Brown90f0cee2010-10-08 22:31:17 -07001829 // The connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001830 // Ignore already broken or zombie connections.
Jeff Brown90f0cee2010-10-08 22:31:17 -07001831 if (connection->status == Connection::STATUS_NORMAL) {
1832 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001833
Jeff Brown90f0cee2010-10-08 22:31:17 -07001834 // Notify other system components.
1835 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001836 }
Jeff Browne839a582010-04-22 18:58:52 -07001837}
1838
Jeff Brown53a415e2010-09-15 15:18:56 -07001839void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1840 while (! connection->outboundQueue.isEmpty()) {
1841 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1842 if (dispatchEntry->hasForegroundTarget()) {
1843 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001844 }
1845 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001846 }
1847
Jeff Brown53a415e2010-09-15 15:18:56 -07001848 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001849}
1850
Jeff Brown59abe7e2010-09-13 23:17:30 -07001851int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-04-22 18:58:52 -07001852 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1853
1854 { // acquire lock
1855 AutoMutex _l(d->mLock);
1856
1857 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1858 if (connectionIndex < 0) {
1859 LOGE("Received spurious receive callback for unknown input channel. "
1860 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001861 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001862 }
1863
Jeff Brown51d45a72010-06-17 20:52:56 -07001864 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001865
1866 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001867 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-04-22 18:58:52 -07001868 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1869 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001870 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001871 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001872 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001873 }
1874
Jeff Brown59abe7e2010-09-13 23:17:30 -07001875 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001876 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1877 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001878 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001879 }
1880
1881 status_t status = connection->inputPublisher.receiveFinishedSignal();
1882 if (status) {
1883 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1884 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001885 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001886 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001887 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001888 }
1889
Jeff Brown51d45a72010-06-17 20:52:56 -07001890 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001891 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001892 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001893 } // release lock
1894}
1895
Jeff Brown90f0cee2010-10-08 22:31:17 -07001896void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1897 InputState::CancelationOptions options, const char* reason) {
1898 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1899 synthesizeCancelationEventsForConnectionLocked(
1900 mConnectionsByReceiveFd.valueAt(i), options, reason);
1901 }
1902}
1903
1904void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1905 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1906 const char* reason) {
1907 ssize_t index = getConnectionIndexLocked(channel);
1908 if (index >= 0) {
1909 synthesizeCancelationEventsForConnectionLocked(
1910 mConnectionsByReceiveFd.valueAt(index), options, reason);
1911 }
1912}
1913
1914void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1915 const sp<Connection>& connection, InputState::CancelationOptions options,
1916 const char* reason) {
1917 nsecs_t currentTime = now();
1918
1919 mTempCancelationEvents.clear();
1920 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1921 mTempCancelationEvents, options);
1922
1923 if (! mTempCancelationEvents.isEmpty()
1924 && connection->status != Connection::STATUS_BROKEN) {
1925#if DEBUG_OUTBOUND_EVENT_DETAILS
1926 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1927 "with reality: %s, options=%d.",
1928 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1929#endif
1930 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1931 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1932 switch (cancelationEventEntry->type) {
1933 case EventEntry::TYPE_KEY:
1934 logOutboundKeyDetailsLocked("cancel - ",
1935 static_cast<KeyEntry*>(cancelationEventEntry));
1936 break;
1937 case EventEntry::TYPE_MOTION:
1938 logOutboundMotionDetailsLocked("cancel - ",
1939 static_cast<MotionEntry*>(cancelationEventEntry));
1940 break;
1941 }
1942
1943 int32_t xOffset, yOffset;
1944 const InputWindow* window = getWindowLocked(connection->inputChannel);
1945 if (window) {
1946 xOffset = -window->frameLeft;
1947 yOffset = -window->frameTop;
1948 } else {
1949 xOffset = 0;
1950 yOffset = 0;
1951 }
1952
1953 DispatchEntry* cancelationDispatchEntry =
1954 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1955 0, xOffset, yOffset);
1956 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1957
1958 mAllocator.releaseEventEntry(cancelationEventEntry);
1959 }
1960
1961 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1962 startDispatchCycleLocked(currentTime, connection);
1963 }
1964 }
1965}
1966
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001967InputDispatcher::MotionEntry*
1968InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1969 assert(pointerIds.value != 0);
1970
1971 uint32_t splitPointerIndexMap[MAX_POINTERS];
1972 int32_t splitPointerIds[MAX_POINTERS];
1973 PointerCoords splitPointerCoords[MAX_POINTERS];
1974
1975 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1976 uint32_t splitPointerCount = 0;
1977
1978 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1979 originalPointerIndex++) {
1980 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1981 if (pointerIds.hasBit(pointerId)) {
1982 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1983 splitPointerIds[splitPointerCount] = pointerId;
1984 splitPointerCoords[splitPointerCount] =
1985 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1986 splitPointerCount += 1;
1987 }
1988 }
1989 assert(splitPointerCount == pointerIds.count());
1990
1991 int32_t action = originalMotionEntry->action;
1992 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1993 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
1994 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1995 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
1996 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
1997 if (pointerIds.hasBit(pointerId)) {
1998 if (pointerIds.count() == 1) {
1999 // The first/last pointer went down/up.
2000 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2001 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brownffb16d62010-09-27 16:35:11 -07002002 } else {
2003 // A secondary pointer went down/up.
2004 uint32_t splitPointerIndex = 0;
2005 while (pointerId != splitPointerIds[splitPointerIndex]) {
2006 splitPointerIndex += 1;
2007 }
2008 action = maskedAction | (splitPointerIndex
2009 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002010 }
2011 } else {
2012 // An unrelated pointer changed.
2013 action = AMOTION_EVENT_ACTION_MOVE;
2014 }
2015 }
2016
2017 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2018 originalMotionEntry->eventTime,
2019 originalMotionEntry->deviceId,
2020 originalMotionEntry->source,
2021 originalMotionEntry->policyFlags,
2022 action,
2023 originalMotionEntry->flags,
2024 originalMotionEntry->metaState,
2025 originalMotionEntry->edgeFlags,
2026 originalMotionEntry->xPrecision,
2027 originalMotionEntry->yPrecision,
2028 originalMotionEntry->downTime,
2029 splitPointerCount, splitPointerIds, splitPointerCoords);
2030
2031 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2032 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2033 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2034 splitPointerIndex++) {
2035 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2036 splitPointerCoords[splitPointerIndex] =
2037 originalMotionSample->pointerCoords[originalPointerIndex];
2038 }
2039
2040 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2041 splitPointerCoords);
2042 }
2043
2044 return splitMotionEntry;
2045}
2046
Jeff Brown54bc2812010-06-15 01:31:58 -07002047void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002048#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -07002049 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07002050#endif
2051
Jeff Browna665ca82010-09-08 11:49:43 -07002052 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002053 { // acquire lock
2054 AutoMutex _l(mLock);
2055
Jeff Brown51d45a72010-06-17 20:52:56 -07002056 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browna665ca82010-09-08 11:49:43 -07002057 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002058 } // release lock
2059
Jeff Browna665ca82010-09-08 11:49:43 -07002060 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002061 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002062 }
2063}
2064
Jeff Brown5c1ed842010-07-14 18:48:53 -07002065void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -07002066 uint32_t policyFlags, int32_t action, int32_t flags,
2067 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2068#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002069 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07002070 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07002071 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -07002072 keyCode, scanCode, metaState, downTime);
2073#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002074 if (! validateKeyEvent(action)) {
2075 return;
2076 }
Jeff Browne839a582010-04-22 18:58:52 -07002077
Jeff Brown33d54ce2010-10-11 14:20:19 -07002078 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002079 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2080 keyCode, scanCode, /*byref*/ policyFlags);
2081
Jeff Browna665ca82010-09-08 11:49:43 -07002082 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002083 { // acquire lock
2084 AutoMutex _l(mLock);
2085
Jeff Brown51d45a72010-06-17 20:52:56 -07002086 int32_t repeatCount = 0;
2087 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002088 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07002089 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07002090
Jeff Browna665ca82010-09-08 11:49:43 -07002091 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002092 } // release lock
2093
Jeff Browna665ca82010-09-08 11:49:43 -07002094 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002095 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002096 }
2097}
2098
Jeff Brown5c1ed842010-07-14 18:48:53 -07002099void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002100 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002101 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2102 float xPrecision, float yPrecision, nsecs_t downTime) {
2103#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002104 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002105 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2106 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2107 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002108 xPrecision, yPrecision, downTime);
2109 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07002110 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002111 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07002112 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07002113 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-08-30 03:02:23 -07002114 pointerCoords[i].pressure, pointerCoords[i].size,
2115 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2116 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2117 pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -07002118 }
2119#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002120 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2121 return;
2122 }
Jeff Browne839a582010-04-22 18:58:52 -07002123
Jeff Brown33d54ce2010-10-11 14:20:19 -07002124 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002125 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2126
Jeff Browna665ca82010-09-08 11:49:43 -07002127 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002128 { // acquire lock
2129 AutoMutex _l(mLock);
2130
2131 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07002132 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07002133 // BATCHING CASE
2134 //
2135 // Try to append a move sample to the tail of the inbound queue for this device.
2136 // Give up if we encounter a non-move motion event for this device since that
2137 // means we cannot append any new samples until a new motion event has started.
Jeff Browna665ca82010-09-08 11:49:43 -07002138 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2139 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07002140 if (entry->type != EventEntry::TYPE_MOTION) {
2141 // Keep looking for motion events.
2142 continue;
2143 }
2144
2145 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2146 if (motionEntry->deviceId != deviceId) {
2147 // Keep looking for this device.
2148 continue;
2149 }
2150
Jeff Brown5c1ed842010-07-14 18:48:53 -07002151 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07002152 || motionEntry->pointerCount != pointerCount
2153 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07002154 // Last motion event in the queue for this device is not compatible for
2155 // appending new samples. Stop here.
2156 goto NoBatchingOrStreaming;
2157 }
2158
2159 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07002160 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07002161 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002162#if DEBUG_BATCHING
2163 LOGD("Appended motion sample onto batch for most recent "
2164 "motion event for this device in the inbound queue.");
2165#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07002166 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002167 }
2168
2169 // STREAMING CASE
2170 //
2171 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07002172 // Search the outbound queue for the current foreground targets to find a dispatched
2173 // motion event that is still in progress. If found, then, appen the new sample to
2174 // that event and push it out to all current targets. The logic in
2175 // prepareDispatchCycleLocked takes care of the case where some targets may
2176 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown54bc2812010-06-15 01:31:58 -07002177 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002178 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2179 const InputTarget& inputTarget = mCurrentInputTargets[i];
2180 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2181 // Skip non-foreground targets. We only want to stream if there is at
2182 // least one foreground target whose dispatch is still in progress.
2183 continue;
Jeff Browne839a582010-04-22 18:58:52 -07002184 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002185
2186 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2187 if (connectionIndex < 0) {
2188 // Connection must no longer be valid.
2189 continue;
2190 }
2191
2192 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2193 if (connection->outboundQueue.isEmpty()) {
2194 // This foreground target has an empty outbound queue.
2195 continue;
2196 }
2197
2198 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2199 if (! dispatchEntry->inProgress
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002200 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2201 || dispatchEntry->isSplit()) {
2202 // No motion event is being dispatched, or it is being split across
2203 // windows in which case we cannot stream.
Jeff Brown53a415e2010-09-15 15:18:56 -07002204 continue;
2205 }
2206
2207 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2208 dispatchEntry->eventEntry);
2209 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2210 || motionEntry->deviceId != deviceId
2211 || motionEntry->pointerCount != pointerCount
2212 || motionEntry->isInjected()) {
2213 // The motion event is not compatible with this move.
2214 continue;
2215 }
2216
2217 // Hurray! This foreground target is currently dispatching a move event
2218 // that we can stream onto. Append the motion sample and resume dispatch.
2219 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2220#if DEBUG_BATCHING
2221 LOGD("Appended motion sample onto batch for most recently dispatched "
2222 "motion event for this device in the outbound queues. "
2223 "Attempting to stream the motion sample.");
2224#endif
2225 nsecs_t currentTime = now();
2226 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2227 true /*resumeWithAppendedMotionSample*/);
2228
2229 runCommandsLockedInterruptible();
2230 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002231 }
2232 }
2233
2234NoBatchingOrStreaming:;
2235 }
2236
2237 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07002238 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002239 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002240 xPrecision, yPrecision, downTime,
2241 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002242
Jeff Browna665ca82010-09-08 11:49:43 -07002243 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002244 } // release lock
2245
Jeff Browna665ca82010-09-08 11:49:43 -07002246 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002247 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002248 }
2249}
2250
Jeff Brown90f0cee2010-10-08 22:31:17 -07002251void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2252 uint32_t policyFlags) {
2253#if DEBUG_INBOUND_EVENT_DETAILS
2254 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2255 switchCode, switchValue, policyFlags);
2256#endif
2257
Jeff Brown33d54ce2010-10-11 14:20:19 -07002258 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002259 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2260}
2261
Jeff Brown51d45a72010-06-17 20:52:56 -07002262int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07002263 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002264#if DEBUG_INBOUND_EVENT_DETAILS
2265 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002266 "syncMode=%d, timeoutMillis=%d",
2267 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07002268#endif
2269
2270 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brown33d54ce2010-10-11 14:20:19 -07002271
2272 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2273 if (hasInjectionPermission(injectorPid, injectorUid)) {
2274 policyFlags |= POLICY_FLAG_TRUSTED;
2275 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002276
Jeff Brown90f0cee2010-10-08 22:31:17 -07002277 EventEntry* injectedEntry;
2278 switch (event->getType()) {
2279 case AINPUT_EVENT_TYPE_KEY: {
2280 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2281 int32_t action = keyEvent->getAction();
2282 if (! validateKeyEvent(action)) {
Jeff Browna665ca82010-09-08 11:49:43 -07002283 return INPUT_EVENT_INJECTION_FAILED;
2284 }
2285
Jeff Brown90f0cee2010-10-08 22:31:17 -07002286 nsecs_t eventTime = keyEvent->getEventTime();
2287 int32_t deviceId = keyEvent->getDeviceId();
2288 int32_t flags = keyEvent->getFlags();
2289 int32_t keyCode = keyEvent->getKeyCode();
2290 int32_t scanCode = keyEvent->getScanCode();
Jeff Brown33d54ce2010-10-11 14:20:19 -07002291 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2292 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002293
Jeff Brown90f0cee2010-10-08 22:31:17 -07002294 mLock.lock();
2295 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2296 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2297 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2298 break;
2299 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002300
Jeff Brown90f0cee2010-10-08 22:31:17 -07002301 case AINPUT_EVENT_TYPE_MOTION: {
2302 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2303 int32_t action = motionEvent->getAction();
2304 size_t pointerCount = motionEvent->getPointerCount();
2305 const int32_t* pointerIds = motionEvent->getPointerIds();
2306 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2307 return INPUT_EVENT_INJECTION_FAILED;
2308 }
2309
2310 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown33d54ce2010-10-11 14:20:19 -07002311 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002312
2313 mLock.lock();
2314 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2315 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2316 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2317 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2318 action, motionEvent->getFlags(),
2319 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2320 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2321 motionEvent->getDownTime(), uint32_t(pointerCount),
2322 pointerIds, samplePointerCoords);
2323 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2324 sampleEventTimes += 1;
2325 samplePointerCoords += pointerCount;
2326 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2327 }
2328 injectedEntry = motionEntry;
2329 break;
2330 }
2331
2332 default:
2333 LOGW("Cannot inject event of type %d", event->getType());
2334 return INPUT_EVENT_INJECTION_FAILED;
2335 }
2336
2337 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2338 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2339 injectionState->injectionIsAsync = true;
2340 }
2341
2342 injectionState->refCount += 1;
2343 injectedEntry->injectionState = injectionState;
2344
2345 bool needWake = enqueueInboundEventLocked(injectedEntry);
2346 mLock.unlock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002347
Jeff Browna665ca82010-09-08 11:49:43 -07002348 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002349 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07002350 }
2351
2352 int32_t injectionResult;
2353 { // acquire lock
2354 AutoMutex _l(mLock);
2355
Jeff Brownf67c53e2010-07-28 15:48:59 -07002356 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2357 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2358 } else {
2359 for (;;) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002360 injectionResult = injectionState->injectionResult;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002361 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2362 break;
2363 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002364
Jeff Brown51d45a72010-06-17 20:52:56 -07002365 nsecs_t remainingTimeout = endTime - now();
2366 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002367#if DEBUG_INJECTION
2368 LOGD("injectInputEvent - Timed out waiting for injection result "
2369 "to become available.");
2370#endif
Jeff Brown51d45a72010-06-17 20:52:56 -07002371 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2372 break;
2373 }
2374
Jeff Brownf67c53e2010-07-28 15:48:59 -07002375 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2376 }
2377
2378 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2379 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002380 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002381#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002382 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002383 injectionState->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002384#endif
2385 nsecs_t remainingTimeout = endTime - now();
2386 if (remainingTimeout <= 0) {
2387#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002388 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002389 "dispatches to finish.");
2390#endif
2391 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2392 break;
2393 }
2394
2395 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2396 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002397 }
2398 }
2399
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002400 mAllocator.releaseInjectionState(injectionState);
Jeff Brown51d45a72010-06-17 20:52:56 -07002401 } // release lock
2402
Jeff Brownf67c53e2010-07-28 15:48:59 -07002403#if DEBUG_INJECTION
2404 LOGD("injectInputEvent - Finished with result %d. "
2405 "injectorPid=%d, injectorUid=%d",
2406 injectionResult, injectorPid, injectorUid);
2407#endif
2408
Jeff Brown51d45a72010-06-17 20:52:56 -07002409 return injectionResult;
2410}
2411
Jeff Brown90f0cee2010-10-08 22:31:17 -07002412bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2413 return injectorUid == 0
2414 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2415}
2416
Jeff Brown51d45a72010-06-17 20:52:56 -07002417void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002418 InjectionState* injectionState = entry->injectionState;
2419 if (injectionState) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002420#if DEBUG_INJECTION
2421 LOGD("Setting input event injection result to %d. "
2422 "injectorPid=%d, injectorUid=%d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002423 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002424#endif
2425
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002426 if (injectionState->injectionIsAsync) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002427 // Log the outcome since the injector did not wait for the injection result.
2428 switch (injectionResult) {
2429 case INPUT_EVENT_INJECTION_SUCCEEDED:
2430 LOGV("Asynchronous input event injection succeeded.");
2431 break;
2432 case INPUT_EVENT_INJECTION_FAILED:
2433 LOGW("Asynchronous input event injection failed.");
2434 break;
2435 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2436 LOGW("Asynchronous input event injection permission denied.");
2437 break;
2438 case INPUT_EVENT_INJECTION_TIMED_OUT:
2439 LOGW("Asynchronous input event injection timed out.");
2440 break;
2441 }
2442 }
2443
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002444 injectionState->injectionResult = injectionResult;
Jeff Brown51d45a72010-06-17 20:52:56 -07002445 mInjectionResultAvailableCondition.broadcast();
2446 }
2447}
2448
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002449void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2450 InjectionState* injectionState = entry->injectionState;
2451 if (injectionState) {
2452 injectionState->pendingForegroundDispatches += 1;
2453 }
2454}
2455
Jeff Brown53a415e2010-09-15 15:18:56 -07002456void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002457 InjectionState* injectionState = entry->injectionState;
2458 if (injectionState) {
2459 injectionState->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002460
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002461 if (injectionState->pendingForegroundDispatches == 0) {
2462 mInjectionSyncFinishedCondition.broadcast();
2463 }
Jeff Browna665ca82010-09-08 11:49:43 -07002464 }
2465}
2466
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002467const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2468 for (size_t i = 0; i < mWindows.size(); i++) {
2469 const InputWindow* window = & mWindows[i];
2470 if (window->inputChannel == inputChannel) {
2471 return window;
2472 }
2473 }
2474 return NULL;
2475}
2476
Jeff Browna665ca82010-09-08 11:49:43 -07002477void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2478#if DEBUG_FOCUS
2479 LOGD("setInputWindows");
2480#endif
2481 { // acquire lock
2482 AutoMutex _l(mLock);
2483
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002484 // Clear old window pointers.
Jeff Brown90f0cee2010-10-08 22:31:17 -07002485 sp<InputChannel> oldFocusedWindowChannel;
2486 if (mFocusedWindow) {
2487 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2488 mFocusedWindow = NULL;
2489 }
2490
Jeff Browna665ca82010-09-08 11:49:43 -07002491 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002492
2493 // Loop over new windows and rebuild the necessary window pointers for
2494 // tracking focus and touch.
Jeff Browna665ca82010-09-08 11:49:43 -07002495 mWindows.appendVector(inputWindows);
2496
2497 size_t numWindows = mWindows.size();
2498 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002499 const InputWindow* window = & mWindows.itemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07002500 if (window->hasFocus) {
2501 mFocusedWindow = window;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002502 break;
Jeff Browna665ca82010-09-08 11:49:43 -07002503 }
2504 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002505
Jeff Brown90f0cee2010-10-08 22:31:17 -07002506 if (oldFocusedWindowChannel != NULL) {
2507 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2508#if DEBUG_FOCUS
2509 LOGD("Focus left window: %s",
2510 oldFocusedWindowChannel->getName().string());
2511#endif
2512 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2513 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2514 oldFocusedWindowChannel.clear();
2515 }
2516 }
2517 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2518#if DEBUG_FOCUS
2519 LOGD("Focus entered window: %s",
2520 mFocusedWindow->inputChannel->getName().string());
2521#endif
2522 }
2523
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002524 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2525 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2526 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2527 if (window) {
2528 touchedWindow.window = window;
2529 i += 1;
2530 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -07002531#if DEBUG_FOCUS
2532 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2533#endif
Jeff Brown90f0cee2010-10-08 22:31:17 -07002534 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2535 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownb13d7b52010-10-15 16:20:51 -07002536 mTouchState.windows.removeAt(i);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002537 }
2538 }
Jeff Browna665ca82010-09-08 11:49:43 -07002539
Jeff Browna665ca82010-09-08 11:49:43 -07002540#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002541 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002542#endif
2543 } // release lock
2544
2545 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002546 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002547}
2548
2549void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2550#if DEBUG_FOCUS
2551 LOGD("setFocusedApplication");
2552#endif
2553 { // acquire lock
2554 AutoMutex _l(mLock);
2555
2556 releaseFocusedApplicationLocked();
2557
2558 if (inputApplication) {
2559 mFocusedApplicationStorage = *inputApplication;
2560 mFocusedApplication = & mFocusedApplicationStorage;
2561 }
2562
2563#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002564 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002565#endif
2566 } // release lock
2567
2568 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002569 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002570}
2571
2572void InputDispatcher::releaseFocusedApplicationLocked() {
2573 if (mFocusedApplication) {
2574 mFocusedApplication = NULL;
2575 mFocusedApplicationStorage.handle.clear();
2576 }
2577}
2578
2579void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2580#if DEBUG_FOCUS
2581 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2582#endif
2583
2584 bool changed;
2585 { // acquire lock
2586 AutoMutex _l(mLock);
2587
2588 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2589 if (mDispatchFrozen && ! frozen) {
2590 resetANRTimeoutsLocked();
2591 }
2592
2593 mDispatchEnabled = enabled;
2594 mDispatchFrozen = frozen;
2595 changed = true;
2596 } else {
2597 changed = false;
2598 }
2599
2600#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002601 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002602#endif
2603 } // release lock
2604
2605 if (changed) {
2606 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002607 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002608 }
2609}
2610
Jeff Brown744c5592010-09-27 14:52:15 -07002611bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2612 const sp<InputChannel>& toChannel) {
2613#if DEBUG_FOCUS
2614 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2615 fromChannel->getName().string(), toChannel->getName().string());
2616#endif
2617 { // acquire lock
2618 AutoMutex _l(mLock);
2619
2620 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2621 const InputWindow* toWindow = getWindowLocked(toChannel);
2622 if (! fromWindow || ! toWindow) {
2623#if DEBUG_FOCUS
2624 LOGD("Cannot transfer focus because from or to window not found.");
2625#endif
2626 return false;
2627 }
2628 if (fromWindow == toWindow) {
2629#if DEBUG_FOCUS
2630 LOGD("Trivial transfer to same window.");
2631#endif
2632 return true;
2633 }
2634
2635 bool found = false;
2636 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2637 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2638 if (touchedWindow.window == fromWindow) {
2639 int32_t oldTargetFlags = touchedWindow.targetFlags;
2640 BitSet32 pointerIds = touchedWindow.pointerIds;
2641
2642 mTouchState.windows.removeAt(i);
2643
2644 int32_t newTargetFlags = 0;
2645 if (oldTargetFlags & InputTarget::FLAG_FOREGROUND) {
2646 newTargetFlags |= InputTarget::FLAG_FOREGROUND;
2647 if (toWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) {
2648 newTargetFlags |= InputTarget::FLAG_SPLIT;
2649 }
2650 }
2651 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2652
2653 found = true;
2654 break;
2655 }
2656 }
2657
2658 if (! found) {
2659#if DEBUG_FOCUS
2660 LOGD("Focus transfer failed because from window did not have focus.");
2661#endif
2662 return false;
2663 }
2664
Jeff Brownb6702e52010-10-11 18:32:20 -07002665 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2666 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2667 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2668 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2669 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2670
2671 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2672 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2673 InputState::CANCEL_POINTER_EVENTS,
2674 "transferring touch focus from this window to another window");
2675 }
2676
Jeff Brown744c5592010-09-27 14:52:15 -07002677#if DEBUG_FOCUS
2678 logDispatchStateLocked();
2679#endif
2680 } // release lock
2681
2682 // Wake up poll loop since it may need to make new input dispatching choices.
2683 mLooper->wake();
2684 return true;
2685}
2686
Jeff Browna665ca82010-09-08 11:49:43 -07002687void InputDispatcher::logDispatchStateLocked() {
2688 String8 dump;
2689 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002690
2691 char* text = dump.lockBuffer(dump.size());
2692 char* start = text;
2693 while (*start != '\0') {
2694 char* end = strchr(start, '\n');
2695 if (*end == '\n') {
2696 *(end++) = '\0';
2697 }
2698 LOGD("%s", start);
2699 start = end;
2700 }
Jeff Browna665ca82010-09-08 11:49:43 -07002701}
2702
2703void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002704 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2705 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002706
2707 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002708 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002709 mFocusedApplication->name.string(),
2710 mFocusedApplication->dispatchingTimeout / 1000000.0);
2711 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002712 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002713 }
Jeff Brown2806e382010-10-01 17:46:21 -07002714 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002715 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-10-01 17:46:21 -07002716
2717 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2718 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2719 if (!mTouchState.windows.isEmpty()) {
2720 dump.append(INDENT "TouchedWindows:\n");
2721 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2722 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2723 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2724 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2725 touchedWindow.targetFlags);
2726 }
2727 } else {
2728 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002729 }
2730
Jeff Brown2806e382010-10-01 17:46:21 -07002731 if (!mWindows.isEmpty()) {
2732 dump.append(INDENT "Windows:\n");
2733 for (size_t i = 0; i < mWindows.size(); i++) {
2734 const InputWindow& window = mWindows[i];
2735 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2736 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2737 "frame=[%d,%d][%d,%d], "
2738 "visibleFrame=[%d,%d][%d,%d], "
2739 "touchableArea=[%d,%d][%d,%d], "
2740 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2741 i, window.name.string(),
2742 toString(window.paused),
2743 toString(window.hasFocus),
2744 toString(window.hasWallpaper),
2745 toString(window.visible),
2746 toString(window.canReceiveKeys),
2747 window.layoutParamsFlags, window.layoutParamsType,
2748 window.layer,
2749 window.frameLeft, window.frameTop,
2750 window.frameRight, window.frameBottom,
2751 window.visibleFrameLeft, window.visibleFrameTop,
2752 window.visibleFrameRight, window.visibleFrameBottom,
2753 window.touchableAreaLeft, window.touchableAreaTop,
2754 window.touchableAreaRight, window.touchableAreaBottom,
2755 window.ownerPid, window.ownerUid,
2756 window.dispatchingTimeout / 1000000.0);
2757 }
2758 } else {
2759 dump.append(INDENT "Windows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002760 }
2761
Jeff Brown2806e382010-10-01 17:46:21 -07002762 if (!mMonitoringChannels.isEmpty()) {
2763 dump.append(INDENT "MonitoringChannels:\n");
2764 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2765 const sp<InputChannel>& channel = mMonitoringChannels[i];
2766 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2767 }
2768 } else {
2769 dump.append(INDENT "MonitoringChannels: <none>\n");
2770 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002771
Jeff Brown2806e382010-10-01 17:46:21 -07002772 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2773
2774 if (!mActiveConnections.isEmpty()) {
2775 dump.append(INDENT "ActiveConnections:\n");
2776 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2777 const Connection* connection = mActiveConnections[i];
2778 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
Jeff Brown90f0cee2010-10-08 22:31:17 -07002779 "inputState.isNeutral=%s\n",
Jeff Brown2806e382010-10-01 17:46:21 -07002780 i, connection->getInputChannelName(), connection->getStatusLabel(),
2781 connection->outboundQueue.count(),
Jeff Brown90f0cee2010-10-08 22:31:17 -07002782 toString(connection->inputState.isNeutral()));
Jeff Brown2806e382010-10-01 17:46:21 -07002783 }
2784 } else {
2785 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002786 }
2787
2788 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002789 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002790 (mAppSwitchDueTime - now()) / 1000000.0);
2791 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002792 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002793 }
2794}
2795
2796status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002797#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002798 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2799 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002800#endif
2801
Jeff Browne839a582010-04-22 18:58:52 -07002802 { // acquire lock
2803 AutoMutex _l(mLock);
2804
Jeff Brown53a415e2010-09-15 15:18:56 -07002805 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002806 LOGW("Attempted to register already registered input channel '%s'",
2807 inputChannel->getName().string());
2808 return BAD_VALUE;
2809 }
2810
2811 sp<Connection> connection = new Connection(inputChannel);
2812 status_t status = connection->initialize();
2813 if (status) {
2814 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2815 inputChannel->getName().string(), status);
2816 return status;
2817 }
2818
Jeff Brown0cacb872010-08-17 15:59:26 -07002819 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002820 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002821
Jeff Browna665ca82010-09-08 11:49:43 -07002822 if (monitor) {
2823 mMonitoringChannels.push(inputChannel);
2824 }
2825
Jeff Brown59abe7e2010-09-13 23:17:30 -07002826 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002827
Jeff Brown54bc2812010-06-15 01:31:58 -07002828 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002829 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002830 return OK;
2831}
2832
2833status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002834#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002835 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002836#endif
2837
Jeff Browne839a582010-04-22 18:58:52 -07002838 { // acquire lock
2839 AutoMutex _l(mLock);
2840
Jeff Brown53a415e2010-09-15 15:18:56 -07002841 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002842 if (connectionIndex < 0) {
2843 LOGW("Attempted to unregister already unregistered input channel '%s'",
2844 inputChannel->getName().string());
2845 return BAD_VALUE;
2846 }
2847
2848 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2849 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2850
2851 connection->status = Connection::STATUS_ZOMBIE;
2852
Jeff Browna665ca82010-09-08 11:49:43 -07002853 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2854 if (mMonitoringChannels[i] == inputChannel) {
2855 mMonitoringChannels.removeAt(i);
2856 break;
2857 }
2858 }
2859
Jeff Brown59abe7e2010-09-13 23:17:30 -07002860 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002861
Jeff Brown51d45a72010-06-17 20:52:56 -07002862 nsecs_t currentTime = now();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002863 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002864
2865 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002866 } // release lock
2867
Jeff Browne839a582010-04-22 18:58:52 -07002868 // Wake the poll loop because removing the connection may have changed the current
2869 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002870 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002871 return OK;
2872}
2873
Jeff Brown53a415e2010-09-15 15:18:56 -07002874ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002875 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2876 if (connectionIndex >= 0) {
2877 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2878 if (connection->inputChannel.get() == inputChannel.get()) {
2879 return connectionIndex;
2880 }
2881 }
2882
2883 return -1;
2884}
2885
Jeff Browne839a582010-04-22 18:58:52 -07002886void InputDispatcher::activateConnectionLocked(Connection* connection) {
2887 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2888 if (mActiveConnections.itemAt(i) == connection) {
2889 return;
2890 }
2891 }
2892 mActiveConnections.add(connection);
2893}
2894
2895void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2896 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2897 if (mActiveConnections.itemAt(i) == connection) {
2898 mActiveConnections.removeAt(i);
2899 return;
2900 }
2901 }
2902}
2903
Jeff Brown54bc2812010-06-15 01:31:58 -07002904void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002905 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002906}
2907
Jeff Brown54bc2812010-06-15 01:31:58 -07002908void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002909 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002910}
2911
Jeff Brown54bc2812010-06-15 01:31:58 -07002912void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002913 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002914 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2915 connection->getInputChannelName());
2916
Jeff Brown54bc2812010-06-15 01:31:58 -07002917 CommandEntry* commandEntry = postCommandLocked(
2918 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002919 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002920}
2921
Jeff Brown53a415e2010-09-15 15:18:56 -07002922void InputDispatcher::onANRLocked(
2923 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2924 nsecs_t eventTime, nsecs_t waitStartTime) {
2925 LOGI("Application is not responding: %s. "
2926 "%01.1fms since event, %01.1fms since wait started",
2927 getApplicationWindowLabelLocked(application, window).string(),
2928 (currentTime - eventTime) / 1000000.0,
2929 (currentTime - waitStartTime) / 1000000.0);
2930
2931 CommandEntry* commandEntry = postCommandLocked(
2932 & InputDispatcher::doNotifyANRLockedInterruptible);
2933 if (application) {
2934 commandEntry->inputApplicationHandle = application->handle;
2935 }
2936 if (window) {
2937 commandEntry->inputChannel = window->inputChannel;
2938 }
2939}
2940
Jeff Browna665ca82010-09-08 11:49:43 -07002941void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2942 CommandEntry* commandEntry) {
2943 mLock.unlock();
2944
2945 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2946
2947 mLock.lock();
2948}
2949
Jeff Brown54bc2812010-06-15 01:31:58 -07002950void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2951 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002952 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002953
Jeff Brown51d45a72010-06-17 20:52:56 -07002954 if (connection->status != Connection::STATUS_ZOMBIE) {
2955 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002956
Jeff Brown51d45a72010-06-17 20:52:56 -07002957 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2958
2959 mLock.lock();
2960 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002961}
2962
Jeff Brown53a415e2010-09-15 15:18:56 -07002963void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002964 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002965 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002966
Jeff Brown53a415e2010-09-15 15:18:56 -07002967 nsecs_t newTimeout = mPolicy->notifyANR(
2968 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002969
Jeff Brown53a415e2010-09-15 15:18:56 -07002970 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002971
Jeff Brown53a415e2010-09-15 15:18:56 -07002972 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002973}
2974
Jeff Browna665ca82010-09-08 11:49:43 -07002975void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2976 CommandEntry* commandEntry) {
2977 KeyEntry* entry = commandEntry->keyEntry;
2978 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2979 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2980 entry->downTime, entry->eventTime);
2981
2982 mLock.unlock();
2983
2984 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2985 & mReusableKeyEvent, entry->policyFlags);
2986
2987 mLock.lock();
2988
2989 entry->interceptKeyResult = consumed
2990 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2991 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2992 mAllocator.releaseKeyEntry(entry);
2993}
2994
2995void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2996 mLock.unlock();
2997
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002998 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07002999
3000 mLock.lock();
3001}
3002
Jeff Brown53a415e2010-09-15 15:18:56 -07003003void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3004 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3005 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07003006}
3007
3008void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07003009 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07003010 dumpDispatchStateLocked(dump);
3011}
3012
Jeff Brown54bc2812010-06-15 01:31:58 -07003013
Jeff Brown53a415e2010-09-15 15:18:56 -07003014// --- InputDispatcher::Queue ---
3015
3016template <typename T>
3017uint32_t InputDispatcher::Queue<T>::count() const {
3018 uint32_t result = 0;
3019 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3020 result += 1;
3021 }
3022 return result;
3023}
3024
3025
Jeff Browne839a582010-04-22 18:58:52 -07003026// --- InputDispatcher::Allocator ---
3027
3028InputDispatcher::Allocator::Allocator() {
3029}
3030
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003031InputDispatcher::InjectionState*
3032InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3033 InjectionState* injectionState = mInjectionStatePool.alloc();
3034 injectionState->refCount = 1;
3035 injectionState->injectorPid = injectorPid;
3036 injectionState->injectorUid = injectorUid;
3037 injectionState->injectionIsAsync = false;
3038 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3039 injectionState->pendingForegroundDispatches = 0;
3040 return injectionState;
3041}
3042
Jeff Brown51d45a72010-06-17 20:52:56 -07003043void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brown90f0cee2010-10-08 22:31:17 -07003044 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown51d45a72010-06-17 20:52:56 -07003045 entry->type = type;
3046 entry->refCount = 1;
3047 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07003048 entry->eventTime = eventTime;
Jeff Brown90f0cee2010-10-08 22:31:17 -07003049 entry->policyFlags = policyFlags;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003050 entry->injectionState = NULL;
3051}
3052
3053void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3054 if (entry->injectionState) {
3055 releaseInjectionState(entry->injectionState);
3056 entry->injectionState = NULL;
3057 }
Jeff Brown51d45a72010-06-17 20:52:56 -07003058}
3059
Jeff Browne839a582010-04-22 18:58:52 -07003060InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07003061InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003062 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003063 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Browne839a582010-04-22 18:58:52 -07003064 return entry;
3065}
3066
Jeff Brown51d45a72010-06-17 20:52:56 -07003067InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07003068 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07003069 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3070 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003071 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003072 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003073
3074 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003075 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003076 entry->action = action;
3077 entry->flags = flags;
3078 entry->keyCode = keyCode;
3079 entry->scanCode = scanCode;
3080 entry->metaState = metaState;
3081 entry->repeatCount = repeatCount;
3082 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07003083 entry->syntheticRepeat = false;
3084 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07003085 return entry;
3086}
3087
Jeff Brown51d45a72010-06-17 20:52:56 -07003088InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07003089 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07003090 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3091 nsecs_t downTime, uint32_t pointerCount,
3092 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003093 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003094 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003095
3096 entry->eventTime = eventTime;
3097 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003098 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003099 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07003100 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07003101 entry->metaState = metaState;
3102 entry->edgeFlags = edgeFlags;
3103 entry->xPrecision = xPrecision;
3104 entry->yPrecision = yPrecision;
3105 entry->downTime = downTime;
3106 entry->pointerCount = pointerCount;
3107 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07003108 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07003109 entry->lastSample = & entry->firstSample;
3110 for (uint32_t i = 0; i < pointerCount; i++) {
3111 entry->pointerIds[i] = pointerIds[i];
3112 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3113 }
Jeff Browne839a582010-04-22 18:58:52 -07003114 return entry;
3115}
3116
3117InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07003118 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07003119 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07003120 DispatchEntry* entry = mDispatchEntryPool.alloc();
3121 entry->eventEntry = eventEntry;
3122 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07003123 entry->targetFlags = targetFlags;
3124 entry->xOffset = xOffset;
3125 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07003126 entry->inProgress = false;
3127 entry->headMotionSample = NULL;
3128 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07003129 return entry;
3130}
3131
Jeff Brown54bc2812010-06-15 01:31:58 -07003132InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3133 CommandEntry* entry = mCommandEntryPool.alloc();
3134 entry->command = command;
3135 return entry;
3136}
3137
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003138void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3139 injectionState->refCount -= 1;
3140 if (injectionState->refCount == 0) {
3141 mInjectionStatePool.free(injectionState);
3142 } else {
3143 assert(injectionState->refCount > 0);
3144 }
3145}
3146
Jeff Browne839a582010-04-22 18:58:52 -07003147void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3148 switch (entry->type) {
3149 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3150 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3151 break;
3152 case EventEntry::TYPE_KEY:
3153 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3154 break;
3155 case EventEntry::TYPE_MOTION:
3156 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3157 break;
3158 default:
3159 assert(false);
3160 break;
3161 }
3162}
3163
3164void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3165 ConfigurationChangedEntry* entry) {
3166 entry->refCount -= 1;
3167 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003168 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003169 mConfigurationChangeEntryPool.free(entry);
3170 } else {
3171 assert(entry->refCount > 0);
3172 }
3173}
3174
3175void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3176 entry->refCount -= 1;
3177 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003178 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003179 mKeyEntryPool.free(entry);
3180 } else {
3181 assert(entry->refCount > 0);
3182 }
3183}
3184
3185void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3186 entry->refCount -= 1;
3187 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003188 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -07003189 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3190 MotionSample* next = sample->next;
3191 mMotionSamplePool.free(sample);
3192 sample = next;
3193 }
Jeff Browne839a582010-04-22 18:58:52 -07003194 mMotionEntryPool.free(entry);
3195 } else {
3196 assert(entry->refCount > 0);
3197 }
3198}
3199
3200void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3201 releaseEventEntry(entry->eventEntry);
3202 mDispatchEntryPool.free(entry);
3203}
3204
Jeff Brown54bc2812010-06-15 01:31:58 -07003205void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3206 mCommandEntryPool.free(entry);
3207}
3208
Jeff Browne839a582010-04-22 18:58:52 -07003209void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003210 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003211 MotionSample* sample = mMotionSamplePool.alloc();
3212 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003213 uint32_t pointerCount = motionEntry->pointerCount;
3214 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07003215 sample->pointerCoords[i] = pointerCoords[i];
3216 }
3217
3218 sample->next = NULL;
3219 motionEntry->lastSample->next = sample;
3220 motionEntry->lastSample = sample;
3221}
3222
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003223void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3224 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003225
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003226 keyEntry->dispatchInProgress = false;
3227 keyEntry->syntheticRepeat = false;
3228 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003229}
3230
3231
Jeff Brown542412c2010-08-18 15:51:08 -07003232// --- InputDispatcher::MotionEntry ---
3233
3234uint32_t InputDispatcher::MotionEntry::countSamples() const {
3235 uint32_t count = 1;
3236 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3237 count += 1;
3238 }
3239 return count;
3240}
3241
Jeff Browna665ca82010-09-08 11:49:43 -07003242
3243// --- InputDispatcher::InputState ---
3244
Jeff Brown90f0cee2010-10-08 22:31:17 -07003245InputDispatcher::InputState::InputState() {
Jeff Browna665ca82010-09-08 11:49:43 -07003246}
3247
3248InputDispatcher::InputState::~InputState() {
3249}
3250
3251bool InputDispatcher::InputState::isNeutral() const {
3252 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3253}
3254
Jeff Browna665ca82010-09-08 11:49:43 -07003255InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3256 const EventEntry* entry) {
3257 switch (entry->type) {
3258 case EventEntry::TYPE_KEY:
3259 return trackKey(static_cast<const KeyEntry*>(entry));
3260
3261 case EventEntry::TYPE_MOTION:
3262 return trackMotion(static_cast<const MotionEntry*>(entry));
3263
3264 default:
3265 return CONSISTENT;
3266 }
3267}
3268
3269InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3270 const KeyEntry* entry) {
3271 int32_t action = entry->action;
3272 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3273 KeyMemento& memento = mKeyMementos.editItemAt(i);
3274 if (memento.deviceId == entry->deviceId
3275 && memento.source == entry->source
3276 && memento.keyCode == entry->keyCode
3277 && memento.scanCode == entry->scanCode) {
3278 switch (action) {
3279 case AKEY_EVENT_ACTION_UP:
3280 mKeyMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003281 return CONSISTENT;
3282
3283 case AKEY_EVENT_ACTION_DOWN:
3284 return TOLERABLE;
3285
3286 default:
3287 return BROKEN;
3288 }
3289 }
3290 }
3291
3292 switch (action) {
3293 case AKEY_EVENT_ACTION_DOWN: {
3294 mKeyMementos.push();
3295 KeyMemento& memento = mKeyMementos.editTop();
3296 memento.deviceId = entry->deviceId;
3297 memento.source = entry->source;
3298 memento.keyCode = entry->keyCode;
3299 memento.scanCode = entry->scanCode;
3300 memento.downTime = entry->downTime;
3301 return CONSISTENT;
3302 }
3303
3304 default:
3305 return BROKEN;
3306 }
3307}
3308
3309InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3310 const MotionEntry* entry) {
3311 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3312 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3313 MotionMemento& memento = mMotionMementos.editItemAt(i);
3314 if (memento.deviceId == entry->deviceId
3315 && memento.source == entry->source) {
3316 switch (action) {
3317 case AMOTION_EVENT_ACTION_UP:
3318 case AMOTION_EVENT_ACTION_CANCEL:
3319 mMotionMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003320 return CONSISTENT;
3321
3322 case AMOTION_EVENT_ACTION_DOWN:
3323 return TOLERABLE;
3324
3325 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3326 if (entry->pointerCount == memento.pointerCount + 1) {
3327 memento.setPointers(entry);
3328 return CONSISTENT;
3329 }
3330 return BROKEN;
3331
3332 case AMOTION_EVENT_ACTION_POINTER_UP:
3333 if (entry->pointerCount == memento.pointerCount - 1) {
3334 memento.setPointers(entry);
3335 return CONSISTENT;
3336 }
3337 return BROKEN;
3338
3339 case AMOTION_EVENT_ACTION_MOVE:
3340 if (entry->pointerCount == memento.pointerCount) {
3341 return CONSISTENT;
3342 }
3343 return BROKEN;
3344
3345 default:
3346 return BROKEN;
3347 }
3348 }
3349 }
3350
3351 switch (action) {
3352 case AMOTION_EVENT_ACTION_DOWN: {
3353 mMotionMementos.push();
3354 MotionMemento& memento = mMotionMementos.editTop();
3355 memento.deviceId = entry->deviceId;
3356 memento.source = entry->source;
3357 memento.xPrecision = entry->xPrecision;
3358 memento.yPrecision = entry->yPrecision;
3359 memento.downTime = entry->downTime;
3360 memento.setPointers(entry);
3361 return CONSISTENT;
3362 }
3363
3364 default:
3365 return BROKEN;
3366 }
3367}
3368
3369void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3370 pointerCount = entry->pointerCount;
3371 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3372 pointerIds[i] = entry->pointerIds[i];
3373 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3374 }
3375}
3376
Jeff Brown90f0cee2010-10-08 22:31:17 -07003377void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3378 Allocator* allocator, Vector<EventEntry*>& outEvents,
3379 CancelationOptions options) {
3380 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003381 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003382 if (shouldCancelEvent(memento.source, options)) {
3383 outEvents.push(allocator->obtainKeyEntry(currentTime,
3384 memento.deviceId, memento.source, 0,
3385 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3386 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3387 mKeyMementos.removeAt(i);
3388 } else {
3389 i += 1;
3390 }
Jeff Browna665ca82010-09-08 11:49:43 -07003391 }
3392
Jeff Brown316237d2010-10-11 18:22:53 -07003393 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003394 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003395 if (shouldCancelEvent(memento.source, options)) {
3396 outEvents.push(allocator->obtainMotionEntry(currentTime,
3397 memento.deviceId, memento.source, 0,
3398 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3399 memento.xPrecision, memento.yPrecision, memento.downTime,
3400 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3401 mMotionMementos.removeAt(i);
3402 } else {
3403 i += 1;
3404 }
Jeff Browna665ca82010-09-08 11:49:43 -07003405 }
3406}
3407
3408void InputDispatcher::InputState::clear() {
3409 mKeyMementos.clear();
3410 mMotionMementos.clear();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003411}
3412
Jeff Brownb6702e52010-10-11 18:32:20 -07003413void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3414 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3415 const MotionMemento& memento = mMotionMementos.itemAt(i);
3416 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3417 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3418 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3419 if (memento.deviceId == otherMemento.deviceId
3420 && memento.source == otherMemento.source) {
3421 other.mMotionMementos.removeAt(j);
3422 } else {
3423 j += 1;
3424 }
3425 }
3426 other.mMotionMementos.push(memento);
3427 }
3428 }
3429}
3430
Jeff Brown90f0cee2010-10-08 22:31:17 -07003431bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3432 CancelationOptions options) {
3433 switch (options) {
3434 case CANCEL_POINTER_EVENTS:
3435 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3436 case CANCEL_NON_POINTER_EVENTS:
3437 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3438 default:
3439 return true;
3440 }
Jeff Browna665ca82010-09-08 11:49:43 -07003441}
3442
3443
Jeff Browne839a582010-04-22 18:58:52 -07003444// --- InputDispatcher::Connection ---
3445
3446InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3447 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003448 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003449}
3450
3451InputDispatcher::Connection::~Connection() {
3452}
3453
3454status_t InputDispatcher::Connection::initialize() {
3455 return inputPublisher.initialize();
3456}
3457
Jeff Brown54bc2812010-06-15 01:31:58 -07003458const char* InputDispatcher::Connection::getStatusLabel() const {
3459 switch (status) {
3460 case STATUS_NORMAL:
3461 return "NORMAL";
3462
3463 case STATUS_BROKEN:
3464 return "BROKEN";
3465
Jeff Brown54bc2812010-06-15 01:31:58 -07003466 case STATUS_ZOMBIE:
3467 return "ZOMBIE";
3468
3469 default:
3470 return "UNKNOWN";
3471 }
3472}
3473
Jeff Browne839a582010-04-22 18:58:52 -07003474InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3475 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003476 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3477 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003478 if (dispatchEntry->eventEntry == eventEntry) {
3479 return dispatchEntry;
3480 }
3481 }
3482 return NULL;
3483}
3484
Jeff Browna665ca82010-09-08 11:49:43 -07003485
Jeff Brown54bc2812010-06-15 01:31:58 -07003486// --- InputDispatcher::CommandEntry ---
3487
Jeff Browna665ca82010-09-08 11:49:43 -07003488InputDispatcher::CommandEntry::CommandEntry() :
3489 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003490}
3491
3492InputDispatcher::CommandEntry::~CommandEntry() {
3493}
3494
Jeff Browne839a582010-04-22 18:58:52 -07003495
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003496// --- InputDispatcher::TouchState ---
3497
3498InputDispatcher::TouchState::TouchState() :
3499 down(false), split(false) {
3500}
3501
3502InputDispatcher::TouchState::~TouchState() {
3503}
3504
3505void InputDispatcher::TouchState::reset() {
3506 down = false;
3507 split = false;
3508 windows.clear();
3509}
3510
3511void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3512 down = other.down;
3513 split = other.split;
3514 windows.clear();
3515 windows.appendVector(other.windows);
3516}
3517
3518void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3519 int32_t targetFlags, BitSet32 pointerIds) {
3520 if (targetFlags & InputTarget::FLAG_SPLIT) {
3521 split = true;
3522 }
3523
3524 for (size_t i = 0; i < windows.size(); i++) {
3525 TouchedWindow& touchedWindow = windows.editItemAt(i);
3526 if (touchedWindow.window == window) {
3527 touchedWindow.targetFlags |= targetFlags;
3528 touchedWindow.pointerIds.value |= pointerIds.value;
3529 return;
3530 }
3531 }
3532
3533 windows.push();
3534
3535 TouchedWindow& touchedWindow = windows.editTop();
3536 touchedWindow.window = window;
3537 touchedWindow.targetFlags = targetFlags;
3538 touchedWindow.pointerIds = pointerIds;
3539 touchedWindow.channel = window->inputChannel;
3540}
3541
3542void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3543 for (size_t i = 0 ; i < windows.size(); ) {
3544 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3545 windows.removeAt(i);
3546 } else {
3547 i += 1;
3548 }
3549 }
3550}
3551
3552const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3553 for (size_t i = 0; i < windows.size(); i++) {
3554 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3555 return windows[i].window;
3556 }
3557 }
3558 return NULL;
3559}
3560
3561
Jeff Browne839a582010-04-22 18:58:52 -07003562// --- InputDispatcherThread ---
3563
3564InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3565 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3566}
3567
3568InputDispatcherThread::~InputDispatcherThread() {
3569}
3570
3571bool InputDispatcherThread::threadLoop() {
3572 mDispatcher->dispatchOnce();
3573 return true;
3574}
3575
3576} // namespace android