blob: 4c86ebe0f5e11cc4fcad390f8150c85260b78662 [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 Brown53f291e2010-10-25 17:37:46 -07001166#if DEBUG_INPUT_DISPATCHER_POLICY
1167 LOGD("Dropping event because the pointer is not down or we previously "
1168 "dropped the pointer down event.");
1169#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001170 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001171 goto Failed;
1172 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001173 }
Jeff Browna665ca82010-09-08 11:49:43 -07001174
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001175 // Check permission to inject into all touched foreground windows and ensure there
1176 // is at least one touched foreground window.
1177 {
1178 bool haveForegroundWindow = false;
1179 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1180 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1181 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1182 haveForegroundWindow = true;
1183 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1184 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1185 injectionPermission = INJECTION_PERMISSION_DENIED;
1186 goto Failed;
1187 }
1188 }
1189 }
1190 if (! haveForegroundWindow) {
Jeff Browna665ca82010-09-08 11:49:43 -07001191#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001192 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Browna665ca82010-09-08 11:49:43 -07001193#endif
1194 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001195 goto Failed;
1196 }
1197
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001198 // Permission granted to injection into all touched foreground windows.
1199 injectionPermission = INJECTION_PERMISSION_GRANTED;
1200 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001201
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001202 // Ensure all touched foreground windows are ready for new input.
1203 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1204 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1205 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1206 // If the touched window is paused then keep waiting.
1207 if (touchedWindow.window->paused) {
1208#if DEBUG_INPUT_DISPATCHER_POLICY
1209 LOGD("Waiting because touched window is paused.");
Jeff Brown53a415e2010-09-15 15:18:56 -07001210#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001211 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1212 NULL, touchedWindow.window, nextWakeupTime);
1213 goto Unresponsive;
1214 }
1215
1216 // If the touched window is still working on previous events then keep waiting.
1217 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1218#if DEBUG_FOCUS
1219 LOGD("Waiting because touched window still processing previous input.");
1220#endif
1221 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1222 NULL, touchedWindow.window, nextWakeupTime);
1223 goto Unresponsive;
1224 }
1225 }
1226 }
1227
1228 // If this is the first pointer going down and the touched window has a wallpaper
1229 // then also add the touched wallpaper windows so they are locked in for the duration
1230 // of the touch gesture.
1231 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1232 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1233 if (foregroundWindow->hasWallpaper) {
1234 for (size_t i = 0; i < mWindows.size(); i++) {
1235 const InputWindow* window = & mWindows[i];
1236 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001237 mTempTouchState.addOrUpdateWindow(window,
1238 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001239 }
1240 }
1241 }
1242 }
1243
Jeff Browna665ca82010-09-08 11:49:43 -07001244 // Success! Output targets.
1245 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Browna665ca82010-09-08 11:49:43 -07001246
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001247 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1248 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1249 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1250 touchedWindow.pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001251 }
1252
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001253 // Drop the outside touch window since we will not care about them in the next iteration.
1254 mTempTouchState.removeOutsideTouchWindows();
1255
Jeff Browna665ca82010-09-08 11:49:43 -07001256Failed:
1257 // Check injection permission once and for all.
1258 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001259 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001260 injectionPermission = INJECTION_PERMISSION_GRANTED;
1261 } else {
1262 injectionPermission = INJECTION_PERMISSION_DENIED;
1263 }
1264 }
1265
1266 // Update final pieces of touch state if the injector had permission.
1267 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001268 if (maskedAction == AMOTION_EVENT_ACTION_UP
1269 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1270 // All pointers up or canceled.
1271 mTempTouchState.reset();
1272 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1273 // First pointer went down.
1274 if (mTouchState.down) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001275#if DEBUG_FOCUS
1276 LOGD("Pointer down received while already down.");
1277#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001278 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001279 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1280 // One pointer went up.
1281 if (isSplit) {
1282 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1283 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Browna665ca82010-09-08 11:49:43 -07001284
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001285 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1286 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1287 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1288 touchedWindow.pointerIds.clearBit(pointerId);
1289 if (touchedWindow.pointerIds.isEmpty()) {
1290 mTempTouchState.windows.removeAt(i);
1291 continue;
1292 }
1293 }
1294 i += 1;
1295 }
Jeff Browna665ca82010-09-08 11:49:43 -07001296 }
Jeff Browna665ca82010-09-08 11:49:43 -07001297 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001298
1299 // Save changes to touch state.
1300 mTouchState.copyFrom(mTempTouchState);
Jeff Browna665ca82010-09-08 11:49:43 -07001301 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001302#if DEBUG_FOCUS
1303 LOGD("Not updating touch focus because injection was denied.");
1304#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001305 }
1306
1307Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -07001308 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1309 updateDispatchStatisticsLocked(currentTime, entry,
1310 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001311#if DEBUG_FOCUS
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001312 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1313 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown53a415e2010-09-15 15:18:56 -07001314 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001315#endif
1316 return injectionResult;
1317}
1318
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001319void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1320 BitSet32 pointerIds) {
Jeff Browna665ca82010-09-08 11:49:43 -07001321 mCurrentInputTargets.push();
1322
1323 InputTarget& target = mCurrentInputTargets.editTop();
1324 target.inputChannel = window->inputChannel;
1325 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001326 target.xOffset = - window->frameLeft;
1327 target.yOffset = - window->frameTop;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001328 target.pointerIds = pointerIds;
Jeff Browna665ca82010-09-08 11:49:43 -07001329}
1330
1331void InputDispatcher::addMonitoringTargetsLocked() {
1332 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1333 mCurrentInputTargets.push();
1334
1335 InputTarget& target = mCurrentInputTargets.editTop();
1336 target.inputChannel = mMonitoringChannels[i];
1337 target.flags = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07001338 target.xOffset = 0;
1339 target.yOffset = 0;
1340 }
1341}
1342
1343bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001344 const InjectionState* injectionState) {
1345 if (injectionState
Jeff Brown90f0cee2010-10-08 22:31:17 -07001346 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1347 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1348 if (window) {
1349 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1350 "with input channel %s owned by uid %d",
1351 injectionState->injectorPid, injectionState->injectorUid,
1352 window->inputChannel->getName().string(),
1353 window->ownerUid);
1354 } else {
1355 LOGW("Permission denied: injecting event from pid %d uid %d",
1356 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-09-08 11:49:43 -07001357 }
Jeff Brown90f0cee2010-10-08 22:31:17 -07001358 return false;
Jeff Browna665ca82010-09-08 11:49:43 -07001359 }
1360 return true;
1361}
1362
Jeff Brown35cf0e92010-10-05 12:26:23 -07001363bool InputDispatcher::isWindowObscuredAtPointLocked(
1364 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Browna665ca82010-09-08 11:49:43 -07001365 size_t numWindows = mWindows.size();
1366 for (size_t i = 0; i < numWindows; i++) {
1367 const InputWindow* other = & mWindows.itemAt(i);
1368 if (other == window) {
1369 break;
1370 }
Jeff Brown35cf0e92010-10-05 12:26:23 -07001371 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001372 return true;
1373 }
1374 }
1375 return false;
1376}
1377
Jeff Brown53a415e2010-09-15 15:18:56 -07001378bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1379 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1380 if (connectionIndex >= 0) {
1381 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1382 return connection->outboundQueue.isEmpty();
1383 } else {
1384 return true;
1385 }
1386}
1387
1388String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1389 const InputWindow* window) {
1390 if (application) {
1391 if (window) {
1392 String8 label(application->name);
1393 label.append(" - ");
1394 label.append(window->name);
1395 return label;
1396 } else {
1397 return application->name;
1398 }
1399 } else if (window) {
1400 return window->name;
1401 } else {
1402 return String8("<unknown application or window>");
1403 }
1404}
1405
Jeff Brownef3a8232010-10-18 13:21:23 -07001406void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1407 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
1408 if (eventEntry->type == EventEntry::TYPE_MOTION) {
1409 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
1410 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1411 switch (motionEntry->action) {
1412 case AMOTION_EVENT_ACTION_DOWN:
1413 eventType = POWER_MANAGER_TOUCH_EVENT;
1414 break;
1415 case AMOTION_EVENT_ACTION_UP:
1416 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
1417 break;
1418 default:
1419 if (motionEntry->eventTime - motionEntry->downTime >= EVENT_IGNORE_DURATION) {
1420 eventType = POWER_MANAGER_TOUCH_EVENT;
1421 } else {
1422 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
1423 }
1424 break;
1425 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001426 }
1427 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001428
Jeff Browna665ca82010-09-08 11:49:43 -07001429 CommandEntry* commandEntry = postCommandLocked(
1430 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Brownef3a8232010-10-18 13:21:23 -07001431 commandEntry->eventTime = eventEntry->eventTime;
Jeff Browna665ca82010-09-08 11:49:43 -07001432 commandEntry->userActivityEventType = eventType;
1433}
1434
Jeff Brown51d45a72010-06-17 20:52:56 -07001435void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1436 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -07001437 bool resumeWithAppendedMotionSample) {
1438#if DEBUG_DISPATCH_CYCLE
Jeff Brown53a415e2010-09-15 15:18:56 -07001439 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001440 "xOffset=%f, yOffset=%f, "
1441 "windowType=%d, pointerIds=0x%x, "
1442 "resumeWithAppendedMotionSample=%s",
Jeff Brown53a415e2010-09-15 15:18:56 -07001443 connection->getInputChannelName(), inputTarget->flags,
Jeff Browne839a582010-04-22 18:58:52 -07001444 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001445 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Browna665ca82010-09-08 11:49:43 -07001446 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -07001447#endif
1448
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001449 // Make sure we are never called for streaming when splitting across multiple windows.
1450 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1451 assert(! (resumeWithAppendedMotionSample && isSplit));
1452
Jeff Browne839a582010-04-22 18:58:52 -07001453 // Skip this event if the connection status is not normal.
Jeff Brown53a415e2010-09-15 15:18:56 -07001454 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Browne839a582010-04-22 18:58:52 -07001455 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001456#if DEBUG_DISPATCH_CYCLE
1457 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Browna665ca82010-09-08 11:49:43 -07001458 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown90f0cee2010-10-08 22:31:17 -07001459#endif
Jeff Browne839a582010-04-22 18:58:52 -07001460 return;
1461 }
1462
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001463 // Split a motion event if needed.
1464 if (isSplit) {
1465 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1466
1467 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1468 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1469 MotionEntry* splitMotionEntry = splitMotionEvent(
1470 originalMotionEntry, inputTarget->pointerIds);
1471#if DEBUG_FOCUS
1472 LOGD("channel '%s' ~ Split motion event.",
1473 connection->getInputChannelName());
1474 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1475#endif
1476 eventEntry = splitMotionEntry;
1477 }
1478 }
1479
Jeff Browne839a582010-04-22 18:58:52 -07001480 // Resume the dispatch cycle with a freshly appended motion sample.
1481 // First we check that the last dispatch entry in the outbound queue is for the same
1482 // motion event to which we appended the motion sample. If we find such a dispatch
1483 // entry, and if it is currently in progress then we try to stream the new sample.
1484 bool wasEmpty = connection->outboundQueue.isEmpty();
1485
1486 if (! wasEmpty && resumeWithAppendedMotionSample) {
1487 DispatchEntry* motionEventDispatchEntry =
1488 connection->findQueuedDispatchEntryForEvent(eventEntry);
1489 if (motionEventDispatchEntry) {
1490 // If the dispatch entry is not in progress, then we must be busy dispatching an
1491 // earlier event. Not a problem, the motion event is on the outbound queue and will
1492 // be dispatched later.
1493 if (! motionEventDispatchEntry->inProgress) {
1494#if DEBUG_BATCHING
1495 LOGD("channel '%s' ~ Not streaming because the motion event has "
1496 "not yet been dispatched. "
1497 "(Waiting for earlier events to be consumed.)",
1498 connection->getInputChannelName());
1499#endif
1500 return;
1501 }
1502
1503 // If the dispatch entry is in progress but it already has a tail of pending
1504 // motion samples, then it must mean that the shared memory buffer filled up.
1505 // Not a problem, when this dispatch cycle is finished, we will eventually start
1506 // a new dispatch cycle to process the tail and that tail includes the newly
1507 // appended motion sample.
1508 if (motionEventDispatchEntry->tailMotionSample) {
1509#if DEBUG_BATCHING
1510 LOGD("channel '%s' ~ Not streaming because no new samples can "
1511 "be appended to the motion event in this dispatch cycle. "
1512 "(Waiting for next dispatch cycle to start.)",
1513 connection->getInputChannelName());
1514#endif
1515 return;
1516 }
1517
1518 // The dispatch entry is in progress and is still potentially open for streaming.
1519 // Try to stream the new motion sample. This might fail if the consumer has already
1520 // consumed the motion event (or if the channel is broken).
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001521 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1522 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Browne839a582010-04-22 18:58:52 -07001523 status_t status = connection->inputPublisher.appendMotionSample(
1524 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1525 if (status == OK) {
1526#if DEBUG_BATCHING
1527 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1528 connection->getInputChannelName());
1529#endif
1530 return;
1531 }
1532
1533#if DEBUG_BATCHING
1534 if (status == NO_MEMORY) {
1535 LOGD("channel '%s' ~ Could not append motion sample to currently "
1536 "dispatched move event because the shared memory buffer is full. "
1537 "(Waiting for next dispatch cycle to start.)",
1538 connection->getInputChannelName());
1539 } else if (status == status_t(FAILED_TRANSACTION)) {
1540 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown50de30a2010-06-22 01:27:15 -07001541 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-04-22 18:58:52 -07001542 "(Waiting for next dispatch cycle to start.)",
1543 connection->getInputChannelName());
1544 } else {
1545 LOGD("channel '%s' ~ Could not append motion sample to currently "
1546 "dispatched move event due to an error, status=%d. "
1547 "(Waiting for next dispatch cycle to start.)",
1548 connection->getInputChannelName(), status);
1549 }
1550#endif
1551 // Failed to stream. Start a new tail of pending motion samples to dispatch
1552 // in the next cycle.
1553 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1554 return;
1555 }
1556 }
1557
1558 // This is a new event.
1559 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Browna665ca82010-09-08 11:49:43 -07001560 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown53a415e2010-09-15 15:18:56 -07001561 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1562 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001563 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001564 }
1565
Jeff Browne839a582010-04-22 18:58:52 -07001566 // Handle the case where we could not stream a new motion sample because the consumer has
1567 // already consumed the motion event (otherwise the corresponding dispatch entry would
1568 // still be in the outbound queue for this connection). We set the head motion sample
1569 // to the list starting with the newly appended motion sample.
1570 if (resumeWithAppendedMotionSample) {
1571#if DEBUG_BATCHING
1572 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1573 "that cannot be streamed because the motion event has already been consumed.",
1574 connection->getInputChannelName());
1575#endif
1576 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1577 dispatchEntry->headMotionSample = appendedMotionSample;
1578 }
1579
1580 // Enqueue the dispatch entry.
1581 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1582
1583 // If the outbound queue was previously empty, start the dispatch cycle going.
1584 if (wasEmpty) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001585 activateConnectionLocked(connection.get());
Jeff Brown53a415e2010-09-15 15:18:56 -07001586 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001587 }
1588}
1589
Jeff Brown51d45a72010-06-17 20:52:56 -07001590void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown53a415e2010-09-15 15:18:56 -07001591 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001592#if DEBUG_DISPATCH_CYCLE
1593 LOGD("channel '%s' ~ startDispatchCycle",
1594 connection->getInputChannelName());
1595#endif
1596
1597 assert(connection->status == Connection::STATUS_NORMAL);
1598 assert(! connection->outboundQueue.isEmpty());
1599
Jeff Browna665ca82010-09-08 11:49:43 -07001600 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001601 assert(! dispatchEntry->inProgress);
1602
Jeff Browna665ca82010-09-08 11:49:43 -07001603 // Mark the dispatch entry as in progress.
1604 dispatchEntry->inProgress = true;
1605
1606 // Update the connection's input state.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001607 EventEntry* eventEntry = dispatchEntry->eventEntry;
1608 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001609
1610#if FILTER_INPUT_EVENTS
1611 // Filter out inconsistent sequences of input events.
1612 // The input system may drop or inject events in a way that could violate implicit
1613 // invariants on input state and potentially cause an application to crash
1614 // or think that a key or pointer is stuck down. Technically we make no guarantees
1615 // of consistency but it would be nice to improve on this where possible.
1616 // XXX: This code is a proof of concept only. Not ready for prime time.
1617 if (consistency == InputState::TOLERABLE) {
1618#if DEBUG_DISPATCH_CYCLE
1619 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1620 "current input state but that is likely to be tolerated by the application.",
1621 connection->getInputChannelName());
1622#endif
1623 } else if (consistency == InputState::BROKEN) {
1624 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1625 "current input state and that is likely to cause the application to crash.",
1626 connection->getInputChannelName());
1627 startNextDispatchCycleLocked(currentTime, connection);
1628 return;
1629 }
1630#endif
Jeff Browne839a582010-04-22 18:58:52 -07001631
1632 // Publish the event.
1633 status_t status;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001634 switch (eventEntry->type) {
Jeff Browne839a582010-04-22 18:58:52 -07001635 case EventEntry::TYPE_KEY: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001636 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001637
1638 // Apply target flags.
1639 int32_t action = keyEntry->action;
1640 int32_t flags = keyEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001641
1642 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001643 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-04-22 18:58:52 -07001644 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1645 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1646 keyEntry->eventTime);
1647
1648 if (status) {
1649 LOGE("channel '%s' ~ Could not publish key event, "
1650 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001651 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001652 return;
1653 }
1654 break;
1655 }
1656
1657 case EventEntry::TYPE_MOTION: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001658 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001659
1660 // Apply target flags.
1661 int32_t action = motionEntry->action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07001662 int32_t flags = motionEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001663 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001664 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -07001665 }
Jeff Brownaf30ff62010-09-01 17:01:00 -07001666 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1667 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1668 }
Jeff Browne839a582010-04-22 18:58:52 -07001669
1670 // If headMotionSample is non-NULL, then it points to the first new sample that we
1671 // were unable to dispatch during the previous cycle so we resume dispatching from
1672 // that point in the list of motion samples.
1673 // Otherwise, we just start from the first sample of the motion event.
1674 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1675 if (! firstMotionSample) {
1676 firstMotionSample = & motionEntry->firstSample;
1677 }
1678
Jeff Brownf26db0d2010-07-16 17:21:06 -07001679 // Set the X and Y offset depending on the input source.
1680 float xOffset, yOffset;
1681 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1682 xOffset = dispatchEntry->xOffset;
1683 yOffset = dispatchEntry->yOffset;
1684 } else {
1685 xOffset = 0.0f;
1686 yOffset = 0.0f;
1687 }
1688
Jeff Browne839a582010-04-22 18:58:52 -07001689 // Publish the motion event and the first motion sample.
1690 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001691 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -07001692 xOffset, yOffset,
Jeff Browne839a582010-04-22 18:58:52 -07001693 motionEntry->xPrecision, motionEntry->yPrecision,
1694 motionEntry->downTime, firstMotionSample->eventTime,
1695 motionEntry->pointerCount, motionEntry->pointerIds,
1696 firstMotionSample->pointerCoords);
1697
1698 if (status) {
1699 LOGE("channel '%s' ~ Could not publish motion event, "
1700 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001701 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001702 return;
1703 }
1704
1705 // Append additional motion samples.
1706 MotionSample* nextMotionSample = firstMotionSample->next;
1707 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1708 status = connection->inputPublisher.appendMotionSample(
1709 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1710 if (status == NO_MEMORY) {
1711#if DEBUG_DISPATCH_CYCLE
1712 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1713 "be sent in the next dispatch cycle.",
1714 connection->getInputChannelName());
1715#endif
1716 break;
1717 }
1718 if (status != OK) {
1719 LOGE("channel '%s' ~ Could not append motion sample "
1720 "for a reason other than out of memory, status=%d",
1721 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001722 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001723 return;
1724 }
1725 }
1726
1727 // Remember the next motion sample that we could not dispatch, in case we ran out
1728 // of space in the shared memory buffer.
1729 dispatchEntry->tailMotionSample = nextMotionSample;
1730 break;
1731 }
1732
1733 default: {
1734 assert(false);
1735 }
1736 }
1737
1738 // Send the dispatch signal.
1739 status = connection->inputPublisher.sendDispatchSignal();
1740 if (status) {
1741 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1742 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001743 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001744 return;
1745 }
1746
1747 // Record information about the newly started dispatch cycle.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001748 connection->lastEventTime = eventEntry->eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07001749 connection->lastDispatchTime = currentTime;
1750
Jeff Browne839a582010-04-22 18:58:52 -07001751 // Notify other system components.
1752 onDispatchCycleStartedLocked(currentTime, connection);
1753}
1754
Jeff Brown51d45a72010-06-17 20:52:56 -07001755void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1756 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001757#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001758 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -07001759 "%01.1fms since dispatch",
1760 connection->getInputChannelName(),
1761 connection->getEventLatencyMillis(currentTime),
1762 connection->getDispatchLatencyMillis(currentTime));
1763#endif
1764
Jeff Brown54bc2812010-06-15 01:31:58 -07001765 if (connection->status == Connection::STATUS_BROKEN
1766 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001767 return;
1768 }
1769
Jeff Brown53a415e2010-09-15 15:18:56 -07001770 // Notify other system components.
1771 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001772
1773 // Reset the publisher since the event has been consumed.
1774 // We do this now so that the publisher can release some of its internal resources
1775 // while waiting for the next dispatch cycle to begin.
1776 status_t status = connection->inputPublisher.reset();
1777 if (status) {
1778 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1779 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001780 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001781 return;
1782 }
1783
Jeff Browna665ca82010-09-08 11:49:43 -07001784 startNextDispatchCycleLocked(currentTime, connection);
1785}
1786
1787void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1788 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001789 // Start the next dispatch cycle for this connection.
1790 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001791 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001792 if (dispatchEntry->inProgress) {
1793 // Finish or resume current event in progress.
1794 if (dispatchEntry->tailMotionSample) {
1795 // We have a tail of undispatched motion samples.
1796 // Reuse the same DispatchEntry and start a new cycle.
1797 dispatchEntry->inProgress = false;
1798 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1799 dispatchEntry->tailMotionSample = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07001800 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001801 return;
1802 }
1803 // Finished.
1804 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001805 if (dispatchEntry->hasForegroundTarget()) {
1806 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001807 }
Jeff Browne839a582010-04-22 18:58:52 -07001808 mAllocator.releaseDispatchEntry(dispatchEntry);
1809 } else {
1810 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown53a415e2010-09-15 15:18:56 -07001811 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001812 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001813 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001814 return;
1815 }
1816 }
1817
1818 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001819 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001820}
1821
Jeff Brown90f0cee2010-10-08 22:31:17 -07001822void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1823 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001824#if DEBUG_DISPATCH_CYCLE
Jeff Brown90f0cee2010-10-08 22:31:17 -07001825 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001826 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001827#endif
1828
Jeff Browna665ca82010-09-08 11:49:43 -07001829 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001830 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001831
Jeff Brown90f0cee2010-10-08 22:31:17 -07001832 // The connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001833 // Ignore already broken or zombie connections.
Jeff Brown90f0cee2010-10-08 22:31:17 -07001834 if (connection->status == Connection::STATUS_NORMAL) {
1835 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001836
Jeff Brown90f0cee2010-10-08 22:31:17 -07001837 // Notify other system components.
1838 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001839 }
Jeff Browne839a582010-04-22 18:58:52 -07001840}
1841
Jeff Brown53a415e2010-09-15 15:18:56 -07001842void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1843 while (! connection->outboundQueue.isEmpty()) {
1844 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1845 if (dispatchEntry->hasForegroundTarget()) {
1846 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001847 }
1848 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001849 }
1850
Jeff Brown53a415e2010-09-15 15:18:56 -07001851 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001852}
1853
Jeff Brown59abe7e2010-09-13 23:17:30 -07001854int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-04-22 18:58:52 -07001855 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1856
1857 { // acquire lock
1858 AutoMutex _l(d->mLock);
1859
1860 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1861 if (connectionIndex < 0) {
1862 LOGE("Received spurious receive callback for unknown input channel. "
1863 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001864 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001865 }
1866
Jeff Brown51d45a72010-06-17 20:52:56 -07001867 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001868
1869 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001870 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-04-22 18:58:52 -07001871 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1872 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001873 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001874 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001875 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001876 }
1877
Jeff Brown59abe7e2010-09-13 23:17:30 -07001878 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001879 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1880 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001881 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001882 }
1883
1884 status_t status = connection->inputPublisher.receiveFinishedSignal();
1885 if (status) {
1886 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1887 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001888 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001889 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001890 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001891 }
1892
Jeff Brown51d45a72010-06-17 20:52:56 -07001893 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001894 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001895 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001896 } // release lock
1897}
1898
Jeff Brown90f0cee2010-10-08 22:31:17 -07001899void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1900 InputState::CancelationOptions options, const char* reason) {
1901 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1902 synthesizeCancelationEventsForConnectionLocked(
1903 mConnectionsByReceiveFd.valueAt(i), options, reason);
1904 }
1905}
1906
1907void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1908 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1909 const char* reason) {
1910 ssize_t index = getConnectionIndexLocked(channel);
1911 if (index >= 0) {
1912 synthesizeCancelationEventsForConnectionLocked(
1913 mConnectionsByReceiveFd.valueAt(index), options, reason);
1914 }
1915}
1916
1917void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1918 const sp<Connection>& connection, InputState::CancelationOptions options,
1919 const char* reason) {
1920 nsecs_t currentTime = now();
1921
1922 mTempCancelationEvents.clear();
1923 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1924 mTempCancelationEvents, options);
1925
1926 if (! mTempCancelationEvents.isEmpty()
1927 && connection->status != Connection::STATUS_BROKEN) {
1928#if DEBUG_OUTBOUND_EVENT_DETAILS
1929 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1930 "with reality: %s, options=%d.",
1931 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1932#endif
1933 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1934 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1935 switch (cancelationEventEntry->type) {
1936 case EventEntry::TYPE_KEY:
1937 logOutboundKeyDetailsLocked("cancel - ",
1938 static_cast<KeyEntry*>(cancelationEventEntry));
1939 break;
1940 case EventEntry::TYPE_MOTION:
1941 logOutboundMotionDetailsLocked("cancel - ",
1942 static_cast<MotionEntry*>(cancelationEventEntry));
1943 break;
1944 }
1945
1946 int32_t xOffset, yOffset;
1947 const InputWindow* window = getWindowLocked(connection->inputChannel);
1948 if (window) {
1949 xOffset = -window->frameLeft;
1950 yOffset = -window->frameTop;
1951 } else {
1952 xOffset = 0;
1953 yOffset = 0;
1954 }
1955
1956 DispatchEntry* cancelationDispatchEntry =
1957 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1958 0, xOffset, yOffset);
1959 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1960
1961 mAllocator.releaseEventEntry(cancelationEventEntry);
1962 }
1963
1964 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1965 startDispatchCycleLocked(currentTime, connection);
1966 }
1967 }
1968}
1969
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001970InputDispatcher::MotionEntry*
1971InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1972 assert(pointerIds.value != 0);
1973
1974 uint32_t splitPointerIndexMap[MAX_POINTERS];
1975 int32_t splitPointerIds[MAX_POINTERS];
1976 PointerCoords splitPointerCoords[MAX_POINTERS];
1977
1978 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1979 uint32_t splitPointerCount = 0;
1980
1981 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1982 originalPointerIndex++) {
1983 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1984 if (pointerIds.hasBit(pointerId)) {
1985 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1986 splitPointerIds[splitPointerCount] = pointerId;
1987 splitPointerCoords[splitPointerCount] =
1988 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1989 splitPointerCount += 1;
1990 }
1991 }
1992 assert(splitPointerCount == pointerIds.count());
1993
1994 int32_t action = originalMotionEntry->action;
1995 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1996 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
1997 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1998 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
1999 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2000 if (pointerIds.hasBit(pointerId)) {
2001 if (pointerIds.count() == 1) {
2002 // The first/last pointer went down/up.
2003 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2004 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brownffb16d62010-09-27 16:35:11 -07002005 } else {
2006 // A secondary pointer went down/up.
2007 uint32_t splitPointerIndex = 0;
2008 while (pointerId != splitPointerIds[splitPointerIndex]) {
2009 splitPointerIndex += 1;
2010 }
2011 action = maskedAction | (splitPointerIndex
2012 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002013 }
2014 } else {
2015 // An unrelated pointer changed.
2016 action = AMOTION_EVENT_ACTION_MOVE;
2017 }
2018 }
2019
2020 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2021 originalMotionEntry->eventTime,
2022 originalMotionEntry->deviceId,
2023 originalMotionEntry->source,
2024 originalMotionEntry->policyFlags,
2025 action,
2026 originalMotionEntry->flags,
2027 originalMotionEntry->metaState,
2028 originalMotionEntry->edgeFlags,
2029 originalMotionEntry->xPrecision,
2030 originalMotionEntry->yPrecision,
2031 originalMotionEntry->downTime,
2032 splitPointerCount, splitPointerIds, splitPointerCoords);
2033
2034 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2035 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2036 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2037 splitPointerIndex++) {
2038 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2039 splitPointerCoords[splitPointerIndex] =
2040 originalMotionSample->pointerCoords[originalPointerIndex];
2041 }
2042
2043 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2044 splitPointerCoords);
2045 }
2046
2047 return splitMotionEntry;
2048}
2049
Jeff Brown54bc2812010-06-15 01:31:58 -07002050void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002051#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -07002052 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07002053#endif
2054
Jeff Browna665ca82010-09-08 11:49:43 -07002055 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002056 { // acquire lock
2057 AutoMutex _l(mLock);
2058
Jeff Brown51d45a72010-06-17 20:52:56 -07002059 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browna665ca82010-09-08 11:49:43 -07002060 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002061 } // release lock
2062
Jeff Browna665ca82010-09-08 11:49:43 -07002063 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002064 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002065 }
2066}
2067
Jeff Brown5c1ed842010-07-14 18:48:53 -07002068void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -07002069 uint32_t policyFlags, int32_t action, int32_t flags,
2070 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2071#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002072 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07002073 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07002074 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -07002075 keyCode, scanCode, metaState, downTime);
2076#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002077 if (! validateKeyEvent(action)) {
2078 return;
2079 }
Jeff Browne839a582010-04-22 18:58:52 -07002080
Jeff Brown33d54ce2010-10-11 14:20:19 -07002081 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002082 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2083 keyCode, scanCode, /*byref*/ policyFlags);
2084
Jeff Browna665ca82010-09-08 11:49:43 -07002085 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002086 { // acquire lock
2087 AutoMutex _l(mLock);
2088
Jeff Brown51d45a72010-06-17 20:52:56 -07002089 int32_t repeatCount = 0;
2090 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002091 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07002092 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07002093
Jeff Browna665ca82010-09-08 11:49:43 -07002094 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002095 } // release lock
2096
Jeff Browna665ca82010-09-08 11:49:43 -07002097 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002098 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002099 }
2100}
2101
Jeff Brown5c1ed842010-07-14 18:48:53 -07002102void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002103 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002104 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2105 float xPrecision, float yPrecision, nsecs_t downTime) {
2106#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002107 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002108 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2109 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2110 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002111 xPrecision, yPrecision, downTime);
2112 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07002113 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002114 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07002115 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07002116 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-08-30 03:02:23 -07002117 pointerCoords[i].pressure, pointerCoords[i].size,
2118 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2119 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2120 pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -07002121 }
2122#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002123 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2124 return;
2125 }
Jeff Browne839a582010-04-22 18:58:52 -07002126
Jeff Brown33d54ce2010-10-11 14:20:19 -07002127 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002128 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2129
Jeff Browna665ca82010-09-08 11:49:43 -07002130 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002131 { // acquire lock
2132 AutoMutex _l(mLock);
2133
2134 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07002135 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07002136 // BATCHING CASE
2137 //
2138 // Try to append a move sample to the tail of the inbound queue for this device.
2139 // Give up if we encounter a non-move motion event for this device since that
2140 // means we cannot append any new samples until a new motion event has started.
Jeff Browna665ca82010-09-08 11:49:43 -07002141 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2142 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07002143 if (entry->type != EventEntry::TYPE_MOTION) {
2144 // Keep looking for motion events.
2145 continue;
2146 }
2147
2148 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2149 if (motionEntry->deviceId != deviceId) {
2150 // Keep looking for this device.
2151 continue;
2152 }
2153
Jeff Brown5c1ed842010-07-14 18:48:53 -07002154 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07002155 || motionEntry->pointerCount != pointerCount
2156 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07002157 // Last motion event in the queue for this device is not compatible for
2158 // appending new samples. Stop here.
2159 goto NoBatchingOrStreaming;
2160 }
2161
2162 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07002163 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07002164 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002165#if DEBUG_BATCHING
2166 LOGD("Appended motion sample onto batch for most recent "
2167 "motion event for this device in the inbound queue.");
2168#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07002169 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002170 }
2171
2172 // STREAMING CASE
2173 //
2174 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07002175 // Search the outbound queue for the current foreground targets to find a dispatched
2176 // motion event that is still in progress. If found, then, appen the new sample to
2177 // that event and push it out to all current targets. The logic in
2178 // prepareDispatchCycleLocked takes care of the case where some targets may
2179 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown54bc2812010-06-15 01:31:58 -07002180 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002181 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2182 const InputTarget& inputTarget = mCurrentInputTargets[i];
2183 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2184 // Skip non-foreground targets. We only want to stream if there is at
2185 // least one foreground target whose dispatch is still in progress.
2186 continue;
Jeff Browne839a582010-04-22 18:58:52 -07002187 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002188
2189 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2190 if (connectionIndex < 0) {
2191 // Connection must no longer be valid.
2192 continue;
2193 }
2194
2195 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2196 if (connection->outboundQueue.isEmpty()) {
2197 // This foreground target has an empty outbound queue.
2198 continue;
2199 }
2200
2201 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2202 if (! dispatchEntry->inProgress
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002203 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2204 || dispatchEntry->isSplit()) {
2205 // No motion event is being dispatched, or it is being split across
2206 // windows in which case we cannot stream.
Jeff Brown53a415e2010-09-15 15:18:56 -07002207 continue;
2208 }
2209
2210 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2211 dispatchEntry->eventEntry);
2212 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2213 || motionEntry->deviceId != deviceId
2214 || motionEntry->pointerCount != pointerCount
2215 || motionEntry->isInjected()) {
2216 // The motion event is not compatible with this move.
2217 continue;
2218 }
2219
2220 // Hurray! This foreground target is currently dispatching a move event
2221 // that we can stream onto. Append the motion sample and resume dispatch.
2222 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2223#if DEBUG_BATCHING
2224 LOGD("Appended motion sample onto batch for most recently dispatched "
2225 "motion event for this device in the outbound queues. "
2226 "Attempting to stream the motion sample.");
2227#endif
2228 nsecs_t currentTime = now();
2229 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2230 true /*resumeWithAppendedMotionSample*/);
2231
2232 runCommandsLockedInterruptible();
2233 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002234 }
2235 }
2236
2237NoBatchingOrStreaming:;
2238 }
2239
2240 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07002241 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002242 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002243 xPrecision, yPrecision, downTime,
2244 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002245
Jeff Browna665ca82010-09-08 11:49:43 -07002246 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002247 } // release lock
2248
Jeff Browna665ca82010-09-08 11:49:43 -07002249 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002250 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002251 }
2252}
2253
Jeff Brown90f0cee2010-10-08 22:31:17 -07002254void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2255 uint32_t policyFlags) {
2256#if DEBUG_INBOUND_EVENT_DETAILS
2257 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2258 switchCode, switchValue, policyFlags);
2259#endif
2260
Jeff Brown33d54ce2010-10-11 14:20:19 -07002261 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002262 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2263}
2264
Jeff Brown51d45a72010-06-17 20:52:56 -07002265int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07002266 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002267#if DEBUG_INBOUND_EVENT_DETAILS
2268 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002269 "syncMode=%d, timeoutMillis=%d",
2270 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07002271#endif
2272
2273 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brown33d54ce2010-10-11 14:20:19 -07002274
2275 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2276 if (hasInjectionPermission(injectorPid, injectorUid)) {
2277 policyFlags |= POLICY_FLAG_TRUSTED;
2278 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002279
Jeff Brown90f0cee2010-10-08 22:31:17 -07002280 EventEntry* injectedEntry;
2281 switch (event->getType()) {
2282 case AINPUT_EVENT_TYPE_KEY: {
2283 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2284 int32_t action = keyEvent->getAction();
2285 if (! validateKeyEvent(action)) {
Jeff Browna665ca82010-09-08 11:49:43 -07002286 return INPUT_EVENT_INJECTION_FAILED;
2287 }
2288
Jeff Brown90f0cee2010-10-08 22:31:17 -07002289 nsecs_t eventTime = keyEvent->getEventTime();
2290 int32_t deviceId = keyEvent->getDeviceId();
2291 int32_t flags = keyEvent->getFlags();
2292 int32_t keyCode = keyEvent->getKeyCode();
2293 int32_t scanCode = keyEvent->getScanCode();
Jeff Brown33d54ce2010-10-11 14:20:19 -07002294 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2295 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002296
Jeff Brown90f0cee2010-10-08 22:31:17 -07002297 mLock.lock();
2298 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2299 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2300 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2301 break;
2302 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002303
Jeff Brown90f0cee2010-10-08 22:31:17 -07002304 case AINPUT_EVENT_TYPE_MOTION: {
2305 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2306 int32_t action = motionEvent->getAction();
2307 size_t pointerCount = motionEvent->getPointerCount();
2308 const int32_t* pointerIds = motionEvent->getPointerIds();
2309 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2310 return INPUT_EVENT_INJECTION_FAILED;
2311 }
2312
2313 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown33d54ce2010-10-11 14:20:19 -07002314 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002315
2316 mLock.lock();
2317 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2318 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2319 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2320 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2321 action, motionEvent->getFlags(),
2322 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2323 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2324 motionEvent->getDownTime(), uint32_t(pointerCount),
2325 pointerIds, samplePointerCoords);
2326 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2327 sampleEventTimes += 1;
2328 samplePointerCoords += pointerCount;
2329 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2330 }
2331 injectedEntry = motionEntry;
2332 break;
2333 }
2334
2335 default:
2336 LOGW("Cannot inject event of type %d", event->getType());
2337 return INPUT_EVENT_INJECTION_FAILED;
2338 }
2339
2340 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2341 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2342 injectionState->injectionIsAsync = true;
2343 }
2344
2345 injectionState->refCount += 1;
2346 injectedEntry->injectionState = injectionState;
2347
2348 bool needWake = enqueueInboundEventLocked(injectedEntry);
2349 mLock.unlock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002350
Jeff Browna665ca82010-09-08 11:49:43 -07002351 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002352 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07002353 }
2354
2355 int32_t injectionResult;
2356 { // acquire lock
2357 AutoMutex _l(mLock);
2358
Jeff Brownf67c53e2010-07-28 15:48:59 -07002359 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2360 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2361 } else {
2362 for (;;) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002363 injectionResult = injectionState->injectionResult;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002364 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2365 break;
2366 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002367
Jeff Brown51d45a72010-06-17 20:52:56 -07002368 nsecs_t remainingTimeout = endTime - now();
2369 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002370#if DEBUG_INJECTION
2371 LOGD("injectInputEvent - Timed out waiting for injection result "
2372 "to become available.");
2373#endif
Jeff Brown51d45a72010-06-17 20:52:56 -07002374 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2375 break;
2376 }
2377
Jeff Brownf67c53e2010-07-28 15:48:59 -07002378 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2379 }
2380
2381 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2382 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002383 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002384#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002385 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002386 injectionState->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002387#endif
2388 nsecs_t remainingTimeout = endTime - now();
2389 if (remainingTimeout <= 0) {
2390#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002391 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002392 "dispatches to finish.");
2393#endif
2394 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2395 break;
2396 }
2397
2398 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2399 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002400 }
2401 }
2402
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002403 mAllocator.releaseInjectionState(injectionState);
Jeff Brown51d45a72010-06-17 20:52:56 -07002404 } // release lock
2405
Jeff Brownf67c53e2010-07-28 15:48:59 -07002406#if DEBUG_INJECTION
2407 LOGD("injectInputEvent - Finished with result %d. "
2408 "injectorPid=%d, injectorUid=%d",
2409 injectionResult, injectorPid, injectorUid);
2410#endif
2411
Jeff Brown51d45a72010-06-17 20:52:56 -07002412 return injectionResult;
2413}
2414
Jeff Brown90f0cee2010-10-08 22:31:17 -07002415bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2416 return injectorUid == 0
2417 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2418}
2419
Jeff Brown51d45a72010-06-17 20:52:56 -07002420void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002421 InjectionState* injectionState = entry->injectionState;
2422 if (injectionState) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002423#if DEBUG_INJECTION
2424 LOGD("Setting input event injection result to %d. "
2425 "injectorPid=%d, injectorUid=%d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002426 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002427#endif
2428
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002429 if (injectionState->injectionIsAsync) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002430 // Log the outcome since the injector did not wait for the injection result.
2431 switch (injectionResult) {
2432 case INPUT_EVENT_INJECTION_SUCCEEDED:
2433 LOGV("Asynchronous input event injection succeeded.");
2434 break;
2435 case INPUT_EVENT_INJECTION_FAILED:
2436 LOGW("Asynchronous input event injection failed.");
2437 break;
2438 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2439 LOGW("Asynchronous input event injection permission denied.");
2440 break;
2441 case INPUT_EVENT_INJECTION_TIMED_OUT:
2442 LOGW("Asynchronous input event injection timed out.");
2443 break;
2444 }
2445 }
2446
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002447 injectionState->injectionResult = injectionResult;
Jeff Brown51d45a72010-06-17 20:52:56 -07002448 mInjectionResultAvailableCondition.broadcast();
2449 }
2450}
2451
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002452void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2453 InjectionState* injectionState = entry->injectionState;
2454 if (injectionState) {
2455 injectionState->pendingForegroundDispatches += 1;
2456 }
2457}
2458
Jeff Brown53a415e2010-09-15 15:18:56 -07002459void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002460 InjectionState* injectionState = entry->injectionState;
2461 if (injectionState) {
2462 injectionState->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002463
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002464 if (injectionState->pendingForegroundDispatches == 0) {
2465 mInjectionSyncFinishedCondition.broadcast();
2466 }
Jeff Browna665ca82010-09-08 11:49:43 -07002467 }
2468}
2469
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002470const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2471 for (size_t i = 0; i < mWindows.size(); i++) {
2472 const InputWindow* window = & mWindows[i];
2473 if (window->inputChannel == inputChannel) {
2474 return window;
2475 }
2476 }
2477 return NULL;
2478}
2479
Jeff Browna665ca82010-09-08 11:49:43 -07002480void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2481#if DEBUG_FOCUS
2482 LOGD("setInputWindows");
2483#endif
2484 { // acquire lock
2485 AutoMutex _l(mLock);
2486
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002487 // Clear old window pointers.
Jeff Brown90f0cee2010-10-08 22:31:17 -07002488 sp<InputChannel> oldFocusedWindowChannel;
2489 if (mFocusedWindow) {
2490 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2491 mFocusedWindow = NULL;
2492 }
2493
Jeff Browna665ca82010-09-08 11:49:43 -07002494 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002495
2496 // Loop over new windows and rebuild the necessary window pointers for
2497 // tracking focus and touch.
Jeff Browna665ca82010-09-08 11:49:43 -07002498 mWindows.appendVector(inputWindows);
2499
2500 size_t numWindows = mWindows.size();
2501 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002502 const InputWindow* window = & mWindows.itemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07002503 if (window->hasFocus) {
2504 mFocusedWindow = window;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002505 break;
Jeff Browna665ca82010-09-08 11:49:43 -07002506 }
2507 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002508
Jeff Brown90f0cee2010-10-08 22:31:17 -07002509 if (oldFocusedWindowChannel != NULL) {
2510 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2511#if DEBUG_FOCUS
2512 LOGD("Focus left window: %s",
2513 oldFocusedWindowChannel->getName().string());
2514#endif
2515 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2516 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2517 oldFocusedWindowChannel.clear();
2518 }
2519 }
2520 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2521#if DEBUG_FOCUS
2522 LOGD("Focus entered window: %s",
2523 mFocusedWindow->inputChannel->getName().string());
2524#endif
2525 }
2526
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002527 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2528 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2529 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2530 if (window) {
2531 touchedWindow.window = window;
2532 i += 1;
2533 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -07002534#if DEBUG_FOCUS
2535 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2536#endif
Jeff Brown90f0cee2010-10-08 22:31:17 -07002537 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2538 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownb13d7b52010-10-15 16:20:51 -07002539 mTouchState.windows.removeAt(i);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002540 }
2541 }
Jeff Browna665ca82010-09-08 11:49:43 -07002542
Jeff Browna665ca82010-09-08 11:49:43 -07002543#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002544 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002545#endif
2546 } // release lock
2547
2548 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002549 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002550}
2551
2552void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2553#if DEBUG_FOCUS
2554 LOGD("setFocusedApplication");
2555#endif
2556 { // acquire lock
2557 AutoMutex _l(mLock);
2558
2559 releaseFocusedApplicationLocked();
2560
2561 if (inputApplication) {
2562 mFocusedApplicationStorage = *inputApplication;
2563 mFocusedApplication = & mFocusedApplicationStorage;
2564 }
2565
2566#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002567 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002568#endif
2569 } // release lock
2570
2571 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002572 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002573}
2574
2575void InputDispatcher::releaseFocusedApplicationLocked() {
2576 if (mFocusedApplication) {
2577 mFocusedApplication = NULL;
2578 mFocusedApplicationStorage.handle.clear();
2579 }
2580}
2581
2582void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2583#if DEBUG_FOCUS
2584 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2585#endif
2586
2587 bool changed;
2588 { // acquire lock
2589 AutoMutex _l(mLock);
2590
2591 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2592 if (mDispatchFrozen && ! frozen) {
2593 resetANRTimeoutsLocked();
2594 }
2595
2596 mDispatchEnabled = enabled;
2597 mDispatchFrozen = frozen;
2598 changed = true;
2599 } else {
2600 changed = false;
2601 }
2602
2603#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002604 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002605#endif
2606 } // release lock
2607
2608 if (changed) {
2609 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002610 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002611 }
2612}
2613
Jeff Brown744c5592010-09-27 14:52:15 -07002614bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2615 const sp<InputChannel>& toChannel) {
2616#if DEBUG_FOCUS
2617 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2618 fromChannel->getName().string(), toChannel->getName().string());
2619#endif
2620 { // acquire lock
2621 AutoMutex _l(mLock);
2622
2623 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2624 const InputWindow* toWindow = getWindowLocked(toChannel);
2625 if (! fromWindow || ! toWindow) {
2626#if DEBUG_FOCUS
2627 LOGD("Cannot transfer focus because from or to window not found.");
2628#endif
2629 return false;
2630 }
2631 if (fromWindow == toWindow) {
2632#if DEBUG_FOCUS
2633 LOGD("Trivial transfer to same window.");
2634#endif
2635 return true;
2636 }
2637
2638 bool found = false;
2639 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2640 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2641 if (touchedWindow.window == fromWindow) {
2642 int32_t oldTargetFlags = touchedWindow.targetFlags;
2643 BitSet32 pointerIds = touchedWindow.pointerIds;
2644
2645 mTouchState.windows.removeAt(i);
2646
2647 int32_t newTargetFlags = 0;
2648 if (oldTargetFlags & InputTarget::FLAG_FOREGROUND) {
2649 newTargetFlags |= InputTarget::FLAG_FOREGROUND;
2650 if (toWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) {
2651 newTargetFlags |= InputTarget::FLAG_SPLIT;
2652 }
2653 }
2654 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2655
2656 found = true;
2657 break;
2658 }
2659 }
2660
2661 if (! found) {
2662#if DEBUG_FOCUS
2663 LOGD("Focus transfer failed because from window did not have focus.");
2664#endif
2665 return false;
2666 }
2667
Jeff Brownb6702e52010-10-11 18:32:20 -07002668 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2669 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2670 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2671 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2672 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2673
2674 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2675 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2676 InputState::CANCEL_POINTER_EVENTS,
2677 "transferring touch focus from this window to another window");
2678 }
2679
Jeff Brown744c5592010-09-27 14:52:15 -07002680#if DEBUG_FOCUS
2681 logDispatchStateLocked();
2682#endif
2683 } // release lock
2684
2685 // Wake up poll loop since it may need to make new input dispatching choices.
2686 mLooper->wake();
2687 return true;
2688}
2689
Jeff Browna665ca82010-09-08 11:49:43 -07002690void InputDispatcher::logDispatchStateLocked() {
2691 String8 dump;
2692 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002693
2694 char* text = dump.lockBuffer(dump.size());
2695 char* start = text;
2696 while (*start != '\0') {
2697 char* end = strchr(start, '\n');
2698 if (*end == '\n') {
2699 *(end++) = '\0';
2700 }
2701 LOGD("%s", start);
2702 start = end;
2703 }
Jeff Browna665ca82010-09-08 11:49:43 -07002704}
2705
2706void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002707 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2708 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002709
2710 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002711 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002712 mFocusedApplication->name.string(),
2713 mFocusedApplication->dispatchingTimeout / 1000000.0);
2714 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002715 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002716 }
Jeff Brown2806e382010-10-01 17:46:21 -07002717 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002718 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-10-01 17:46:21 -07002719
2720 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2721 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2722 if (!mTouchState.windows.isEmpty()) {
2723 dump.append(INDENT "TouchedWindows:\n");
2724 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2725 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2726 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2727 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2728 touchedWindow.targetFlags);
2729 }
2730 } else {
2731 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002732 }
2733
Jeff Brown2806e382010-10-01 17:46:21 -07002734 if (!mWindows.isEmpty()) {
2735 dump.append(INDENT "Windows:\n");
2736 for (size_t i = 0; i < mWindows.size(); i++) {
2737 const InputWindow& window = mWindows[i];
2738 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2739 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2740 "frame=[%d,%d][%d,%d], "
2741 "visibleFrame=[%d,%d][%d,%d], "
2742 "touchableArea=[%d,%d][%d,%d], "
2743 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2744 i, window.name.string(),
2745 toString(window.paused),
2746 toString(window.hasFocus),
2747 toString(window.hasWallpaper),
2748 toString(window.visible),
2749 toString(window.canReceiveKeys),
2750 window.layoutParamsFlags, window.layoutParamsType,
2751 window.layer,
2752 window.frameLeft, window.frameTop,
2753 window.frameRight, window.frameBottom,
2754 window.visibleFrameLeft, window.visibleFrameTop,
2755 window.visibleFrameRight, window.visibleFrameBottom,
2756 window.touchableAreaLeft, window.touchableAreaTop,
2757 window.touchableAreaRight, window.touchableAreaBottom,
2758 window.ownerPid, window.ownerUid,
2759 window.dispatchingTimeout / 1000000.0);
2760 }
2761 } else {
2762 dump.append(INDENT "Windows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002763 }
2764
Jeff Brown2806e382010-10-01 17:46:21 -07002765 if (!mMonitoringChannels.isEmpty()) {
2766 dump.append(INDENT "MonitoringChannels:\n");
2767 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2768 const sp<InputChannel>& channel = mMonitoringChannels[i];
2769 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2770 }
2771 } else {
2772 dump.append(INDENT "MonitoringChannels: <none>\n");
2773 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002774
Jeff Brown2806e382010-10-01 17:46:21 -07002775 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2776
2777 if (!mActiveConnections.isEmpty()) {
2778 dump.append(INDENT "ActiveConnections:\n");
2779 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2780 const Connection* connection = mActiveConnections[i];
Jeff Brown53f291e2010-10-25 17:37:46 -07002781 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brown90f0cee2010-10-08 22:31:17 -07002782 "inputState.isNeutral=%s\n",
Jeff Brown2806e382010-10-01 17:46:21 -07002783 i, connection->getInputChannelName(), connection->getStatusLabel(),
2784 connection->outboundQueue.count(),
Jeff Brown90f0cee2010-10-08 22:31:17 -07002785 toString(connection->inputState.isNeutral()));
Jeff Brown2806e382010-10-01 17:46:21 -07002786 }
2787 } else {
2788 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002789 }
2790
2791 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002792 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002793 (mAppSwitchDueTime - now()) / 1000000.0);
2794 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002795 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002796 }
2797}
2798
2799status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002800#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002801 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2802 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002803#endif
2804
Jeff Browne839a582010-04-22 18:58:52 -07002805 { // acquire lock
2806 AutoMutex _l(mLock);
2807
Jeff Brown53a415e2010-09-15 15:18:56 -07002808 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002809 LOGW("Attempted to register already registered input channel '%s'",
2810 inputChannel->getName().string());
2811 return BAD_VALUE;
2812 }
2813
2814 sp<Connection> connection = new Connection(inputChannel);
2815 status_t status = connection->initialize();
2816 if (status) {
2817 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2818 inputChannel->getName().string(), status);
2819 return status;
2820 }
2821
Jeff Brown0cacb872010-08-17 15:59:26 -07002822 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002823 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002824
Jeff Browna665ca82010-09-08 11:49:43 -07002825 if (monitor) {
2826 mMonitoringChannels.push(inputChannel);
2827 }
2828
Jeff Brown59abe7e2010-09-13 23:17:30 -07002829 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002830
Jeff Brown54bc2812010-06-15 01:31:58 -07002831 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002832 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002833 return OK;
2834}
2835
2836status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002837#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002838 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002839#endif
2840
Jeff Browne839a582010-04-22 18:58:52 -07002841 { // acquire lock
2842 AutoMutex _l(mLock);
2843
Jeff Brown53a415e2010-09-15 15:18:56 -07002844 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002845 if (connectionIndex < 0) {
2846 LOGW("Attempted to unregister already unregistered input channel '%s'",
2847 inputChannel->getName().string());
2848 return BAD_VALUE;
2849 }
2850
2851 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2852 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2853
2854 connection->status = Connection::STATUS_ZOMBIE;
2855
Jeff Browna665ca82010-09-08 11:49:43 -07002856 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2857 if (mMonitoringChannels[i] == inputChannel) {
2858 mMonitoringChannels.removeAt(i);
2859 break;
2860 }
2861 }
2862
Jeff Brown59abe7e2010-09-13 23:17:30 -07002863 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002864
Jeff Brown51d45a72010-06-17 20:52:56 -07002865 nsecs_t currentTime = now();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002866 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002867
2868 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002869 } // release lock
2870
Jeff Browne839a582010-04-22 18:58:52 -07002871 // Wake the poll loop because removing the connection may have changed the current
2872 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002873 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002874 return OK;
2875}
2876
Jeff Brown53a415e2010-09-15 15:18:56 -07002877ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002878 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2879 if (connectionIndex >= 0) {
2880 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2881 if (connection->inputChannel.get() == inputChannel.get()) {
2882 return connectionIndex;
2883 }
2884 }
2885
2886 return -1;
2887}
2888
Jeff Browne839a582010-04-22 18:58:52 -07002889void InputDispatcher::activateConnectionLocked(Connection* connection) {
2890 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2891 if (mActiveConnections.itemAt(i) == connection) {
2892 return;
2893 }
2894 }
2895 mActiveConnections.add(connection);
2896}
2897
2898void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2899 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2900 if (mActiveConnections.itemAt(i) == connection) {
2901 mActiveConnections.removeAt(i);
2902 return;
2903 }
2904 }
2905}
2906
Jeff Brown54bc2812010-06-15 01:31:58 -07002907void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002908 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002909}
2910
Jeff Brown54bc2812010-06-15 01:31:58 -07002911void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002912 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002913}
2914
Jeff Brown54bc2812010-06-15 01:31:58 -07002915void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002916 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002917 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2918 connection->getInputChannelName());
2919
Jeff Brown54bc2812010-06-15 01:31:58 -07002920 CommandEntry* commandEntry = postCommandLocked(
2921 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002922 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002923}
2924
Jeff Brown53a415e2010-09-15 15:18:56 -07002925void InputDispatcher::onANRLocked(
2926 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2927 nsecs_t eventTime, nsecs_t waitStartTime) {
2928 LOGI("Application is not responding: %s. "
2929 "%01.1fms since event, %01.1fms since wait started",
2930 getApplicationWindowLabelLocked(application, window).string(),
2931 (currentTime - eventTime) / 1000000.0,
2932 (currentTime - waitStartTime) / 1000000.0);
2933
2934 CommandEntry* commandEntry = postCommandLocked(
2935 & InputDispatcher::doNotifyANRLockedInterruptible);
2936 if (application) {
2937 commandEntry->inputApplicationHandle = application->handle;
2938 }
2939 if (window) {
2940 commandEntry->inputChannel = window->inputChannel;
2941 }
2942}
2943
Jeff Browna665ca82010-09-08 11:49:43 -07002944void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2945 CommandEntry* commandEntry) {
2946 mLock.unlock();
2947
2948 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2949
2950 mLock.lock();
2951}
2952
Jeff Brown54bc2812010-06-15 01:31:58 -07002953void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2954 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002955 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002956
Jeff Brown51d45a72010-06-17 20:52:56 -07002957 if (connection->status != Connection::STATUS_ZOMBIE) {
2958 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002959
Jeff Brown51d45a72010-06-17 20:52:56 -07002960 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2961
2962 mLock.lock();
2963 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002964}
2965
Jeff Brown53a415e2010-09-15 15:18:56 -07002966void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002967 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002968 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002969
Jeff Brown53a415e2010-09-15 15:18:56 -07002970 nsecs_t newTimeout = mPolicy->notifyANR(
2971 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002972
Jeff Brown53a415e2010-09-15 15:18:56 -07002973 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002974
Jeff Brown53a415e2010-09-15 15:18:56 -07002975 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002976}
2977
Jeff Browna665ca82010-09-08 11:49:43 -07002978void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2979 CommandEntry* commandEntry) {
2980 KeyEntry* entry = commandEntry->keyEntry;
2981 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2982 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2983 entry->downTime, entry->eventTime);
2984
2985 mLock.unlock();
2986
2987 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2988 & mReusableKeyEvent, entry->policyFlags);
2989
2990 mLock.lock();
2991
2992 entry->interceptKeyResult = consumed
2993 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2994 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2995 mAllocator.releaseKeyEntry(entry);
2996}
2997
2998void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2999 mLock.unlock();
3000
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003001 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07003002
3003 mLock.lock();
3004}
3005
Jeff Brown53a415e2010-09-15 15:18:56 -07003006void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3007 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3008 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07003009}
3010
3011void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07003012 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07003013 dumpDispatchStateLocked(dump);
3014}
3015
Jeff Brown54bc2812010-06-15 01:31:58 -07003016
Jeff Brown53a415e2010-09-15 15:18:56 -07003017// --- InputDispatcher::Queue ---
3018
3019template <typename T>
3020uint32_t InputDispatcher::Queue<T>::count() const {
3021 uint32_t result = 0;
3022 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3023 result += 1;
3024 }
3025 return result;
3026}
3027
3028
Jeff Browne839a582010-04-22 18:58:52 -07003029// --- InputDispatcher::Allocator ---
3030
3031InputDispatcher::Allocator::Allocator() {
3032}
3033
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003034InputDispatcher::InjectionState*
3035InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3036 InjectionState* injectionState = mInjectionStatePool.alloc();
3037 injectionState->refCount = 1;
3038 injectionState->injectorPid = injectorPid;
3039 injectionState->injectorUid = injectorUid;
3040 injectionState->injectionIsAsync = false;
3041 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3042 injectionState->pendingForegroundDispatches = 0;
3043 return injectionState;
3044}
3045
Jeff Brown51d45a72010-06-17 20:52:56 -07003046void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brown90f0cee2010-10-08 22:31:17 -07003047 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown51d45a72010-06-17 20:52:56 -07003048 entry->type = type;
3049 entry->refCount = 1;
3050 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07003051 entry->eventTime = eventTime;
Jeff Brown90f0cee2010-10-08 22:31:17 -07003052 entry->policyFlags = policyFlags;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003053 entry->injectionState = NULL;
3054}
3055
3056void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3057 if (entry->injectionState) {
3058 releaseInjectionState(entry->injectionState);
3059 entry->injectionState = NULL;
3060 }
Jeff Brown51d45a72010-06-17 20:52:56 -07003061}
3062
Jeff Browne839a582010-04-22 18:58:52 -07003063InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07003064InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003065 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003066 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Browne839a582010-04-22 18:58:52 -07003067 return entry;
3068}
3069
Jeff Brown51d45a72010-06-17 20:52:56 -07003070InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07003071 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07003072 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3073 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003074 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003075 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003076
3077 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003078 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003079 entry->action = action;
3080 entry->flags = flags;
3081 entry->keyCode = keyCode;
3082 entry->scanCode = scanCode;
3083 entry->metaState = metaState;
3084 entry->repeatCount = repeatCount;
3085 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07003086 entry->syntheticRepeat = false;
3087 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07003088 return entry;
3089}
3090
Jeff Brown51d45a72010-06-17 20:52:56 -07003091InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07003092 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07003093 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3094 nsecs_t downTime, uint32_t pointerCount,
3095 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003096 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003097 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003098
3099 entry->eventTime = eventTime;
3100 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003101 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003102 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07003103 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07003104 entry->metaState = metaState;
3105 entry->edgeFlags = edgeFlags;
3106 entry->xPrecision = xPrecision;
3107 entry->yPrecision = yPrecision;
3108 entry->downTime = downTime;
3109 entry->pointerCount = pointerCount;
3110 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07003111 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07003112 entry->lastSample = & entry->firstSample;
3113 for (uint32_t i = 0; i < pointerCount; i++) {
3114 entry->pointerIds[i] = pointerIds[i];
3115 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3116 }
Jeff Browne839a582010-04-22 18:58:52 -07003117 return entry;
3118}
3119
3120InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07003121 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07003122 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07003123 DispatchEntry* entry = mDispatchEntryPool.alloc();
3124 entry->eventEntry = eventEntry;
3125 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07003126 entry->targetFlags = targetFlags;
3127 entry->xOffset = xOffset;
3128 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07003129 entry->inProgress = false;
3130 entry->headMotionSample = NULL;
3131 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07003132 return entry;
3133}
3134
Jeff Brown54bc2812010-06-15 01:31:58 -07003135InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3136 CommandEntry* entry = mCommandEntryPool.alloc();
3137 entry->command = command;
3138 return entry;
3139}
3140
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003141void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3142 injectionState->refCount -= 1;
3143 if (injectionState->refCount == 0) {
3144 mInjectionStatePool.free(injectionState);
3145 } else {
3146 assert(injectionState->refCount > 0);
3147 }
3148}
3149
Jeff Browne839a582010-04-22 18:58:52 -07003150void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3151 switch (entry->type) {
3152 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3153 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3154 break;
3155 case EventEntry::TYPE_KEY:
3156 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3157 break;
3158 case EventEntry::TYPE_MOTION:
3159 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3160 break;
3161 default:
3162 assert(false);
3163 break;
3164 }
3165}
3166
3167void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3168 ConfigurationChangedEntry* entry) {
3169 entry->refCount -= 1;
3170 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003171 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003172 mConfigurationChangeEntryPool.free(entry);
3173 } else {
3174 assert(entry->refCount > 0);
3175 }
3176}
3177
3178void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3179 entry->refCount -= 1;
3180 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003181 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003182 mKeyEntryPool.free(entry);
3183 } else {
3184 assert(entry->refCount > 0);
3185 }
3186}
3187
3188void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3189 entry->refCount -= 1;
3190 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003191 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -07003192 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3193 MotionSample* next = sample->next;
3194 mMotionSamplePool.free(sample);
3195 sample = next;
3196 }
Jeff Browne839a582010-04-22 18:58:52 -07003197 mMotionEntryPool.free(entry);
3198 } else {
3199 assert(entry->refCount > 0);
3200 }
3201}
3202
3203void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3204 releaseEventEntry(entry->eventEntry);
3205 mDispatchEntryPool.free(entry);
3206}
3207
Jeff Brown54bc2812010-06-15 01:31:58 -07003208void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3209 mCommandEntryPool.free(entry);
3210}
3211
Jeff Browne839a582010-04-22 18:58:52 -07003212void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003213 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003214 MotionSample* sample = mMotionSamplePool.alloc();
3215 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003216 uint32_t pointerCount = motionEntry->pointerCount;
3217 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07003218 sample->pointerCoords[i] = pointerCoords[i];
3219 }
3220
3221 sample->next = NULL;
3222 motionEntry->lastSample->next = sample;
3223 motionEntry->lastSample = sample;
3224}
3225
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003226void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3227 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003228
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003229 keyEntry->dispatchInProgress = false;
3230 keyEntry->syntheticRepeat = false;
3231 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003232}
3233
3234
Jeff Brown542412c2010-08-18 15:51:08 -07003235// --- InputDispatcher::MotionEntry ---
3236
3237uint32_t InputDispatcher::MotionEntry::countSamples() const {
3238 uint32_t count = 1;
3239 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3240 count += 1;
3241 }
3242 return count;
3243}
3244
Jeff Browna665ca82010-09-08 11:49:43 -07003245
3246// --- InputDispatcher::InputState ---
3247
Jeff Brown90f0cee2010-10-08 22:31:17 -07003248InputDispatcher::InputState::InputState() {
Jeff Browna665ca82010-09-08 11:49:43 -07003249}
3250
3251InputDispatcher::InputState::~InputState() {
3252}
3253
3254bool InputDispatcher::InputState::isNeutral() const {
3255 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3256}
3257
Jeff Browna665ca82010-09-08 11:49:43 -07003258InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3259 const EventEntry* entry) {
3260 switch (entry->type) {
3261 case EventEntry::TYPE_KEY:
3262 return trackKey(static_cast<const KeyEntry*>(entry));
3263
3264 case EventEntry::TYPE_MOTION:
3265 return trackMotion(static_cast<const MotionEntry*>(entry));
3266
3267 default:
3268 return CONSISTENT;
3269 }
3270}
3271
3272InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3273 const KeyEntry* entry) {
3274 int32_t action = entry->action;
3275 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3276 KeyMemento& memento = mKeyMementos.editItemAt(i);
3277 if (memento.deviceId == entry->deviceId
3278 && memento.source == entry->source
3279 && memento.keyCode == entry->keyCode
3280 && memento.scanCode == entry->scanCode) {
3281 switch (action) {
3282 case AKEY_EVENT_ACTION_UP:
3283 mKeyMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003284 return CONSISTENT;
3285
3286 case AKEY_EVENT_ACTION_DOWN:
3287 return TOLERABLE;
3288
3289 default:
3290 return BROKEN;
3291 }
3292 }
3293 }
3294
3295 switch (action) {
3296 case AKEY_EVENT_ACTION_DOWN: {
3297 mKeyMementos.push();
3298 KeyMemento& memento = mKeyMementos.editTop();
3299 memento.deviceId = entry->deviceId;
3300 memento.source = entry->source;
3301 memento.keyCode = entry->keyCode;
3302 memento.scanCode = entry->scanCode;
3303 memento.downTime = entry->downTime;
3304 return CONSISTENT;
3305 }
3306
3307 default:
3308 return BROKEN;
3309 }
3310}
3311
3312InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3313 const MotionEntry* entry) {
3314 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3315 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3316 MotionMemento& memento = mMotionMementos.editItemAt(i);
3317 if (memento.deviceId == entry->deviceId
3318 && memento.source == entry->source) {
3319 switch (action) {
3320 case AMOTION_EVENT_ACTION_UP:
3321 case AMOTION_EVENT_ACTION_CANCEL:
3322 mMotionMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003323 return CONSISTENT;
3324
3325 case AMOTION_EVENT_ACTION_DOWN:
3326 return TOLERABLE;
3327
3328 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3329 if (entry->pointerCount == memento.pointerCount + 1) {
3330 memento.setPointers(entry);
3331 return CONSISTENT;
3332 }
3333 return BROKEN;
3334
3335 case AMOTION_EVENT_ACTION_POINTER_UP:
3336 if (entry->pointerCount == memento.pointerCount - 1) {
3337 memento.setPointers(entry);
3338 return CONSISTENT;
3339 }
3340 return BROKEN;
3341
3342 case AMOTION_EVENT_ACTION_MOVE:
3343 if (entry->pointerCount == memento.pointerCount) {
3344 return CONSISTENT;
3345 }
3346 return BROKEN;
3347
3348 default:
3349 return BROKEN;
3350 }
3351 }
3352 }
3353
3354 switch (action) {
3355 case AMOTION_EVENT_ACTION_DOWN: {
3356 mMotionMementos.push();
3357 MotionMemento& memento = mMotionMementos.editTop();
3358 memento.deviceId = entry->deviceId;
3359 memento.source = entry->source;
3360 memento.xPrecision = entry->xPrecision;
3361 memento.yPrecision = entry->yPrecision;
3362 memento.downTime = entry->downTime;
3363 memento.setPointers(entry);
3364 return CONSISTENT;
3365 }
3366
3367 default:
3368 return BROKEN;
3369 }
3370}
3371
3372void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3373 pointerCount = entry->pointerCount;
3374 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3375 pointerIds[i] = entry->pointerIds[i];
3376 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3377 }
3378}
3379
Jeff Brown90f0cee2010-10-08 22:31:17 -07003380void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3381 Allocator* allocator, Vector<EventEntry*>& outEvents,
3382 CancelationOptions options) {
3383 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003384 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003385 if (shouldCancelEvent(memento.source, options)) {
3386 outEvents.push(allocator->obtainKeyEntry(currentTime,
3387 memento.deviceId, memento.source, 0,
3388 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3389 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3390 mKeyMementos.removeAt(i);
3391 } else {
3392 i += 1;
3393 }
Jeff Browna665ca82010-09-08 11:49:43 -07003394 }
3395
Jeff Brown316237d2010-10-11 18:22:53 -07003396 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003397 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003398 if (shouldCancelEvent(memento.source, options)) {
3399 outEvents.push(allocator->obtainMotionEntry(currentTime,
3400 memento.deviceId, memento.source, 0,
3401 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3402 memento.xPrecision, memento.yPrecision, memento.downTime,
3403 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3404 mMotionMementos.removeAt(i);
3405 } else {
3406 i += 1;
3407 }
Jeff Browna665ca82010-09-08 11:49:43 -07003408 }
3409}
3410
3411void InputDispatcher::InputState::clear() {
3412 mKeyMementos.clear();
3413 mMotionMementos.clear();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003414}
3415
Jeff Brownb6702e52010-10-11 18:32:20 -07003416void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3417 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3418 const MotionMemento& memento = mMotionMementos.itemAt(i);
3419 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3420 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3421 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3422 if (memento.deviceId == otherMemento.deviceId
3423 && memento.source == otherMemento.source) {
3424 other.mMotionMementos.removeAt(j);
3425 } else {
3426 j += 1;
3427 }
3428 }
3429 other.mMotionMementos.push(memento);
3430 }
3431 }
3432}
3433
Jeff Brown90f0cee2010-10-08 22:31:17 -07003434bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3435 CancelationOptions options) {
3436 switch (options) {
3437 case CANCEL_POINTER_EVENTS:
3438 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3439 case CANCEL_NON_POINTER_EVENTS:
3440 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3441 default:
3442 return true;
3443 }
Jeff Browna665ca82010-09-08 11:49:43 -07003444}
3445
3446
Jeff Browne839a582010-04-22 18:58:52 -07003447// --- InputDispatcher::Connection ---
3448
3449InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3450 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003451 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003452}
3453
3454InputDispatcher::Connection::~Connection() {
3455}
3456
3457status_t InputDispatcher::Connection::initialize() {
3458 return inputPublisher.initialize();
3459}
3460
Jeff Brown54bc2812010-06-15 01:31:58 -07003461const char* InputDispatcher::Connection::getStatusLabel() const {
3462 switch (status) {
3463 case STATUS_NORMAL:
3464 return "NORMAL";
3465
3466 case STATUS_BROKEN:
3467 return "BROKEN";
3468
Jeff Brown54bc2812010-06-15 01:31:58 -07003469 case STATUS_ZOMBIE:
3470 return "ZOMBIE";
3471
3472 default:
3473 return "UNKNOWN";
3474 }
3475}
3476
Jeff Browne839a582010-04-22 18:58:52 -07003477InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3478 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003479 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3480 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003481 if (dispatchEntry->eventEntry == eventEntry) {
3482 return dispatchEntry;
3483 }
3484 }
3485 return NULL;
3486}
3487
Jeff Browna665ca82010-09-08 11:49:43 -07003488
Jeff Brown54bc2812010-06-15 01:31:58 -07003489// --- InputDispatcher::CommandEntry ---
3490
Jeff Browna665ca82010-09-08 11:49:43 -07003491InputDispatcher::CommandEntry::CommandEntry() :
3492 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003493}
3494
3495InputDispatcher::CommandEntry::~CommandEntry() {
3496}
3497
Jeff Browne839a582010-04-22 18:58:52 -07003498
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003499// --- InputDispatcher::TouchState ---
3500
3501InputDispatcher::TouchState::TouchState() :
3502 down(false), split(false) {
3503}
3504
3505InputDispatcher::TouchState::~TouchState() {
3506}
3507
3508void InputDispatcher::TouchState::reset() {
3509 down = false;
3510 split = false;
3511 windows.clear();
3512}
3513
3514void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3515 down = other.down;
3516 split = other.split;
3517 windows.clear();
3518 windows.appendVector(other.windows);
3519}
3520
3521void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3522 int32_t targetFlags, BitSet32 pointerIds) {
3523 if (targetFlags & InputTarget::FLAG_SPLIT) {
3524 split = true;
3525 }
3526
3527 for (size_t i = 0; i < windows.size(); i++) {
3528 TouchedWindow& touchedWindow = windows.editItemAt(i);
3529 if (touchedWindow.window == window) {
3530 touchedWindow.targetFlags |= targetFlags;
3531 touchedWindow.pointerIds.value |= pointerIds.value;
3532 return;
3533 }
3534 }
3535
3536 windows.push();
3537
3538 TouchedWindow& touchedWindow = windows.editTop();
3539 touchedWindow.window = window;
3540 touchedWindow.targetFlags = targetFlags;
3541 touchedWindow.pointerIds = pointerIds;
3542 touchedWindow.channel = window->inputChannel;
3543}
3544
3545void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3546 for (size_t i = 0 ; i < windows.size(); ) {
3547 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3548 windows.removeAt(i);
3549 } else {
3550 i += 1;
3551 }
3552 }
3553}
3554
3555const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3556 for (size_t i = 0; i < windows.size(); i++) {
3557 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3558 return windows[i].window;
3559 }
3560 }
3561 return NULL;
3562}
3563
3564
Jeff Browne839a582010-04-22 18:58:52 -07003565// --- InputDispatcherThread ---
3566
3567InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3568 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3569}
3570
3571InputDispatcherThread::~InputDispatcherThread() {
3572}
3573
3574bool InputDispatcherThread::threadLoop() {
3575 mDispatcher->dispatchOnce();
3576 return true;
3577}
3578
3579} // namespace android