blob: b936c4d47044fd49c8ad88c0b8e1002850b1a8a1 [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 Brownfef5b042010-10-27 18:43:51 -07001308 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1309 mTempTouchState.reset();
1310
Jeff Brown53a415e2010-09-15 15:18:56 -07001311 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1312 updateDispatchStatisticsLocked(currentTime, entry,
1313 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001314#if DEBUG_FOCUS
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001315 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1316 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown53a415e2010-09-15 15:18:56 -07001317 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001318#endif
1319 return injectionResult;
1320}
1321
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001322void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1323 BitSet32 pointerIds) {
Jeff Browna665ca82010-09-08 11:49:43 -07001324 mCurrentInputTargets.push();
1325
1326 InputTarget& target = mCurrentInputTargets.editTop();
1327 target.inputChannel = window->inputChannel;
1328 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001329 target.xOffset = - window->frameLeft;
1330 target.yOffset = - window->frameTop;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001331 target.pointerIds = pointerIds;
Jeff Browna665ca82010-09-08 11:49:43 -07001332}
1333
1334void InputDispatcher::addMonitoringTargetsLocked() {
1335 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1336 mCurrentInputTargets.push();
1337
1338 InputTarget& target = mCurrentInputTargets.editTop();
1339 target.inputChannel = mMonitoringChannels[i];
1340 target.flags = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07001341 target.xOffset = 0;
1342 target.yOffset = 0;
1343 }
1344}
1345
1346bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001347 const InjectionState* injectionState) {
1348 if (injectionState
Jeff Brown90f0cee2010-10-08 22:31:17 -07001349 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1350 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1351 if (window) {
1352 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1353 "with input channel %s owned by uid %d",
1354 injectionState->injectorPid, injectionState->injectorUid,
1355 window->inputChannel->getName().string(),
1356 window->ownerUid);
1357 } else {
1358 LOGW("Permission denied: injecting event from pid %d uid %d",
1359 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-09-08 11:49:43 -07001360 }
Jeff Brown90f0cee2010-10-08 22:31:17 -07001361 return false;
Jeff Browna665ca82010-09-08 11:49:43 -07001362 }
1363 return true;
1364}
1365
Jeff Brown35cf0e92010-10-05 12:26:23 -07001366bool InputDispatcher::isWindowObscuredAtPointLocked(
1367 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Browna665ca82010-09-08 11:49:43 -07001368 size_t numWindows = mWindows.size();
1369 for (size_t i = 0; i < numWindows; i++) {
1370 const InputWindow* other = & mWindows.itemAt(i);
1371 if (other == window) {
1372 break;
1373 }
Jeff Brown35cf0e92010-10-05 12:26:23 -07001374 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001375 return true;
1376 }
1377 }
1378 return false;
1379}
1380
Jeff Brown53a415e2010-09-15 15:18:56 -07001381bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1382 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1383 if (connectionIndex >= 0) {
1384 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1385 return connection->outboundQueue.isEmpty();
1386 } else {
1387 return true;
1388 }
1389}
1390
1391String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1392 const InputWindow* window) {
1393 if (application) {
1394 if (window) {
1395 String8 label(application->name);
1396 label.append(" - ");
1397 label.append(window->name);
1398 return label;
1399 } else {
1400 return application->name;
1401 }
1402 } else if (window) {
1403 return window->name;
1404 } else {
1405 return String8("<unknown application or window>");
1406 }
1407}
1408
Jeff Brownef3a8232010-10-18 13:21:23 -07001409void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1410 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
1411 if (eventEntry->type == EventEntry::TYPE_MOTION) {
1412 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
1413 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1414 switch (motionEntry->action) {
1415 case AMOTION_EVENT_ACTION_DOWN:
1416 eventType = POWER_MANAGER_TOUCH_EVENT;
1417 break;
1418 case AMOTION_EVENT_ACTION_UP:
1419 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
1420 break;
1421 default:
1422 if (motionEntry->eventTime - motionEntry->downTime >= EVENT_IGNORE_DURATION) {
1423 eventType = POWER_MANAGER_TOUCH_EVENT;
1424 } else {
1425 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
1426 }
1427 break;
1428 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001429 }
1430 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001431
Jeff Browna665ca82010-09-08 11:49:43 -07001432 CommandEntry* commandEntry = postCommandLocked(
1433 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Brownef3a8232010-10-18 13:21:23 -07001434 commandEntry->eventTime = eventEntry->eventTime;
Jeff Browna665ca82010-09-08 11:49:43 -07001435 commandEntry->userActivityEventType = eventType;
1436}
1437
Jeff Brown51d45a72010-06-17 20:52:56 -07001438void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1439 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -07001440 bool resumeWithAppendedMotionSample) {
1441#if DEBUG_DISPATCH_CYCLE
Jeff Brown53a415e2010-09-15 15:18:56 -07001442 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001443 "xOffset=%f, yOffset=%f, "
1444 "windowType=%d, pointerIds=0x%x, "
1445 "resumeWithAppendedMotionSample=%s",
Jeff Brown53a415e2010-09-15 15:18:56 -07001446 connection->getInputChannelName(), inputTarget->flags,
Jeff Browne839a582010-04-22 18:58:52 -07001447 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001448 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Browna665ca82010-09-08 11:49:43 -07001449 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -07001450#endif
1451
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001452 // Make sure we are never called for streaming when splitting across multiple windows.
1453 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1454 assert(! (resumeWithAppendedMotionSample && isSplit));
1455
Jeff Browne839a582010-04-22 18:58:52 -07001456 // Skip this event if the connection status is not normal.
Jeff Brown53a415e2010-09-15 15:18:56 -07001457 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Browne839a582010-04-22 18:58:52 -07001458 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001459#if DEBUG_DISPATCH_CYCLE
1460 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Browna665ca82010-09-08 11:49:43 -07001461 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown90f0cee2010-10-08 22:31:17 -07001462#endif
Jeff Browne839a582010-04-22 18:58:52 -07001463 return;
1464 }
1465
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001466 // Split a motion event if needed.
1467 if (isSplit) {
1468 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1469
1470 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1471 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1472 MotionEntry* splitMotionEntry = splitMotionEvent(
1473 originalMotionEntry, inputTarget->pointerIds);
1474#if DEBUG_FOCUS
1475 LOGD("channel '%s' ~ Split motion event.",
1476 connection->getInputChannelName());
1477 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1478#endif
1479 eventEntry = splitMotionEntry;
1480 }
1481 }
1482
Jeff Browne839a582010-04-22 18:58:52 -07001483 // Resume the dispatch cycle with a freshly appended motion sample.
1484 // First we check that the last dispatch entry in the outbound queue is for the same
1485 // motion event to which we appended the motion sample. If we find such a dispatch
1486 // entry, and if it is currently in progress then we try to stream the new sample.
1487 bool wasEmpty = connection->outboundQueue.isEmpty();
1488
1489 if (! wasEmpty && resumeWithAppendedMotionSample) {
1490 DispatchEntry* motionEventDispatchEntry =
1491 connection->findQueuedDispatchEntryForEvent(eventEntry);
1492 if (motionEventDispatchEntry) {
1493 // If the dispatch entry is not in progress, then we must be busy dispatching an
1494 // earlier event. Not a problem, the motion event is on the outbound queue and will
1495 // be dispatched later.
1496 if (! motionEventDispatchEntry->inProgress) {
1497#if DEBUG_BATCHING
1498 LOGD("channel '%s' ~ Not streaming because the motion event has "
1499 "not yet been dispatched. "
1500 "(Waiting for earlier events to be consumed.)",
1501 connection->getInputChannelName());
1502#endif
1503 return;
1504 }
1505
1506 // If the dispatch entry is in progress but it already has a tail of pending
1507 // motion samples, then it must mean that the shared memory buffer filled up.
1508 // Not a problem, when this dispatch cycle is finished, we will eventually start
1509 // a new dispatch cycle to process the tail and that tail includes the newly
1510 // appended motion sample.
1511 if (motionEventDispatchEntry->tailMotionSample) {
1512#if DEBUG_BATCHING
1513 LOGD("channel '%s' ~ Not streaming because no new samples can "
1514 "be appended to the motion event in this dispatch cycle. "
1515 "(Waiting for next dispatch cycle to start.)",
1516 connection->getInputChannelName());
1517#endif
1518 return;
1519 }
1520
1521 // The dispatch entry is in progress and is still potentially open for streaming.
1522 // Try to stream the new motion sample. This might fail if the consumer has already
1523 // consumed the motion event (or if the channel is broken).
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001524 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1525 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Browne839a582010-04-22 18:58:52 -07001526 status_t status = connection->inputPublisher.appendMotionSample(
1527 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1528 if (status == OK) {
1529#if DEBUG_BATCHING
1530 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1531 connection->getInputChannelName());
1532#endif
1533 return;
1534 }
1535
1536#if DEBUG_BATCHING
1537 if (status == NO_MEMORY) {
1538 LOGD("channel '%s' ~ Could not append motion sample to currently "
1539 "dispatched move event because the shared memory buffer is full. "
1540 "(Waiting for next dispatch cycle to start.)",
1541 connection->getInputChannelName());
1542 } else if (status == status_t(FAILED_TRANSACTION)) {
1543 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown50de30a2010-06-22 01:27:15 -07001544 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-04-22 18:58:52 -07001545 "(Waiting for next dispatch cycle to start.)",
1546 connection->getInputChannelName());
1547 } else {
1548 LOGD("channel '%s' ~ Could not append motion sample to currently "
1549 "dispatched move event due to an error, status=%d. "
1550 "(Waiting for next dispatch cycle to start.)",
1551 connection->getInputChannelName(), status);
1552 }
1553#endif
1554 // Failed to stream. Start a new tail of pending motion samples to dispatch
1555 // in the next cycle.
1556 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1557 return;
1558 }
1559 }
1560
1561 // This is a new event.
1562 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Browna665ca82010-09-08 11:49:43 -07001563 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown53a415e2010-09-15 15:18:56 -07001564 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1565 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001566 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001567 }
1568
Jeff Browne839a582010-04-22 18:58:52 -07001569 // Handle the case where we could not stream a new motion sample because the consumer has
1570 // already consumed the motion event (otherwise the corresponding dispatch entry would
1571 // still be in the outbound queue for this connection). We set the head motion sample
1572 // to the list starting with the newly appended motion sample.
1573 if (resumeWithAppendedMotionSample) {
1574#if DEBUG_BATCHING
1575 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1576 "that cannot be streamed because the motion event has already been consumed.",
1577 connection->getInputChannelName());
1578#endif
1579 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1580 dispatchEntry->headMotionSample = appendedMotionSample;
1581 }
1582
1583 // Enqueue the dispatch entry.
1584 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1585
1586 // If the outbound queue was previously empty, start the dispatch cycle going.
1587 if (wasEmpty) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001588 activateConnectionLocked(connection.get());
Jeff Brown53a415e2010-09-15 15:18:56 -07001589 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001590 }
1591}
1592
Jeff Brown51d45a72010-06-17 20:52:56 -07001593void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown53a415e2010-09-15 15:18:56 -07001594 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001595#if DEBUG_DISPATCH_CYCLE
1596 LOGD("channel '%s' ~ startDispatchCycle",
1597 connection->getInputChannelName());
1598#endif
1599
1600 assert(connection->status == Connection::STATUS_NORMAL);
1601 assert(! connection->outboundQueue.isEmpty());
1602
Jeff Browna665ca82010-09-08 11:49:43 -07001603 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001604 assert(! dispatchEntry->inProgress);
1605
Jeff Browna665ca82010-09-08 11:49:43 -07001606 // Mark the dispatch entry as in progress.
1607 dispatchEntry->inProgress = true;
1608
1609 // Update the connection's input state.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001610 EventEntry* eventEntry = dispatchEntry->eventEntry;
1611 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001612
1613#if FILTER_INPUT_EVENTS
1614 // Filter out inconsistent sequences of input events.
1615 // The input system may drop or inject events in a way that could violate implicit
1616 // invariants on input state and potentially cause an application to crash
1617 // or think that a key or pointer is stuck down. Technically we make no guarantees
1618 // of consistency but it would be nice to improve on this where possible.
1619 // XXX: This code is a proof of concept only. Not ready for prime time.
1620 if (consistency == InputState::TOLERABLE) {
1621#if DEBUG_DISPATCH_CYCLE
1622 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1623 "current input state but that is likely to be tolerated by the application.",
1624 connection->getInputChannelName());
1625#endif
1626 } else if (consistency == InputState::BROKEN) {
1627 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1628 "current input state and that is likely to cause the application to crash.",
1629 connection->getInputChannelName());
1630 startNextDispatchCycleLocked(currentTime, connection);
1631 return;
1632 }
1633#endif
Jeff Browne839a582010-04-22 18:58:52 -07001634
1635 // Publish the event.
1636 status_t status;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001637 switch (eventEntry->type) {
Jeff Browne839a582010-04-22 18:58:52 -07001638 case EventEntry::TYPE_KEY: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001639 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001640
1641 // Apply target flags.
1642 int32_t action = keyEntry->action;
1643 int32_t flags = keyEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001644
1645 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001646 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-04-22 18:58:52 -07001647 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1648 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1649 keyEntry->eventTime);
1650
1651 if (status) {
1652 LOGE("channel '%s' ~ Could not publish key event, "
1653 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001654 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001655 return;
1656 }
1657 break;
1658 }
1659
1660 case EventEntry::TYPE_MOTION: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001661 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001662
1663 // Apply target flags.
1664 int32_t action = motionEntry->action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07001665 int32_t flags = motionEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001666 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001667 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -07001668 }
Jeff Brownaf30ff62010-09-01 17:01:00 -07001669 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1670 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1671 }
Jeff Browne839a582010-04-22 18:58:52 -07001672
1673 // If headMotionSample is non-NULL, then it points to the first new sample that we
1674 // were unable to dispatch during the previous cycle so we resume dispatching from
1675 // that point in the list of motion samples.
1676 // Otherwise, we just start from the first sample of the motion event.
1677 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1678 if (! firstMotionSample) {
1679 firstMotionSample = & motionEntry->firstSample;
1680 }
1681
Jeff Brownf26db0d2010-07-16 17:21:06 -07001682 // Set the X and Y offset depending on the input source.
1683 float xOffset, yOffset;
1684 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1685 xOffset = dispatchEntry->xOffset;
1686 yOffset = dispatchEntry->yOffset;
1687 } else {
1688 xOffset = 0.0f;
1689 yOffset = 0.0f;
1690 }
1691
Jeff Browne839a582010-04-22 18:58:52 -07001692 // Publish the motion event and the first motion sample.
1693 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001694 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -07001695 xOffset, yOffset,
Jeff Browne839a582010-04-22 18:58:52 -07001696 motionEntry->xPrecision, motionEntry->yPrecision,
1697 motionEntry->downTime, firstMotionSample->eventTime,
1698 motionEntry->pointerCount, motionEntry->pointerIds,
1699 firstMotionSample->pointerCoords);
1700
1701 if (status) {
1702 LOGE("channel '%s' ~ Could not publish motion event, "
1703 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001704 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001705 return;
1706 }
1707
1708 // Append additional motion samples.
1709 MotionSample* nextMotionSample = firstMotionSample->next;
1710 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1711 status = connection->inputPublisher.appendMotionSample(
1712 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1713 if (status == NO_MEMORY) {
1714#if DEBUG_DISPATCH_CYCLE
1715 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1716 "be sent in the next dispatch cycle.",
1717 connection->getInputChannelName());
1718#endif
1719 break;
1720 }
1721 if (status != OK) {
1722 LOGE("channel '%s' ~ Could not append motion sample "
1723 "for a reason other than out of memory, status=%d",
1724 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001725 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001726 return;
1727 }
1728 }
1729
1730 // Remember the next motion sample that we could not dispatch, in case we ran out
1731 // of space in the shared memory buffer.
1732 dispatchEntry->tailMotionSample = nextMotionSample;
1733 break;
1734 }
1735
1736 default: {
1737 assert(false);
1738 }
1739 }
1740
1741 // Send the dispatch signal.
1742 status = connection->inputPublisher.sendDispatchSignal();
1743 if (status) {
1744 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1745 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001746 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001747 return;
1748 }
1749
1750 // Record information about the newly started dispatch cycle.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001751 connection->lastEventTime = eventEntry->eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07001752 connection->lastDispatchTime = currentTime;
1753
Jeff Browne839a582010-04-22 18:58:52 -07001754 // Notify other system components.
1755 onDispatchCycleStartedLocked(currentTime, connection);
1756}
1757
Jeff Brown51d45a72010-06-17 20:52:56 -07001758void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1759 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001760#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001761 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -07001762 "%01.1fms since dispatch",
1763 connection->getInputChannelName(),
1764 connection->getEventLatencyMillis(currentTime),
1765 connection->getDispatchLatencyMillis(currentTime));
1766#endif
1767
Jeff Brown54bc2812010-06-15 01:31:58 -07001768 if (connection->status == Connection::STATUS_BROKEN
1769 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001770 return;
1771 }
1772
Jeff Brown53a415e2010-09-15 15:18:56 -07001773 // Notify other system components.
1774 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001775
1776 // Reset the publisher since the event has been consumed.
1777 // We do this now so that the publisher can release some of its internal resources
1778 // while waiting for the next dispatch cycle to begin.
1779 status_t status = connection->inputPublisher.reset();
1780 if (status) {
1781 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1782 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001783 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001784 return;
1785 }
1786
Jeff Browna665ca82010-09-08 11:49:43 -07001787 startNextDispatchCycleLocked(currentTime, connection);
1788}
1789
1790void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1791 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001792 // Start the next dispatch cycle for this connection.
1793 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001794 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001795 if (dispatchEntry->inProgress) {
1796 // Finish or resume current event in progress.
1797 if (dispatchEntry->tailMotionSample) {
1798 // We have a tail of undispatched motion samples.
1799 // Reuse the same DispatchEntry and start a new cycle.
1800 dispatchEntry->inProgress = false;
1801 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1802 dispatchEntry->tailMotionSample = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07001803 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001804 return;
1805 }
1806 // Finished.
1807 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001808 if (dispatchEntry->hasForegroundTarget()) {
1809 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001810 }
Jeff Browne839a582010-04-22 18:58:52 -07001811 mAllocator.releaseDispatchEntry(dispatchEntry);
1812 } else {
1813 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown53a415e2010-09-15 15:18:56 -07001814 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001815 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001816 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001817 return;
1818 }
1819 }
1820
1821 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001822 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001823}
1824
Jeff Brown90f0cee2010-10-08 22:31:17 -07001825void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1826 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001827#if DEBUG_DISPATCH_CYCLE
Jeff Brown90f0cee2010-10-08 22:31:17 -07001828 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001829 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001830#endif
1831
Jeff Browna665ca82010-09-08 11:49:43 -07001832 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001833 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001834
Jeff Brown90f0cee2010-10-08 22:31:17 -07001835 // The connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001836 // Ignore already broken or zombie connections.
Jeff Brown90f0cee2010-10-08 22:31:17 -07001837 if (connection->status == Connection::STATUS_NORMAL) {
1838 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001839
Jeff Brown90f0cee2010-10-08 22:31:17 -07001840 // Notify other system components.
1841 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001842 }
Jeff Browne839a582010-04-22 18:58:52 -07001843}
1844
Jeff Brown53a415e2010-09-15 15:18:56 -07001845void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1846 while (! connection->outboundQueue.isEmpty()) {
1847 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1848 if (dispatchEntry->hasForegroundTarget()) {
1849 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001850 }
1851 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001852 }
1853
Jeff Brown53a415e2010-09-15 15:18:56 -07001854 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001855}
1856
Jeff Brown59abe7e2010-09-13 23:17:30 -07001857int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-04-22 18:58:52 -07001858 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1859
1860 { // acquire lock
1861 AutoMutex _l(d->mLock);
1862
1863 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1864 if (connectionIndex < 0) {
1865 LOGE("Received spurious receive callback for unknown input channel. "
1866 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001867 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001868 }
1869
Jeff Brown51d45a72010-06-17 20:52:56 -07001870 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001871
1872 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001873 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-04-22 18:58:52 -07001874 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1875 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001876 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001877 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001878 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001879 }
1880
Jeff Brown59abe7e2010-09-13 23:17:30 -07001881 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001882 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1883 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001884 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001885 }
1886
1887 status_t status = connection->inputPublisher.receiveFinishedSignal();
1888 if (status) {
1889 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1890 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001891 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001892 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001893 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001894 }
1895
Jeff Brown51d45a72010-06-17 20:52:56 -07001896 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001897 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001898 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001899 } // release lock
1900}
1901
Jeff Brown90f0cee2010-10-08 22:31:17 -07001902void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1903 InputState::CancelationOptions options, const char* reason) {
1904 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1905 synthesizeCancelationEventsForConnectionLocked(
1906 mConnectionsByReceiveFd.valueAt(i), options, reason);
1907 }
1908}
1909
1910void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1911 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1912 const char* reason) {
1913 ssize_t index = getConnectionIndexLocked(channel);
1914 if (index >= 0) {
1915 synthesizeCancelationEventsForConnectionLocked(
1916 mConnectionsByReceiveFd.valueAt(index), options, reason);
1917 }
1918}
1919
1920void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1921 const sp<Connection>& connection, InputState::CancelationOptions options,
1922 const char* reason) {
1923 nsecs_t currentTime = now();
1924
1925 mTempCancelationEvents.clear();
1926 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1927 mTempCancelationEvents, options);
1928
1929 if (! mTempCancelationEvents.isEmpty()
1930 && connection->status != Connection::STATUS_BROKEN) {
1931#if DEBUG_OUTBOUND_EVENT_DETAILS
1932 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1933 "with reality: %s, options=%d.",
1934 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1935#endif
1936 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1937 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1938 switch (cancelationEventEntry->type) {
1939 case EventEntry::TYPE_KEY:
1940 logOutboundKeyDetailsLocked("cancel - ",
1941 static_cast<KeyEntry*>(cancelationEventEntry));
1942 break;
1943 case EventEntry::TYPE_MOTION:
1944 logOutboundMotionDetailsLocked("cancel - ",
1945 static_cast<MotionEntry*>(cancelationEventEntry));
1946 break;
1947 }
1948
1949 int32_t xOffset, yOffset;
1950 const InputWindow* window = getWindowLocked(connection->inputChannel);
1951 if (window) {
1952 xOffset = -window->frameLeft;
1953 yOffset = -window->frameTop;
1954 } else {
1955 xOffset = 0;
1956 yOffset = 0;
1957 }
1958
1959 DispatchEntry* cancelationDispatchEntry =
1960 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1961 0, xOffset, yOffset);
1962 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1963
1964 mAllocator.releaseEventEntry(cancelationEventEntry);
1965 }
1966
1967 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1968 startDispatchCycleLocked(currentTime, connection);
1969 }
1970 }
1971}
1972
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001973InputDispatcher::MotionEntry*
1974InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1975 assert(pointerIds.value != 0);
1976
1977 uint32_t splitPointerIndexMap[MAX_POINTERS];
1978 int32_t splitPointerIds[MAX_POINTERS];
1979 PointerCoords splitPointerCoords[MAX_POINTERS];
1980
1981 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1982 uint32_t splitPointerCount = 0;
1983
1984 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1985 originalPointerIndex++) {
1986 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1987 if (pointerIds.hasBit(pointerId)) {
1988 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1989 splitPointerIds[splitPointerCount] = pointerId;
1990 splitPointerCoords[splitPointerCount] =
1991 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1992 splitPointerCount += 1;
1993 }
1994 }
1995 assert(splitPointerCount == pointerIds.count());
1996
1997 int32_t action = originalMotionEntry->action;
1998 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1999 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2000 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2001 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2002 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2003 if (pointerIds.hasBit(pointerId)) {
2004 if (pointerIds.count() == 1) {
2005 // The first/last pointer went down/up.
2006 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2007 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brownffb16d62010-09-27 16:35:11 -07002008 } else {
2009 // A secondary pointer went down/up.
2010 uint32_t splitPointerIndex = 0;
2011 while (pointerId != splitPointerIds[splitPointerIndex]) {
2012 splitPointerIndex += 1;
2013 }
2014 action = maskedAction | (splitPointerIndex
2015 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002016 }
2017 } else {
2018 // An unrelated pointer changed.
2019 action = AMOTION_EVENT_ACTION_MOVE;
2020 }
2021 }
2022
2023 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2024 originalMotionEntry->eventTime,
2025 originalMotionEntry->deviceId,
2026 originalMotionEntry->source,
2027 originalMotionEntry->policyFlags,
2028 action,
2029 originalMotionEntry->flags,
2030 originalMotionEntry->metaState,
2031 originalMotionEntry->edgeFlags,
2032 originalMotionEntry->xPrecision,
2033 originalMotionEntry->yPrecision,
2034 originalMotionEntry->downTime,
2035 splitPointerCount, splitPointerIds, splitPointerCoords);
2036
2037 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2038 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2039 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2040 splitPointerIndex++) {
2041 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2042 splitPointerCoords[splitPointerIndex] =
2043 originalMotionSample->pointerCoords[originalPointerIndex];
2044 }
2045
2046 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2047 splitPointerCoords);
2048 }
2049
2050 return splitMotionEntry;
2051}
2052
Jeff Brown54bc2812010-06-15 01:31:58 -07002053void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002054#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -07002055 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07002056#endif
2057
Jeff Browna665ca82010-09-08 11:49:43 -07002058 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002059 { // acquire lock
2060 AutoMutex _l(mLock);
2061
Jeff Brown51d45a72010-06-17 20:52:56 -07002062 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browna665ca82010-09-08 11:49:43 -07002063 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002064 } // release lock
2065
Jeff Browna665ca82010-09-08 11:49:43 -07002066 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002067 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002068 }
2069}
2070
Jeff Brown5c1ed842010-07-14 18:48:53 -07002071void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -07002072 uint32_t policyFlags, int32_t action, int32_t flags,
2073 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2074#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002075 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07002076 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07002077 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -07002078 keyCode, scanCode, metaState, downTime);
2079#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002080 if (! validateKeyEvent(action)) {
2081 return;
2082 }
Jeff Browne839a582010-04-22 18:58:52 -07002083
Jeff Brown33d54ce2010-10-11 14:20:19 -07002084 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002085 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2086 keyCode, scanCode, /*byref*/ policyFlags);
2087
Jeff Browna665ca82010-09-08 11:49:43 -07002088 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002089 { // acquire lock
2090 AutoMutex _l(mLock);
2091
Jeff Brown51d45a72010-06-17 20:52:56 -07002092 int32_t repeatCount = 0;
2093 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002094 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07002095 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07002096
Jeff Browna665ca82010-09-08 11:49:43 -07002097 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002098 } // release lock
2099
Jeff Browna665ca82010-09-08 11:49:43 -07002100 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002101 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002102 }
2103}
2104
Jeff Brown5c1ed842010-07-14 18:48:53 -07002105void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002106 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002107 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2108 float xPrecision, float yPrecision, nsecs_t downTime) {
2109#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002110 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002111 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2112 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2113 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002114 xPrecision, yPrecision, downTime);
2115 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07002116 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002117 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07002118 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07002119 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-08-30 03:02:23 -07002120 pointerCoords[i].pressure, pointerCoords[i].size,
2121 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2122 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2123 pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -07002124 }
2125#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002126 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2127 return;
2128 }
Jeff Browne839a582010-04-22 18:58:52 -07002129
Jeff Brown33d54ce2010-10-11 14:20:19 -07002130 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002131 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2132
Jeff Browna665ca82010-09-08 11:49:43 -07002133 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002134 { // acquire lock
2135 AutoMutex _l(mLock);
2136
2137 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07002138 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07002139 // BATCHING CASE
2140 //
2141 // Try to append a move sample to the tail of the inbound queue for this device.
2142 // Give up if we encounter a non-move motion event for this device since that
2143 // means we cannot append any new samples until a new motion event has started.
Jeff Browna665ca82010-09-08 11:49:43 -07002144 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2145 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07002146 if (entry->type != EventEntry::TYPE_MOTION) {
2147 // Keep looking for motion events.
2148 continue;
2149 }
2150
2151 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2152 if (motionEntry->deviceId != deviceId) {
2153 // Keep looking for this device.
2154 continue;
2155 }
2156
Jeff Brown5c1ed842010-07-14 18:48:53 -07002157 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07002158 || motionEntry->pointerCount != pointerCount
2159 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07002160 // Last motion event in the queue for this device is not compatible for
2161 // appending new samples. Stop here.
2162 goto NoBatchingOrStreaming;
2163 }
2164
2165 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07002166 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07002167 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002168#if DEBUG_BATCHING
2169 LOGD("Appended motion sample onto batch for most recent "
2170 "motion event for this device in the inbound queue.");
2171#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07002172 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002173 }
2174
2175 // STREAMING CASE
2176 //
2177 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07002178 // Search the outbound queue for the current foreground targets to find a dispatched
2179 // motion event that is still in progress. If found, then, appen the new sample to
2180 // that event and push it out to all current targets. The logic in
2181 // prepareDispatchCycleLocked takes care of the case where some targets may
2182 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown54bc2812010-06-15 01:31:58 -07002183 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002184 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2185 const InputTarget& inputTarget = mCurrentInputTargets[i];
2186 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2187 // Skip non-foreground targets. We only want to stream if there is at
2188 // least one foreground target whose dispatch is still in progress.
2189 continue;
Jeff Browne839a582010-04-22 18:58:52 -07002190 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002191
2192 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2193 if (connectionIndex < 0) {
2194 // Connection must no longer be valid.
2195 continue;
2196 }
2197
2198 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2199 if (connection->outboundQueue.isEmpty()) {
2200 // This foreground target has an empty outbound queue.
2201 continue;
2202 }
2203
2204 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2205 if (! dispatchEntry->inProgress
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002206 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2207 || dispatchEntry->isSplit()) {
2208 // No motion event is being dispatched, or it is being split across
2209 // windows in which case we cannot stream.
Jeff Brown53a415e2010-09-15 15:18:56 -07002210 continue;
2211 }
2212
2213 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2214 dispatchEntry->eventEntry);
2215 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2216 || motionEntry->deviceId != deviceId
2217 || motionEntry->pointerCount != pointerCount
2218 || motionEntry->isInjected()) {
2219 // The motion event is not compatible with this move.
2220 continue;
2221 }
2222
2223 // Hurray! This foreground target is currently dispatching a move event
2224 // that we can stream onto. Append the motion sample and resume dispatch.
2225 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2226#if DEBUG_BATCHING
2227 LOGD("Appended motion sample onto batch for most recently dispatched "
2228 "motion event for this device in the outbound queues. "
2229 "Attempting to stream the motion sample.");
2230#endif
2231 nsecs_t currentTime = now();
2232 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2233 true /*resumeWithAppendedMotionSample*/);
2234
2235 runCommandsLockedInterruptible();
2236 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002237 }
2238 }
2239
2240NoBatchingOrStreaming:;
2241 }
2242
2243 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07002244 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002245 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002246 xPrecision, yPrecision, downTime,
2247 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002248
Jeff Browna665ca82010-09-08 11:49:43 -07002249 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002250 } // release lock
2251
Jeff Browna665ca82010-09-08 11:49:43 -07002252 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002253 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002254 }
2255}
2256
Jeff Brown90f0cee2010-10-08 22:31:17 -07002257void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2258 uint32_t policyFlags) {
2259#if DEBUG_INBOUND_EVENT_DETAILS
2260 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2261 switchCode, switchValue, policyFlags);
2262#endif
2263
Jeff Brown33d54ce2010-10-11 14:20:19 -07002264 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002265 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2266}
2267
Jeff Brown51d45a72010-06-17 20:52:56 -07002268int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07002269 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002270#if DEBUG_INBOUND_EVENT_DETAILS
2271 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002272 "syncMode=%d, timeoutMillis=%d",
2273 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07002274#endif
2275
2276 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brown33d54ce2010-10-11 14:20:19 -07002277
2278 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2279 if (hasInjectionPermission(injectorPid, injectorUid)) {
2280 policyFlags |= POLICY_FLAG_TRUSTED;
2281 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002282
Jeff Brown90f0cee2010-10-08 22:31:17 -07002283 EventEntry* injectedEntry;
2284 switch (event->getType()) {
2285 case AINPUT_EVENT_TYPE_KEY: {
2286 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2287 int32_t action = keyEvent->getAction();
2288 if (! validateKeyEvent(action)) {
Jeff Browna665ca82010-09-08 11:49:43 -07002289 return INPUT_EVENT_INJECTION_FAILED;
2290 }
2291
Jeff Brown90f0cee2010-10-08 22:31:17 -07002292 nsecs_t eventTime = keyEvent->getEventTime();
2293 int32_t deviceId = keyEvent->getDeviceId();
2294 int32_t flags = keyEvent->getFlags();
2295 int32_t keyCode = keyEvent->getKeyCode();
2296 int32_t scanCode = keyEvent->getScanCode();
Jeff Brown33d54ce2010-10-11 14:20:19 -07002297 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2298 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002299
Jeff Brown90f0cee2010-10-08 22:31:17 -07002300 mLock.lock();
2301 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2302 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2303 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2304 break;
2305 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002306
Jeff Brown90f0cee2010-10-08 22:31:17 -07002307 case AINPUT_EVENT_TYPE_MOTION: {
2308 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2309 int32_t action = motionEvent->getAction();
2310 size_t pointerCount = motionEvent->getPointerCount();
2311 const int32_t* pointerIds = motionEvent->getPointerIds();
2312 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2313 return INPUT_EVENT_INJECTION_FAILED;
2314 }
2315
2316 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown33d54ce2010-10-11 14:20:19 -07002317 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002318
2319 mLock.lock();
2320 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2321 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2322 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2323 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2324 action, motionEvent->getFlags(),
2325 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2326 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2327 motionEvent->getDownTime(), uint32_t(pointerCount),
2328 pointerIds, samplePointerCoords);
2329 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2330 sampleEventTimes += 1;
2331 samplePointerCoords += pointerCount;
2332 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2333 }
2334 injectedEntry = motionEntry;
2335 break;
2336 }
2337
2338 default:
2339 LOGW("Cannot inject event of type %d", event->getType());
2340 return INPUT_EVENT_INJECTION_FAILED;
2341 }
2342
2343 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2344 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2345 injectionState->injectionIsAsync = true;
2346 }
2347
2348 injectionState->refCount += 1;
2349 injectedEntry->injectionState = injectionState;
2350
2351 bool needWake = enqueueInboundEventLocked(injectedEntry);
2352 mLock.unlock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002353
Jeff Browna665ca82010-09-08 11:49:43 -07002354 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002355 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07002356 }
2357
2358 int32_t injectionResult;
2359 { // acquire lock
2360 AutoMutex _l(mLock);
2361
Jeff Brownf67c53e2010-07-28 15:48:59 -07002362 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2363 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2364 } else {
2365 for (;;) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002366 injectionResult = injectionState->injectionResult;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002367 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2368 break;
2369 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002370
Jeff Brown51d45a72010-06-17 20:52:56 -07002371 nsecs_t remainingTimeout = endTime - now();
2372 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002373#if DEBUG_INJECTION
2374 LOGD("injectInputEvent - Timed out waiting for injection result "
2375 "to become available.");
2376#endif
Jeff Brown51d45a72010-06-17 20:52:56 -07002377 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2378 break;
2379 }
2380
Jeff Brownf67c53e2010-07-28 15:48:59 -07002381 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2382 }
2383
2384 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2385 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002386 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002387#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002388 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002389 injectionState->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002390#endif
2391 nsecs_t remainingTimeout = endTime - now();
2392 if (remainingTimeout <= 0) {
2393#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002394 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002395 "dispatches to finish.");
2396#endif
2397 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2398 break;
2399 }
2400
2401 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2402 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002403 }
2404 }
2405
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002406 mAllocator.releaseInjectionState(injectionState);
Jeff Brown51d45a72010-06-17 20:52:56 -07002407 } // release lock
2408
Jeff Brownf67c53e2010-07-28 15:48:59 -07002409#if DEBUG_INJECTION
2410 LOGD("injectInputEvent - Finished with result %d. "
2411 "injectorPid=%d, injectorUid=%d",
2412 injectionResult, injectorPid, injectorUid);
2413#endif
2414
Jeff Brown51d45a72010-06-17 20:52:56 -07002415 return injectionResult;
2416}
2417
Jeff Brown90f0cee2010-10-08 22:31:17 -07002418bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2419 return injectorUid == 0
2420 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2421}
2422
Jeff Brown51d45a72010-06-17 20:52:56 -07002423void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002424 InjectionState* injectionState = entry->injectionState;
2425 if (injectionState) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002426#if DEBUG_INJECTION
2427 LOGD("Setting input event injection result to %d. "
2428 "injectorPid=%d, injectorUid=%d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002429 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002430#endif
2431
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002432 if (injectionState->injectionIsAsync) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002433 // Log the outcome since the injector did not wait for the injection result.
2434 switch (injectionResult) {
2435 case INPUT_EVENT_INJECTION_SUCCEEDED:
2436 LOGV("Asynchronous input event injection succeeded.");
2437 break;
2438 case INPUT_EVENT_INJECTION_FAILED:
2439 LOGW("Asynchronous input event injection failed.");
2440 break;
2441 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2442 LOGW("Asynchronous input event injection permission denied.");
2443 break;
2444 case INPUT_EVENT_INJECTION_TIMED_OUT:
2445 LOGW("Asynchronous input event injection timed out.");
2446 break;
2447 }
2448 }
2449
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002450 injectionState->injectionResult = injectionResult;
Jeff Brown51d45a72010-06-17 20:52:56 -07002451 mInjectionResultAvailableCondition.broadcast();
2452 }
2453}
2454
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002455void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2456 InjectionState* injectionState = entry->injectionState;
2457 if (injectionState) {
2458 injectionState->pendingForegroundDispatches += 1;
2459 }
2460}
2461
Jeff Brown53a415e2010-09-15 15:18:56 -07002462void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002463 InjectionState* injectionState = entry->injectionState;
2464 if (injectionState) {
2465 injectionState->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002466
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002467 if (injectionState->pendingForegroundDispatches == 0) {
2468 mInjectionSyncFinishedCondition.broadcast();
2469 }
Jeff Browna665ca82010-09-08 11:49:43 -07002470 }
2471}
2472
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002473const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2474 for (size_t i = 0; i < mWindows.size(); i++) {
2475 const InputWindow* window = & mWindows[i];
2476 if (window->inputChannel == inputChannel) {
2477 return window;
2478 }
2479 }
2480 return NULL;
2481}
2482
Jeff Browna665ca82010-09-08 11:49:43 -07002483void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2484#if DEBUG_FOCUS
2485 LOGD("setInputWindows");
2486#endif
2487 { // acquire lock
2488 AutoMutex _l(mLock);
2489
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002490 // Clear old window pointers.
Jeff Brown90f0cee2010-10-08 22:31:17 -07002491 sp<InputChannel> oldFocusedWindowChannel;
2492 if (mFocusedWindow) {
2493 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2494 mFocusedWindow = NULL;
2495 }
2496
Jeff Browna665ca82010-09-08 11:49:43 -07002497 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002498
2499 // Loop over new windows and rebuild the necessary window pointers for
2500 // tracking focus and touch.
Jeff Browna665ca82010-09-08 11:49:43 -07002501 mWindows.appendVector(inputWindows);
2502
2503 size_t numWindows = mWindows.size();
2504 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002505 const InputWindow* window = & mWindows.itemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07002506 if (window->hasFocus) {
2507 mFocusedWindow = window;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002508 break;
Jeff Browna665ca82010-09-08 11:49:43 -07002509 }
2510 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002511
Jeff Brown90f0cee2010-10-08 22:31:17 -07002512 if (oldFocusedWindowChannel != NULL) {
2513 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2514#if DEBUG_FOCUS
2515 LOGD("Focus left window: %s",
2516 oldFocusedWindowChannel->getName().string());
2517#endif
2518 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2519 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2520 oldFocusedWindowChannel.clear();
2521 }
2522 }
2523 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2524#if DEBUG_FOCUS
2525 LOGD("Focus entered window: %s",
2526 mFocusedWindow->inputChannel->getName().string());
2527#endif
2528 }
2529
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002530 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2531 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2532 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2533 if (window) {
2534 touchedWindow.window = window;
2535 i += 1;
2536 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -07002537#if DEBUG_FOCUS
2538 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2539#endif
Jeff Brown90f0cee2010-10-08 22:31:17 -07002540 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2541 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownb13d7b52010-10-15 16:20:51 -07002542 mTouchState.windows.removeAt(i);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002543 }
2544 }
Jeff Browna665ca82010-09-08 11:49:43 -07002545
Jeff Browna665ca82010-09-08 11:49:43 -07002546#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002547 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002548#endif
2549 } // release lock
2550
2551 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002552 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002553}
2554
2555void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2556#if DEBUG_FOCUS
2557 LOGD("setFocusedApplication");
2558#endif
2559 { // acquire lock
2560 AutoMutex _l(mLock);
2561
2562 releaseFocusedApplicationLocked();
2563
2564 if (inputApplication) {
2565 mFocusedApplicationStorage = *inputApplication;
2566 mFocusedApplication = & mFocusedApplicationStorage;
2567 }
2568
2569#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002570 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002571#endif
2572 } // release lock
2573
2574 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002575 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002576}
2577
2578void InputDispatcher::releaseFocusedApplicationLocked() {
2579 if (mFocusedApplication) {
2580 mFocusedApplication = NULL;
2581 mFocusedApplicationStorage.handle.clear();
2582 }
2583}
2584
2585void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2586#if DEBUG_FOCUS
2587 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2588#endif
2589
2590 bool changed;
2591 { // acquire lock
2592 AutoMutex _l(mLock);
2593
2594 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brownfef5b042010-10-27 18:43:51 -07002595 if (mDispatchFrozen && !frozen) {
Jeff Browna665ca82010-09-08 11:49:43 -07002596 resetANRTimeoutsLocked();
2597 }
2598
Jeff Brownfef5b042010-10-27 18:43:51 -07002599 if (mDispatchEnabled && !enabled) {
2600 resetAndDropEverythingLocked("dispatcher is being disabled");
2601 }
2602
Jeff Browna665ca82010-09-08 11:49:43 -07002603 mDispatchEnabled = enabled;
2604 mDispatchFrozen = frozen;
2605 changed = true;
2606 } else {
2607 changed = false;
2608 }
2609
2610#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002611 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002612#endif
2613 } // release lock
2614
2615 if (changed) {
2616 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002617 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002618 }
2619}
2620
Jeff Brown744c5592010-09-27 14:52:15 -07002621bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2622 const sp<InputChannel>& toChannel) {
2623#if DEBUG_FOCUS
2624 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2625 fromChannel->getName().string(), toChannel->getName().string());
2626#endif
2627 { // acquire lock
2628 AutoMutex _l(mLock);
2629
2630 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2631 const InputWindow* toWindow = getWindowLocked(toChannel);
2632 if (! fromWindow || ! toWindow) {
2633#if DEBUG_FOCUS
2634 LOGD("Cannot transfer focus because from or to window not found.");
2635#endif
2636 return false;
2637 }
2638 if (fromWindow == toWindow) {
2639#if DEBUG_FOCUS
2640 LOGD("Trivial transfer to same window.");
2641#endif
2642 return true;
2643 }
2644
2645 bool found = false;
2646 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2647 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2648 if (touchedWindow.window == fromWindow) {
2649 int32_t oldTargetFlags = touchedWindow.targetFlags;
2650 BitSet32 pointerIds = touchedWindow.pointerIds;
2651
2652 mTouchState.windows.removeAt(i);
2653
2654 int32_t newTargetFlags = 0;
2655 if (oldTargetFlags & InputTarget::FLAG_FOREGROUND) {
2656 newTargetFlags |= InputTarget::FLAG_FOREGROUND;
2657 if (toWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) {
2658 newTargetFlags |= InputTarget::FLAG_SPLIT;
2659 }
2660 }
2661 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2662
2663 found = true;
2664 break;
2665 }
2666 }
2667
2668 if (! found) {
2669#if DEBUG_FOCUS
2670 LOGD("Focus transfer failed because from window did not have focus.");
2671#endif
2672 return false;
2673 }
2674
Jeff Brownb6702e52010-10-11 18:32:20 -07002675 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2676 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2677 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2678 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2679 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2680
2681 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2682 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2683 InputState::CANCEL_POINTER_EVENTS,
2684 "transferring touch focus from this window to another window");
2685 }
2686
Jeff Brown744c5592010-09-27 14:52:15 -07002687#if DEBUG_FOCUS
2688 logDispatchStateLocked();
2689#endif
2690 } // release lock
2691
2692 // Wake up poll loop since it may need to make new input dispatching choices.
2693 mLooper->wake();
2694 return true;
2695}
2696
Jeff Brownfef5b042010-10-27 18:43:51 -07002697void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2698#if DEBUG_FOCUS
2699 LOGD("Resetting and dropping all events (%s).", reason);
2700#endif
2701
2702 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2703
2704 resetKeyRepeatLocked();
2705 releasePendingEventLocked();
2706 drainInboundQueueLocked();
2707 resetTargetsLocked();
2708
2709 mTouchState.reset();
2710}
2711
Jeff Browna665ca82010-09-08 11:49:43 -07002712void InputDispatcher::logDispatchStateLocked() {
2713 String8 dump;
2714 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002715
2716 char* text = dump.lockBuffer(dump.size());
2717 char* start = text;
2718 while (*start != '\0') {
2719 char* end = strchr(start, '\n');
2720 if (*end == '\n') {
2721 *(end++) = '\0';
2722 }
2723 LOGD("%s", start);
2724 start = end;
2725 }
Jeff Browna665ca82010-09-08 11:49:43 -07002726}
2727
2728void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002729 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2730 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002731
2732 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002733 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002734 mFocusedApplication->name.string(),
2735 mFocusedApplication->dispatchingTimeout / 1000000.0);
2736 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002737 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002738 }
Jeff Brown2806e382010-10-01 17:46:21 -07002739 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002740 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-10-01 17:46:21 -07002741
2742 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2743 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2744 if (!mTouchState.windows.isEmpty()) {
2745 dump.append(INDENT "TouchedWindows:\n");
2746 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2747 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2748 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2749 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2750 touchedWindow.targetFlags);
2751 }
2752 } else {
2753 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002754 }
2755
Jeff Brown2806e382010-10-01 17:46:21 -07002756 if (!mWindows.isEmpty()) {
2757 dump.append(INDENT "Windows:\n");
2758 for (size_t i = 0; i < mWindows.size(); i++) {
2759 const InputWindow& window = mWindows[i];
2760 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2761 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2762 "frame=[%d,%d][%d,%d], "
2763 "visibleFrame=[%d,%d][%d,%d], "
2764 "touchableArea=[%d,%d][%d,%d], "
2765 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2766 i, window.name.string(),
2767 toString(window.paused),
2768 toString(window.hasFocus),
2769 toString(window.hasWallpaper),
2770 toString(window.visible),
2771 toString(window.canReceiveKeys),
2772 window.layoutParamsFlags, window.layoutParamsType,
2773 window.layer,
2774 window.frameLeft, window.frameTop,
2775 window.frameRight, window.frameBottom,
2776 window.visibleFrameLeft, window.visibleFrameTop,
2777 window.visibleFrameRight, window.visibleFrameBottom,
2778 window.touchableAreaLeft, window.touchableAreaTop,
2779 window.touchableAreaRight, window.touchableAreaBottom,
2780 window.ownerPid, window.ownerUid,
2781 window.dispatchingTimeout / 1000000.0);
2782 }
2783 } else {
2784 dump.append(INDENT "Windows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002785 }
2786
Jeff Brown2806e382010-10-01 17:46:21 -07002787 if (!mMonitoringChannels.isEmpty()) {
2788 dump.append(INDENT "MonitoringChannels:\n");
2789 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2790 const sp<InputChannel>& channel = mMonitoringChannels[i];
2791 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2792 }
2793 } else {
2794 dump.append(INDENT "MonitoringChannels: <none>\n");
2795 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002796
Jeff Brown2806e382010-10-01 17:46:21 -07002797 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2798
2799 if (!mActiveConnections.isEmpty()) {
2800 dump.append(INDENT "ActiveConnections:\n");
2801 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2802 const Connection* connection = mActiveConnections[i];
Jeff Brown53f291e2010-10-25 17:37:46 -07002803 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brown90f0cee2010-10-08 22:31:17 -07002804 "inputState.isNeutral=%s\n",
Jeff Brown2806e382010-10-01 17:46:21 -07002805 i, connection->getInputChannelName(), connection->getStatusLabel(),
2806 connection->outboundQueue.count(),
Jeff Brown90f0cee2010-10-08 22:31:17 -07002807 toString(connection->inputState.isNeutral()));
Jeff Brown2806e382010-10-01 17:46:21 -07002808 }
2809 } else {
2810 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002811 }
2812
2813 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002814 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002815 (mAppSwitchDueTime - now()) / 1000000.0);
2816 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002817 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002818 }
2819}
2820
2821status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002822#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002823 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2824 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002825#endif
2826
Jeff Browne839a582010-04-22 18:58:52 -07002827 { // acquire lock
2828 AutoMutex _l(mLock);
2829
Jeff Brown53a415e2010-09-15 15:18:56 -07002830 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002831 LOGW("Attempted to register already registered input channel '%s'",
2832 inputChannel->getName().string());
2833 return BAD_VALUE;
2834 }
2835
2836 sp<Connection> connection = new Connection(inputChannel);
2837 status_t status = connection->initialize();
2838 if (status) {
2839 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2840 inputChannel->getName().string(), status);
2841 return status;
2842 }
2843
Jeff Brown0cacb872010-08-17 15:59:26 -07002844 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002845 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002846
Jeff Browna665ca82010-09-08 11:49:43 -07002847 if (monitor) {
2848 mMonitoringChannels.push(inputChannel);
2849 }
2850
Jeff Brown59abe7e2010-09-13 23:17:30 -07002851 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002852
Jeff Brown54bc2812010-06-15 01:31:58 -07002853 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002854 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002855 return OK;
2856}
2857
2858status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002859#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002860 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002861#endif
2862
Jeff Browne839a582010-04-22 18:58:52 -07002863 { // acquire lock
2864 AutoMutex _l(mLock);
2865
Jeff Brown53a415e2010-09-15 15:18:56 -07002866 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002867 if (connectionIndex < 0) {
2868 LOGW("Attempted to unregister already unregistered input channel '%s'",
2869 inputChannel->getName().string());
2870 return BAD_VALUE;
2871 }
2872
2873 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2874 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2875
2876 connection->status = Connection::STATUS_ZOMBIE;
2877
Jeff Browna665ca82010-09-08 11:49:43 -07002878 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2879 if (mMonitoringChannels[i] == inputChannel) {
2880 mMonitoringChannels.removeAt(i);
2881 break;
2882 }
2883 }
2884
Jeff Brown59abe7e2010-09-13 23:17:30 -07002885 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002886
Jeff Brown51d45a72010-06-17 20:52:56 -07002887 nsecs_t currentTime = now();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002888 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002889
2890 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002891 } // release lock
2892
Jeff Browne839a582010-04-22 18:58:52 -07002893 // Wake the poll loop because removing the connection may have changed the current
2894 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002895 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002896 return OK;
2897}
2898
Jeff Brown53a415e2010-09-15 15:18:56 -07002899ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002900 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2901 if (connectionIndex >= 0) {
2902 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2903 if (connection->inputChannel.get() == inputChannel.get()) {
2904 return connectionIndex;
2905 }
2906 }
2907
2908 return -1;
2909}
2910
Jeff Browne839a582010-04-22 18:58:52 -07002911void InputDispatcher::activateConnectionLocked(Connection* connection) {
2912 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2913 if (mActiveConnections.itemAt(i) == connection) {
2914 return;
2915 }
2916 }
2917 mActiveConnections.add(connection);
2918}
2919
2920void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2921 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2922 if (mActiveConnections.itemAt(i) == connection) {
2923 mActiveConnections.removeAt(i);
2924 return;
2925 }
2926 }
2927}
2928
Jeff Brown54bc2812010-06-15 01:31:58 -07002929void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002930 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002931}
2932
Jeff Brown54bc2812010-06-15 01:31:58 -07002933void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002934 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002935}
2936
Jeff Brown54bc2812010-06-15 01:31:58 -07002937void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002938 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002939 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2940 connection->getInputChannelName());
2941
Jeff Brown54bc2812010-06-15 01:31:58 -07002942 CommandEntry* commandEntry = postCommandLocked(
2943 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002944 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002945}
2946
Jeff Brown53a415e2010-09-15 15:18:56 -07002947void InputDispatcher::onANRLocked(
2948 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2949 nsecs_t eventTime, nsecs_t waitStartTime) {
2950 LOGI("Application is not responding: %s. "
2951 "%01.1fms since event, %01.1fms since wait started",
2952 getApplicationWindowLabelLocked(application, window).string(),
2953 (currentTime - eventTime) / 1000000.0,
2954 (currentTime - waitStartTime) / 1000000.0);
2955
2956 CommandEntry* commandEntry = postCommandLocked(
2957 & InputDispatcher::doNotifyANRLockedInterruptible);
2958 if (application) {
2959 commandEntry->inputApplicationHandle = application->handle;
2960 }
2961 if (window) {
2962 commandEntry->inputChannel = window->inputChannel;
2963 }
2964}
2965
Jeff Browna665ca82010-09-08 11:49:43 -07002966void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2967 CommandEntry* commandEntry) {
2968 mLock.unlock();
2969
2970 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2971
2972 mLock.lock();
2973}
2974
Jeff Brown54bc2812010-06-15 01:31:58 -07002975void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2976 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002977 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002978
Jeff Brown51d45a72010-06-17 20:52:56 -07002979 if (connection->status != Connection::STATUS_ZOMBIE) {
2980 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002981
Jeff Brown51d45a72010-06-17 20:52:56 -07002982 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2983
2984 mLock.lock();
2985 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002986}
2987
Jeff Brown53a415e2010-09-15 15:18:56 -07002988void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002989 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002990 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002991
Jeff Brown53a415e2010-09-15 15:18:56 -07002992 nsecs_t newTimeout = mPolicy->notifyANR(
2993 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002994
Jeff Brown53a415e2010-09-15 15:18:56 -07002995 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002996
Jeff Brown53a415e2010-09-15 15:18:56 -07002997 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002998}
2999
Jeff Browna665ca82010-09-08 11:49:43 -07003000void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3001 CommandEntry* commandEntry) {
3002 KeyEntry* entry = commandEntry->keyEntry;
3003 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3004 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3005 entry->downTime, entry->eventTime);
3006
3007 mLock.unlock();
3008
3009 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
3010 & mReusableKeyEvent, entry->policyFlags);
3011
3012 mLock.lock();
3013
3014 entry->interceptKeyResult = consumed
3015 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
3016 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3017 mAllocator.releaseKeyEntry(entry);
3018}
3019
3020void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3021 mLock.unlock();
3022
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003023 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07003024
3025 mLock.lock();
3026}
3027
Jeff Brown53a415e2010-09-15 15:18:56 -07003028void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3029 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3030 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07003031}
3032
3033void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07003034 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07003035 dumpDispatchStateLocked(dump);
3036}
3037
Jeff Brown54bc2812010-06-15 01:31:58 -07003038
Jeff Brown53a415e2010-09-15 15:18:56 -07003039// --- InputDispatcher::Queue ---
3040
3041template <typename T>
3042uint32_t InputDispatcher::Queue<T>::count() const {
3043 uint32_t result = 0;
3044 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3045 result += 1;
3046 }
3047 return result;
3048}
3049
3050
Jeff Browne839a582010-04-22 18:58:52 -07003051// --- InputDispatcher::Allocator ---
3052
3053InputDispatcher::Allocator::Allocator() {
3054}
3055
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003056InputDispatcher::InjectionState*
3057InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3058 InjectionState* injectionState = mInjectionStatePool.alloc();
3059 injectionState->refCount = 1;
3060 injectionState->injectorPid = injectorPid;
3061 injectionState->injectorUid = injectorUid;
3062 injectionState->injectionIsAsync = false;
3063 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3064 injectionState->pendingForegroundDispatches = 0;
3065 return injectionState;
3066}
3067
Jeff Brown51d45a72010-06-17 20:52:56 -07003068void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brown90f0cee2010-10-08 22:31:17 -07003069 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown51d45a72010-06-17 20:52:56 -07003070 entry->type = type;
3071 entry->refCount = 1;
3072 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07003073 entry->eventTime = eventTime;
Jeff Brown90f0cee2010-10-08 22:31:17 -07003074 entry->policyFlags = policyFlags;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003075 entry->injectionState = NULL;
3076}
3077
3078void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3079 if (entry->injectionState) {
3080 releaseInjectionState(entry->injectionState);
3081 entry->injectionState = NULL;
3082 }
Jeff Brown51d45a72010-06-17 20:52:56 -07003083}
3084
Jeff Browne839a582010-04-22 18:58:52 -07003085InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07003086InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003087 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003088 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Browne839a582010-04-22 18:58:52 -07003089 return entry;
3090}
3091
Jeff Brown51d45a72010-06-17 20:52:56 -07003092InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07003093 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07003094 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3095 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003096 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003097 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003098
3099 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003100 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003101 entry->action = action;
3102 entry->flags = flags;
3103 entry->keyCode = keyCode;
3104 entry->scanCode = scanCode;
3105 entry->metaState = metaState;
3106 entry->repeatCount = repeatCount;
3107 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07003108 entry->syntheticRepeat = false;
3109 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07003110 return entry;
3111}
3112
Jeff Brown51d45a72010-06-17 20:52:56 -07003113InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07003114 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07003115 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3116 nsecs_t downTime, uint32_t pointerCount,
3117 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003118 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003119 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003120
3121 entry->eventTime = eventTime;
3122 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003123 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003124 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07003125 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07003126 entry->metaState = metaState;
3127 entry->edgeFlags = edgeFlags;
3128 entry->xPrecision = xPrecision;
3129 entry->yPrecision = yPrecision;
3130 entry->downTime = downTime;
3131 entry->pointerCount = pointerCount;
3132 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07003133 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07003134 entry->lastSample = & entry->firstSample;
3135 for (uint32_t i = 0; i < pointerCount; i++) {
3136 entry->pointerIds[i] = pointerIds[i];
3137 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3138 }
Jeff Browne839a582010-04-22 18:58:52 -07003139 return entry;
3140}
3141
3142InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07003143 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07003144 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07003145 DispatchEntry* entry = mDispatchEntryPool.alloc();
3146 entry->eventEntry = eventEntry;
3147 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07003148 entry->targetFlags = targetFlags;
3149 entry->xOffset = xOffset;
3150 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07003151 entry->inProgress = false;
3152 entry->headMotionSample = NULL;
3153 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07003154 return entry;
3155}
3156
Jeff Brown54bc2812010-06-15 01:31:58 -07003157InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3158 CommandEntry* entry = mCommandEntryPool.alloc();
3159 entry->command = command;
3160 return entry;
3161}
3162
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003163void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3164 injectionState->refCount -= 1;
3165 if (injectionState->refCount == 0) {
3166 mInjectionStatePool.free(injectionState);
3167 } else {
3168 assert(injectionState->refCount > 0);
3169 }
3170}
3171
Jeff Browne839a582010-04-22 18:58:52 -07003172void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3173 switch (entry->type) {
3174 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3175 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3176 break;
3177 case EventEntry::TYPE_KEY:
3178 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3179 break;
3180 case EventEntry::TYPE_MOTION:
3181 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3182 break;
3183 default:
3184 assert(false);
3185 break;
3186 }
3187}
3188
3189void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3190 ConfigurationChangedEntry* entry) {
3191 entry->refCount -= 1;
3192 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003193 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003194 mConfigurationChangeEntryPool.free(entry);
3195 } else {
3196 assert(entry->refCount > 0);
3197 }
3198}
3199
3200void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3201 entry->refCount -= 1;
3202 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003203 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003204 mKeyEntryPool.free(entry);
3205 } else {
3206 assert(entry->refCount > 0);
3207 }
3208}
3209
3210void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3211 entry->refCount -= 1;
3212 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003213 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -07003214 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3215 MotionSample* next = sample->next;
3216 mMotionSamplePool.free(sample);
3217 sample = next;
3218 }
Jeff Browne839a582010-04-22 18:58:52 -07003219 mMotionEntryPool.free(entry);
3220 } else {
3221 assert(entry->refCount > 0);
3222 }
3223}
3224
3225void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3226 releaseEventEntry(entry->eventEntry);
3227 mDispatchEntryPool.free(entry);
3228}
3229
Jeff Brown54bc2812010-06-15 01:31:58 -07003230void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3231 mCommandEntryPool.free(entry);
3232}
3233
Jeff Browne839a582010-04-22 18:58:52 -07003234void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003235 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003236 MotionSample* sample = mMotionSamplePool.alloc();
3237 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003238 uint32_t pointerCount = motionEntry->pointerCount;
3239 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07003240 sample->pointerCoords[i] = pointerCoords[i];
3241 }
3242
3243 sample->next = NULL;
3244 motionEntry->lastSample->next = sample;
3245 motionEntry->lastSample = sample;
3246}
3247
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003248void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3249 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003250
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003251 keyEntry->dispatchInProgress = false;
3252 keyEntry->syntheticRepeat = false;
3253 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003254}
3255
3256
Jeff Brown542412c2010-08-18 15:51:08 -07003257// --- InputDispatcher::MotionEntry ---
3258
3259uint32_t InputDispatcher::MotionEntry::countSamples() const {
3260 uint32_t count = 1;
3261 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3262 count += 1;
3263 }
3264 return count;
3265}
3266
Jeff Browna665ca82010-09-08 11:49:43 -07003267
3268// --- InputDispatcher::InputState ---
3269
Jeff Brown90f0cee2010-10-08 22:31:17 -07003270InputDispatcher::InputState::InputState() {
Jeff Browna665ca82010-09-08 11:49:43 -07003271}
3272
3273InputDispatcher::InputState::~InputState() {
3274}
3275
3276bool InputDispatcher::InputState::isNeutral() const {
3277 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3278}
3279
Jeff Browna665ca82010-09-08 11:49:43 -07003280InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3281 const EventEntry* entry) {
3282 switch (entry->type) {
3283 case EventEntry::TYPE_KEY:
3284 return trackKey(static_cast<const KeyEntry*>(entry));
3285
3286 case EventEntry::TYPE_MOTION:
3287 return trackMotion(static_cast<const MotionEntry*>(entry));
3288
3289 default:
3290 return CONSISTENT;
3291 }
3292}
3293
3294InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3295 const KeyEntry* entry) {
3296 int32_t action = entry->action;
3297 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3298 KeyMemento& memento = mKeyMementos.editItemAt(i);
3299 if (memento.deviceId == entry->deviceId
3300 && memento.source == entry->source
3301 && memento.keyCode == entry->keyCode
3302 && memento.scanCode == entry->scanCode) {
3303 switch (action) {
3304 case AKEY_EVENT_ACTION_UP:
3305 mKeyMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003306 return CONSISTENT;
3307
3308 case AKEY_EVENT_ACTION_DOWN:
3309 return TOLERABLE;
3310
3311 default:
3312 return BROKEN;
3313 }
3314 }
3315 }
3316
3317 switch (action) {
3318 case AKEY_EVENT_ACTION_DOWN: {
3319 mKeyMementos.push();
3320 KeyMemento& memento = mKeyMementos.editTop();
3321 memento.deviceId = entry->deviceId;
3322 memento.source = entry->source;
3323 memento.keyCode = entry->keyCode;
3324 memento.scanCode = entry->scanCode;
3325 memento.downTime = entry->downTime;
3326 return CONSISTENT;
3327 }
3328
3329 default:
3330 return BROKEN;
3331 }
3332}
3333
3334InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3335 const MotionEntry* entry) {
3336 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3337 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3338 MotionMemento& memento = mMotionMementos.editItemAt(i);
3339 if (memento.deviceId == entry->deviceId
3340 && memento.source == entry->source) {
3341 switch (action) {
3342 case AMOTION_EVENT_ACTION_UP:
3343 case AMOTION_EVENT_ACTION_CANCEL:
3344 mMotionMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003345 return CONSISTENT;
3346
3347 case AMOTION_EVENT_ACTION_DOWN:
3348 return TOLERABLE;
3349
3350 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3351 if (entry->pointerCount == memento.pointerCount + 1) {
3352 memento.setPointers(entry);
3353 return CONSISTENT;
3354 }
3355 return BROKEN;
3356
3357 case AMOTION_EVENT_ACTION_POINTER_UP:
3358 if (entry->pointerCount == memento.pointerCount - 1) {
3359 memento.setPointers(entry);
3360 return CONSISTENT;
3361 }
3362 return BROKEN;
3363
3364 case AMOTION_EVENT_ACTION_MOVE:
3365 if (entry->pointerCount == memento.pointerCount) {
3366 return CONSISTENT;
3367 }
3368 return BROKEN;
3369
3370 default:
3371 return BROKEN;
3372 }
3373 }
3374 }
3375
3376 switch (action) {
3377 case AMOTION_EVENT_ACTION_DOWN: {
3378 mMotionMementos.push();
3379 MotionMemento& memento = mMotionMementos.editTop();
3380 memento.deviceId = entry->deviceId;
3381 memento.source = entry->source;
3382 memento.xPrecision = entry->xPrecision;
3383 memento.yPrecision = entry->yPrecision;
3384 memento.downTime = entry->downTime;
3385 memento.setPointers(entry);
3386 return CONSISTENT;
3387 }
3388
3389 default:
3390 return BROKEN;
3391 }
3392}
3393
3394void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3395 pointerCount = entry->pointerCount;
3396 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3397 pointerIds[i] = entry->pointerIds[i];
3398 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3399 }
3400}
3401
Jeff Brown90f0cee2010-10-08 22:31:17 -07003402void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3403 Allocator* allocator, Vector<EventEntry*>& outEvents,
3404 CancelationOptions options) {
3405 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003406 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003407 if (shouldCancelEvent(memento.source, options)) {
3408 outEvents.push(allocator->obtainKeyEntry(currentTime,
3409 memento.deviceId, memento.source, 0,
3410 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3411 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3412 mKeyMementos.removeAt(i);
3413 } else {
3414 i += 1;
3415 }
Jeff Browna665ca82010-09-08 11:49:43 -07003416 }
3417
Jeff Brown316237d2010-10-11 18:22:53 -07003418 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003419 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003420 if (shouldCancelEvent(memento.source, options)) {
3421 outEvents.push(allocator->obtainMotionEntry(currentTime,
3422 memento.deviceId, memento.source, 0,
3423 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3424 memento.xPrecision, memento.yPrecision, memento.downTime,
3425 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3426 mMotionMementos.removeAt(i);
3427 } else {
3428 i += 1;
3429 }
Jeff Browna665ca82010-09-08 11:49:43 -07003430 }
3431}
3432
3433void InputDispatcher::InputState::clear() {
3434 mKeyMementos.clear();
3435 mMotionMementos.clear();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003436}
3437
Jeff Brownb6702e52010-10-11 18:32:20 -07003438void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3439 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3440 const MotionMemento& memento = mMotionMementos.itemAt(i);
3441 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3442 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3443 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3444 if (memento.deviceId == otherMemento.deviceId
3445 && memento.source == otherMemento.source) {
3446 other.mMotionMementos.removeAt(j);
3447 } else {
3448 j += 1;
3449 }
3450 }
3451 other.mMotionMementos.push(memento);
3452 }
3453 }
3454}
3455
Jeff Brown90f0cee2010-10-08 22:31:17 -07003456bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3457 CancelationOptions options) {
3458 switch (options) {
3459 case CANCEL_POINTER_EVENTS:
3460 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3461 case CANCEL_NON_POINTER_EVENTS:
3462 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3463 default:
3464 return true;
3465 }
Jeff Browna665ca82010-09-08 11:49:43 -07003466}
3467
3468
Jeff Browne839a582010-04-22 18:58:52 -07003469// --- InputDispatcher::Connection ---
3470
3471InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3472 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003473 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003474}
3475
3476InputDispatcher::Connection::~Connection() {
3477}
3478
3479status_t InputDispatcher::Connection::initialize() {
3480 return inputPublisher.initialize();
3481}
3482
Jeff Brown54bc2812010-06-15 01:31:58 -07003483const char* InputDispatcher::Connection::getStatusLabel() const {
3484 switch (status) {
3485 case STATUS_NORMAL:
3486 return "NORMAL";
3487
3488 case STATUS_BROKEN:
3489 return "BROKEN";
3490
Jeff Brown54bc2812010-06-15 01:31:58 -07003491 case STATUS_ZOMBIE:
3492 return "ZOMBIE";
3493
3494 default:
3495 return "UNKNOWN";
3496 }
3497}
3498
Jeff Browne839a582010-04-22 18:58:52 -07003499InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3500 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003501 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3502 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003503 if (dispatchEntry->eventEntry == eventEntry) {
3504 return dispatchEntry;
3505 }
3506 }
3507 return NULL;
3508}
3509
Jeff Browna665ca82010-09-08 11:49:43 -07003510
Jeff Brown54bc2812010-06-15 01:31:58 -07003511// --- InputDispatcher::CommandEntry ---
3512
Jeff Browna665ca82010-09-08 11:49:43 -07003513InputDispatcher::CommandEntry::CommandEntry() :
3514 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003515}
3516
3517InputDispatcher::CommandEntry::~CommandEntry() {
3518}
3519
Jeff Browne839a582010-04-22 18:58:52 -07003520
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003521// --- InputDispatcher::TouchState ---
3522
3523InputDispatcher::TouchState::TouchState() :
3524 down(false), split(false) {
3525}
3526
3527InputDispatcher::TouchState::~TouchState() {
3528}
3529
3530void InputDispatcher::TouchState::reset() {
3531 down = false;
3532 split = false;
3533 windows.clear();
3534}
3535
3536void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3537 down = other.down;
3538 split = other.split;
3539 windows.clear();
3540 windows.appendVector(other.windows);
3541}
3542
3543void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3544 int32_t targetFlags, BitSet32 pointerIds) {
3545 if (targetFlags & InputTarget::FLAG_SPLIT) {
3546 split = true;
3547 }
3548
3549 for (size_t i = 0; i < windows.size(); i++) {
3550 TouchedWindow& touchedWindow = windows.editItemAt(i);
3551 if (touchedWindow.window == window) {
3552 touchedWindow.targetFlags |= targetFlags;
3553 touchedWindow.pointerIds.value |= pointerIds.value;
3554 return;
3555 }
3556 }
3557
3558 windows.push();
3559
3560 TouchedWindow& touchedWindow = windows.editTop();
3561 touchedWindow.window = window;
3562 touchedWindow.targetFlags = targetFlags;
3563 touchedWindow.pointerIds = pointerIds;
3564 touchedWindow.channel = window->inputChannel;
3565}
3566
3567void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3568 for (size_t i = 0 ; i < windows.size(); ) {
3569 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3570 windows.removeAt(i);
3571 } else {
3572 i += 1;
3573 }
3574 }
3575}
3576
3577const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3578 for (size_t i = 0; i < windows.size(); i++) {
3579 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3580 return windows[i].window;
3581 }
3582 }
3583 return NULL;
3584}
3585
3586
Jeff Browne839a582010-04-22 18:58:52 -07003587// --- InputDispatcherThread ---
3588
3589InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3590 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3591}
3592
3593InputDispatcherThread::~InputDispatcherThread() {
3594}
3595
3596bool InputDispatcherThread::threadLoop() {
3597 mDispatcher->dispatchOnce();
3598 return true;
3599}
3600
3601} // namespace android