blob: 46baf9d14fe20efeafbc819001e04b9181df6033 [file] [log] [blame]
Jeff Brown46b9ac02010-04-22 18:58:52 -07001//
2// Copyright 2010 The Android Open Source Project
3//
4// The input dispatcher.
5//
6#define LOG_TAG "InputDispatcher"
7
8//#define LOG_NDEBUG 0
9
10// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070011#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070012
13// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070014#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070015
16// Log debug messages about batching.
Jeff Brown349703e2010-06-22 01:27:15 -070017#define DEBUG_BATCHING 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070018
19// Log debug messages about the dispatch cycle.
Jeff Brown349703e2010-06-22 01:27:15 -070020#define DEBUG_DISPATCH_CYCLE 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070021
Jeff Brown9c3cda02010-06-15 01:31:58 -070022// Log debug messages about registrations.
Jeff Brown349703e2010-06-22 01:27:15 -070023#define DEBUG_REGISTRATION 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070024
Jeff Brown46b9ac02010-04-22 18:58:52 -070025// Log debug messages about performance statistics.
Jeff Brown349703e2010-06-22 01:27:15 -070026#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070027
Jeff Brown7fbdc842010-06-17 20:52:56 -070028// Log debug messages about input event injection.
Jeff Brown349703e2010-06-22 01:27:15 -070029#define DEBUG_INJECTION 0
Jeff Brown7fbdc842010-06-17 20:52:56 -070030
Jeff Brownae9fc032010-08-18 15:51:08 -070031// Log debug messages about input event throttling.
32#define DEBUG_THROTTLING 0
33
Jeff Brownb88102f2010-09-08 11:49:43 -070034// Log debug messages about input focus tracking.
35#define DEBUG_FOCUS 0
36
37// Log debug messages about the app switch latency optimization.
38#define DEBUG_APP_SWITCH 0
39
Jeff Brown46b9ac02010-04-22 18:58:52 -070040#include <cutils/log.h>
41#include <ui/InputDispatcher.h>
Jeff Brownb88102f2010-09-08 11:49:43 -070042#include <ui/PowerManager.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070043
44#include <stddef.h>
45#include <unistd.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070046#include <errno.h>
47#include <limits.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070048
Jeff Brownf2f487182010-10-01 17:46:21 -070049#define INDENT " "
50#define INDENT2 " "
51
Jeff Brown46b9ac02010-04-22 18:58:52 -070052namespace android {
53
Jeff Browna87ea462010-11-01 20:35:46 -070054// Delay before reporting long touch events to the power manager.
55const nsecs_t LONG_TOUCH_DELAY = 300 * 1000000LL; // 300 ms
Jeff Brownb88102f2010-09-08 11:49:43 -070056
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 Brown46b9ac02010-04-22 18:58:52 -070066
Jeff Brown7fbdc842010-06-17 20:52:56 -070067static inline nsecs_t now() {
68 return systemTime(SYSTEM_TIME_MONOTONIC);
69}
70
Jeff Brownb88102f2010-09-08 11:49:43 -070071static inline const char* toString(bool value) {
72 return value ? "true" : "false";
73}
74
Jeff Brown01ce2e92010-09-26 22:20:12 -070075static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
76 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
77 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
78}
79
80static bool isValidKeyAction(int32_t action) {
81 switch (action) {
82 case AKEY_EVENT_ACTION_DOWN:
83 case AKEY_EVENT_ACTION_UP:
84 return true;
85 default:
86 return false;
87 }
88}
89
90static bool validateKeyEvent(int32_t action) {
91 if (! isValidKeyAction(action)) {
92 LOGE("Key event has invalid action code 0x%x", action);
93 return false;
94 }
95 return true;
96}
97
Jeff Brownb6997262010-10-08 22:31:17 -070098static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brown01ce2e92010-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 Brown01ce2e92010-09-26 22:20:12 -0700104 case AMOTION_EVENT_ACTION_OUTSIDE:
105 return true;
Jeff Brownb6997262010-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 Brown01ce2e92010-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 Brownb6997262010-10-08 22:31:17 -0700118 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brown01ce2e92010-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 Brownc3db8582010-10-20 15:33:38 -0700127 BitSet32 pointerIdBits;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700128 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownc3db8582010-10-20 15:33:38 -0700129 int32_t id = pointerIds[i];
130 if (id < 0 || id > MAX_POINTER_ID) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700131 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
Jeff Brownc3db8582010-10-20 15:33:38 -0700132 id, MAX_POINTER_ID);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700133 return false;
134 }
Jeff Brownc3db8582010-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 Brown01ce2e92010-09-26 22:20:12 -0700140 }
141 return true;
142}
143
Jeff Brownb88102f2010-09-08 11:49:43 -0700144
145// --- InputWindow ---
146
Jeff Brownb88102f2010-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 Brown19dfc832010-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 Brown2d3f1592010-10-15 00:54:27 -0700159 || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
160 || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
Jeff Brown19dfc832010-10-05 12:26:23 -0700161}
162
Jeff Brownb88102f2010-09-08 11:49:43 -0700163
Jeff Brown46b9ac02010-04-22 18:58:52 -0700164// --- InputDispatcher ---
165
Jeff Brown9c3cda02010-06-15 01:31:58 -0700166InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Brownb88102f2010-09-08 11:49:43 -0700167 mPolicy(policy),
168 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
169 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brown01ce2e92010-09-26 22:20:12 -0700170 mFocusedWindow(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700171 mFocusedApplication(NULL),
172 mCurrentInputTargetsValid(false),
173 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700174 mLooper = new Looper(false);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700175
Jeff Brownb88102f2010-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 Brown46b9ac02010-04-22 18:58:52 -0700179
Jeff Brownb88102f2010-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 Brown46b9ac02010-04-22 18:58:52 -0700183
184 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700185
Jeff Brownae9fc032010-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 Brown46b9ac02010-04-22 18:58:52 -0700194}
195
196InputDispatcher::~InputDispatcher() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700197 { // acquire lock
198 AutoMutex _l(mLock);
199
200 resetKeyRepeatLocked();
Jeff Brown54a18252010-09-16 14:07:33 -0700201 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700202 drainInboundQueueLocked();
203 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700204
205 while (mConnectionsByReceiveFd.size() != 0) {
206 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
207 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700208}
209
210void InputDispatcher::dispatchOnce() {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700211 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700212 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700213
Jeff Brown46b9ac02010-04-22 18:58:52 -0700214 nsecs_t nextWakeupTime = LONG_LONG_MAX;
215 { // acquire lock
216 AutoMutex _l(mLock);
Jeff Brownb88102f2010-09-08 11:49:43 -0700217 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700218
Jeff Brownb88102f2010-09-08 11:49:43 -0700219 if (runCommandsLockedInterruptible()) {
220 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Brown46b9ac02010-04-22 18:58:52 -0700221 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700222 } // release lock
223
Jeff Brownb88102f2010-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 Brown4fe6c3e2010-09-13 23:17:30 -0700235 mLooper->pollOnce(timeoutMillis);
Jeff Brownb88102f2010-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 Brownb88102f2010-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 Brownb88102f2010-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 Brownb6997262010-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 Brownb88102f2010-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 Browne2fe69e2010-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 Brownb88102f2010-09-08 11:49:43 -0700355 }
356
357 // Now we have an event to dispatch.
358 assert(mPendingEvent != NULL);
Jeff Brown54a18252010-09-16 14:07:33 -0700359 bool done = false;
Jeff Brownb6997262010-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 Brownb88102f2010-09-08 11:49:43 -0700366 switch (mPendingEvent->type) {
367 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
368 ConfigurationChangedEntry* typedEntry =
369 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700370 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brownb6997262010-10-08 22:31:17 -0700371 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Brownb88102f2010-09-08 11:49:43 -0700372 break;
373 }
374
375 case EventEntry::TYPE_KEY: {
376 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700377 if (isAppSwitchDue) {
378 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700379 resetPendingAppSwitchLocked(true);
Jeff Brownb6997262010-10-08 22:31:17 -0700380 isAppSwitchDue = false;
381 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
382 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700383 }
384 }
Jeff Brownb6997262010-10-08 22:31:17 -0700385 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Brownb931a1b2010-10-11 14:20:19 -0700386 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700387 break;
388 }
389
390 case EventEntry::TYPE_MOTION: {
391 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700392 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
393 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700394 }
Jeff Brownb6997262010-10-08 22:31:17 -0700395 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Brownb931a1b2010-10-11 14:20:19 -0700396 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700397 break;
398 }
399
400 default:
401 assert(false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700402 break;
403 }
404
Jeff Brown54a18252010-09-16 14:07:33 -0700405 if (done) {
Jeff Brownb6997262010-10-08 22:31:17 -0700406 if (dropReason != DROP_REASON_NOT_DROPPED) {
407 dropInboundEventLocked(mPendingEvent, dropReason);
408 }
409
Jeff Brown54a18252010-09-16 14:07:33 -0700410 releasePendingEventLocked();
Jeff Brownb88102f2010-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 Brownb6997262010-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 Brownb88102f2010-09-08 11:49:43 -0700436 break;
437 }
Jeff Brownb6997262010-10-08 22:31:17 -0700438 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700439
440 return needWake;
441}
442
Jeff Brownb6997262010-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 Brownb931a1b2010-10-11 14:20:19 -0700447#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown3122e442010-10-11 23:32:49 -0700448 LOGD("Dropped event because policy consumed it.");
Jeff Brownb931a1b2010-10-11 14:20:19 -0700449#endif
Jeff Brown3122e442010-10-11 23:32:49 -0700450 reason = "inbound event was dropped because the policy consumed it";
Jeff Brownb6997262010-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 Brownb88102f2010-09-08 11:49:43 -0700485 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
486}
487
Jeff Brownb6997262010-10-08 22:31:17 -0700488bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
489 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
490 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Brownb931a1b2010-10-11 14:20:19 -0700491 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brownb6997262010-10-08 22:31:17 -0700492 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
493}
494
Jeff Brownb88102f2010-09-08 11:49:43 -0700495bool InputDispatcher::isAppSwitchPendingLocked() {
496 return mAppSwitchDueTime != LONG_LONG_MAX;
497}
498
Jeff Brownb88102f2010-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 Brown46b9ac02010-04-22 18:58:52 -0700509}
510
Jeff Brown9c3cda02010-06-15 01:31:58 -0700511bool InputDispatcher::runCommandsLockedInterruptible() {
512 if (mCommandQueue.isEmpty()) {
513 return false;
514 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700515
Jeff Brown9c3cda02010-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 Brown7fbdc842010-06-17 20:52:56 -0700522 commandEntry->connection.clear();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700523 mAllocator.releaseCommandEntry(commandEntry);
524 } while (! mCommandQueue.isEmpty());
525 return true;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700526}
527
Jeff Brown9c3cda02010-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 Brownb88102f2010-09-08 11:49:43 -0700534void InputDispatcher::drainInboundQueueLocked() {
535 while (! mInboundQueue.isEmpty()) {
536 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700537 releaseInboundEventLocked(entry);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700538 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700539}
540
Jeff Brown54a18252010-09-16 14:07:33 -0700541void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700542 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700543 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700544 mPendingEvent = NULL;
545 }
546}
547
Jeff Brown54a18252010-09-16 14:07:33 -0700548void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700549 InjectionState* injectionState = entry->injectionState;
550 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700551#if DEBUG_DISPATCH_CYCLE
Jeff Brown01ce2e92010-09-26 22:20:12 -0700552 LOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700553#endif
554 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
555 }
556 mAllocator.releaseEventEntry(entry);
557}
558
Jeff Brownb88102f2010-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 Brownb21fb102010-09-07 10:44:57 -0700567 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown349703e2010-06-22 01:27:15 -0700568 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
569
Jeff Brown349703e2010-06-22 01:27:15 -0700570 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brownb931a1b2010-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 Brown46b9ac02010-04-22 18:58:52 -0700573 if (entry->refCount == 1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700574 mAllocator.recycleKeyEntry(entry);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700575 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700576 entry->policyFlags = policyFlags;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700577 entry->repeatCount += 1;
578 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700579 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700580 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700581 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700582 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700583
584 mKeyRepeatState.lastKeyEntry = newEntry;
585 mAllocator.releaseKeyEntry(entry);
586
587 entry = newEntry;
588 }
Jeff Brownb88102f2010-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 Brown46b9ac02010-04-22 18:58:52 -0700594
Jeff Brownb21fb102010-09-07 10:44:57 -0700595 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700596 return entry;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700597}
598
Jeff Brownb88102f2010-09-08 11:49:43 -0700599bool InputDispatcher::dispatchConfigurationChangedLocked(
600 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700601#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownb88102f2010-09-08 11:49:43 -0700602 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
603#endif
604
605 // Reset key repeating in case a keyboard device was added or removed or something.
606 resetKeyRepeatLocked();
607
608 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
609 CommandEntry* commandEntry = postCommandLocked(
610 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
611 commandEntry->eventTime = entry->eventTime;
612 return true;
613}
614
615bool InputDispatcher::dispatchKeyLocked(
616 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brownb931a1b2010-10-11 14:20:19 -0700617 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brownb27b8c02010-11-02 17:58:22 -0700618 // Preprocessing.
619 if (! entry->dispatchInProgress) {
620 if (entry->repeatCount == 0
621 && entry->action == AKEY_EVENT_ACTION_DOWN
622 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
623 && !entry->isInjected()) {
624 if (mKeyRepeatState.lastKeyEntry
625 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
626 // We have seen two identical key downs in a row which indicates that the device
627 // driver is automatically generating key repeats itself. We take note of the
628 // repeat here, but we disable our own next key repeat timer since it is clear that
629 // we will not need to synthesize key repeats ourselves.
630 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
631 resetKeyRepeatLocked();
632 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
633 } else {
634 // Not a repeat. Save key down state in case we do see a repeat later.
635 resetKeyRepeatLocked();
636 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
637 }
638 mKeyRepeatState.lastKeyEntry = entry;
639 entry->refCount += 1;
640 } else if (! entry->syntheticRepeat) {
641 resetKeyRepeatLocked();
642 }
643
Jeff Brown59fd13c2011-03-02 20:49:06 -0800644 if (entry->repeatCount == 1) {
645 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
646 } else {
647 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
648 }
649
Jeff Brownb27b8c02010-11-02 17:58:22 -0700650 entry->dispatchInProgress = true;
651 resetTargetsLocked();
652
653 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
654 }
655
Jeff Brown54a18252010-09-16 14:07:33 -0700656 // Give the policy a chance to intercept the key.
657 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Brownb931a1b2010-10-11 14:20:19 -0700658 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brown54a18252010-09-16 14:07:33 -0700659 CommandEntry* commandEntry = postCommandLocked(
660 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Brownb931a1b2010-10-11 14:20:19 -0700661 if (mFocusedWindow) {
Jeff Brown54a18252010-09-16 14:07:33 -0700662 commandEntry->inputChannel = mFocusedWindow->inputChannel;
663 }
664 commandEntry->keyEntry = entry;
665 entry->refCount += 1;
666 return false; // wait for the command to run
667 } else {
668 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
669 }
670 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Brownb931a1b2010-10-11 14:20:19 -0700671 if (*dropReason == DROP_REASON_NOT_DROPPED) {
672 *dropReason = DROP_REASON_POLICY;
673 }
Jeff Brown54a18252010-09-16 14:07:33 -0700674 }
675
676 // Clean up if dropping the event.
Jeff Brownb931a1b2010-10-11 14:20:19 -0700677 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700678 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700679 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
680 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700681 return true;
682 }
683
Jeff Brownb88102f2010-09-08 11:49:43 -0700684 // Identify targets.
685 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700686 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
687 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700688 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
689 return false;
690 }
691
692 setInjectionResultLocked(entry, injectionResult);
693 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
694 return true;
695 }
696
697 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700698 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700699 }
700
701 // Dispatch the key.
702 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700703 return true;
704}
705
706void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
707#if DEBUG_OUTBOUND_EVENT_DETAILS
708 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
709 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
Jeff Brownb27b8c02010-11-02 17:58:22 -0700710 "repeatCount=%d, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700711 prefix,
712 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
713 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Jeff Brownb27b8c02010-11-02 17:58:22 -0700714 entry->repeatCount, entry->downTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700715#endif
716}
717
718bool InputDispatcher::dispatchMotionLocked(
Jeff Brownb931a1b2010-10-11 14:20:19 -0700719 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brownb27b8c02010-11-02 17:58:22 -0700720 // Preprocessing.
721 if (! entry->dispatchInProgress) {
722 entry->dispatchInProgress = true;
723 resetTargetsLocked();
724
725 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
726 }
727
Jeff Brown54a18252010-09-16 14:07:33 -0700728 // Clean up if dropping the event.
Jeff Brownb931a1b2010-10-11 14:20:19 -0700729 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700730 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700731 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
732 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700733 return true;
734 }
735
Jeff Brownb88102f2010-09-08 11:49:43 -0700736 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
737
738 // Identify targets.
739 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700740 int32_t injectionResult;
741 if (isPointerEvent) {
742 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700743 injectionResult = findTouchedWindowTargetsLocked(currentTime,
744 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700745 } else {
746 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700747 injectionResult = findFocusedWindowTargetsLocked(currentTime,
748 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700749 }
750 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
751 return false;
752 }
753
754 setInjectionResultLocked(entry, injectionResult);
755 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
756 return true;
757 }
758
759 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700760 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700761 }
762
763 // Dispatch the motion.
764 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700765 return true;
766}
767
768
769void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
770#if DEBUG_OUTBOUND_EVENT_DETAILS
771 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700772 "action=0x%x, flags=0x%x, "
Jeff Brown46b9ac02010-04-22 18:58:52 -0700773 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700774 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700775 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
776 entry->action, entry->flags,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700777 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
778 entry->downTime);
779
780 // Print the most recent sample that we have available, this may change due to batching.
781 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700782 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700783 for (; sample->next != NULL; sample = sample->next) {
784 sampleCount += 1;
785 }
786 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -0700787 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700788 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700789 "orientation=%f",
Jeff Brown46b9ac02010-04-22 18:58:52 -0700790 i, entry->pointerIds[i],
Jeff Brown8d608662010-08-30 03:02:23 -0700791 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
792 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
793 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
794 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
795 sample->pointerCoords[i].orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700796 }
797
798 // Keep in mind that due to batching, it is possible for the number of samples actually
799 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700800 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700801 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
802 }
803#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -0700804}
805
806void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
807 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
808#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -0700809 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac02010-04-22 18:58:52 -0700810 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700811 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac02010-04-22 18:58:52 -0700812#endif
813
Jeff Brown9c3cda02010-06-15 01:31:58 -0700814 assert(eventEntry->dispatchInProgress); // should already have been set to true
815
Jeff Browne2fe69e2010-10-18 13:21:23 -0700816 pokeUserActivityLocked(eventEntry);
817
Jeff Brown46b9ac02010-04-22 18:58:52 -0700818 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
819 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
820
Jeff Brown519e0242010-09-15 15:18:56 -0700821 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700822 if (connectionIndex >= 0) {
823 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700824 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700825 resumeWithAppendedMotionSample);
826 } else {
Jeff Brownb6997262010-10-08 22:31:17 -0700827#if DEBUG_FOCUS
828 LOGD("Dropping event delivery to target with channel '%s' because it "
829 "is no longer registered with the input dispatcher.",
Jeff Brown46b9ac02010-04-22 18:58:52 -0700830 inputTarget.inputChannel->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -0700831#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -0700832 }
833 }
834}
835
Jeff Brown54a18252010-09-16 14:07:33 -0700836void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700837 mCurrentInputTargetsValid = false;
838 mCurrentInputTargets.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700839 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
840}
841
Jeff Brown01ce2e92010-09-26 22:20:12 -0700842void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700843 mCurrentInputTargetsValid = true;
844}
845
846int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
847 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
848 nsecs_t* nextWakeupTime) {
849 if (application == NULL && window == NULL) {
850 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
851#if DEBUG_FOCUS
852 LOGD("Waiting for system to become ready for input.");
853#endif
854 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
855 mInputTargetWaitStartTime = currentTime;
856 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
857 mInputTargetWaitTimeoutExpired = false;
858 }
859 } else {
860 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
861#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700862 LOGD("Waiting for application to become ready for input: %s",
863 getApplicationWindowLabelLocked(application, window).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700864#endif
865 nsecs_t timeout = window ? window->dispatchingTimeout :
866 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
867
868 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
869 mInputTargetWaitStartTime = currentTime;
870 mInputTargetWaitTimeoutTime = currentTime + timeout;
871 mInputTargetWaitTimeoutExpired = false;
872 }
873 }
874
875 if (mInputTargetWaitTimeoutExpired) {
876 return INPUT_EVENT_INJECTION_TIMED_OUT;
877 }
878
879 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown519e0242010-09-15 15:18:56 -0700880 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700881
882 // Force poll loop to wake up immediately on next iteration once we get the
883 // ANR response back from the policy.
884 *nextWakeupTime = LONG_LONG_MIN;
885 return INPUT_EVENT_INJECTION_PENDING;
886 } else {
887 // Force poll loop to wake up when timeout is due.
888 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
889 *nextWakeupTime = mInputTargetWaitTimeoutTime;
890 }
891 return INPUT_EVENT_INJECTION_PENDING;
892 }
893}
894
Jeff Brown519e0242010-09-15 15:18:56 -0700895void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
896 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700897 if (newTimeout > 0) {
898 // Extend the timeout.
899 mInputTargetWaitTimeoutTime = now() + newTimeout;
900 } else {
901 // Give up.
902 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -0700903
Jeff Brown01ce2e92010-09-26 22:20:12 -0700904 // Release the touch targets.
905 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -0700906
Jeff Brown519e0242010-09-15 15:18:56 -0700907 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -0700908 if (inputChannel.get()) {
909 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
910 if (connectionIndex >= 0) {
911 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brownb6997262010-10-08 22:31:17 -0700912 synthesizeCancelationEventsForConnectionLocked(
913 connection, InputState::CANCEL_ALL_EVENTS,
914 "application not responding");
Jeff Browndc3e0052010-09-16 11:02:16 -0700915 }
Jeff Brown519e0242010-09-15 15:18:56 -0700916 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700917 }
918}
919
Jeff Brown519e0242010-09-15 15:18:56 -0700920nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -0700921 nsecs_t currentTime) {
922 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
923 return currentTime - mInputTargetWaitStartTime;
924 }
925 return 0;
926}
927
928void InputDispatcher::resetANRTimeoutsLocked() {
929#if DEBUG_FOCUS
930 LOGD("Resetting ANR timeouts.");
931#endif
932
Jeff Brownb88102f2010-09-08 11:49:43 -0700933 // Reset input target wait timeout.
934 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
935}
936
Jeff Brown01ce2e92010-09-26 22:20:12 -0700937int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
938 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700939 mCurrentInputTargets.clear();
940
941 int32_t injectionResult;
942
943 // If there is no currently focused window and no focused application
944 // then drop the event.
945 if (! mFocusedWindow) {
946 if (mFocusedApplication) {
947#if DEBUG_FOCUS
948 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -0700949 "focused application that may eventually add a window: %s.",
950 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700951#endif
952 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
953 mFocusedApplication, NULL, nextWakeupTime);
954 goto Unresponsive;
955 }
956
957 LOGI("Dropping event because there is no focused window or focused application.");
958 injectionResult = INPUT_EVENT_INJECTION_FAILED;
959 goto Failed;
960 }
961
962 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700963 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700964 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
965 goto Failed;
966 }
967
968 // If the currently focused window is paused then keep waiting.
969 if (mFocusedWindow->paused) {
970#if DEBUG_FOCUS
971 LOGD("Waiting because focused window is paused.");
972#endif
973 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
974 mFocusedApplication, mFocusedWindow, nextWakeupTime);
975 goto Unresponsive;
976 }
977
Jeff Brown519e0242010-09-15 15:18:56 -0700978 // If the currently focused window is still working on previous events then keep waiting.
979 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
980#if DEBUG_FOCUS
981 LOGD("Waiting because focused window still processing previous input.");
982#endif
983 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
984 mFocusedApplication, mFocusedWindow, nextWakeupTime);
985 goto Unresponsive;
986 }
987
Jeff Brownb88102f2010-09-08 11:49:43 -0700988 // Success! Output targets.
989 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700990 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -0700991
992 // Done.
993Failed:
994Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -0700995 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
996 updateDispatchStatisticsLocked(currentTime, entry,
997 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -0700998#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700999 LOGD("findFocusedWindow finished: injectionResult=%d, "
1000 "timeSpendWaitingForApplication=%0.1fms",
1001 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001002#endif
1003 return injectionResult;
1004}
1005
Jeff Brown01ce2e92010-09-26 22:20:12 -07001006int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1007 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001008 enum InjectionPermission {
1009 INJECTION_PERMISSION_UNKNOWN,
1010 INJECTION_PERMISSION_GRANTED,
1011 INJECTION_PERMISSION_DENIED
1012 };
1013
Jeff Brownb88102f2010-09-08 11:49:43 -07001014 mCurrentInputTargets.clear();
1015
1016 nsecs_t startTime = now();
1017
1018 // For security reasons, we defer updating the touch state until we are sure that
1019 // event injection will be allowed.
1020 //
1021 // FIXME In the original code, screenWasOff could never be set to true.
1022 // The reason is that the POLICY_FLAG_WOKE_HERE
1023 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1024 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1025 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1026 // events upon which no preprocessing took place. So policyFlags was always 0.
1027 // In the new native input dispatcher we're a bit more careful about event
1028 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1029 // Unfortunately we obtain undesirable behavior.
1030 //
1031 // Here's what happens:
1032 //
1033 // When the device dims in anticipation of going to sleep, touches
1034 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1035 // the device to brighten and reset the user activity timer.
1036 // Touches on other windows (such as the launcher window)
1037 // are dropped. Then after a moment, the device goes to sleep. Oops.
1038 //
1039 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1040 // instead of POLICY_FLAG_WOKE_HERE...
1041 //
1042 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1043
1044 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001045 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001046
1047 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001048 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1049 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1050 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1051 mTempTouchState.reset();
1052 mTempTouchState.down = true;
1053 } else {
1054 mTempTouchState.copyFrom(mTouchState);
1055 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001056
Jeff Brown01ce2e92010-09-26 22:20:12 -07001057 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1058 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1059 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1060 /* Case 1: New splittable pointer going down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001061
Jeff Brown01ce2e92010-09-26 22:20:12 -07001062 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1063 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1064 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1065 const InputWindow* newTouchedWindow = NULL;
1066 const InputWindow* topErrorWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07001067
1068 // Traverse windows from front to back to find touched window and outside targets.
1069 size_t numWindows = mWindows.size();
1070 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001071 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001072 int32_t flags = window->layoutParamsFlags;
1073
1074 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1075 if (! topErrorWindow) {
1076 topErrorWindow = window;
1077 }
1078 }
1079
1080 if (window->visible) {
1081 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1082 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1083 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1084 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1085 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1086 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001087 }
1088 break; // found touched window, exit window loop
1089 }
1090 }
1091
Jeff Brown01ce2e92010-09-26 22:20:12 -07001092 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1093 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001094 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1095 if (isWindowObscuredAtPointLocked(window, x, y)) {
1096 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1097 }
1098
1099 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001100 }
1101 }
1102 }
1103
1104 // If there is an error window but it is not taking focus (typically because
1105 // it is invisible) then wait for it. Any other focused window may in
1106 // fact be in ANR state.
1107 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1108#if DEBUG_FOCUS
1109 LOGD("Waiting because system error window is pending.");
1110#endif
1111 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1112 NULL, NULL, nextWakeupTime);
1113 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1114 goto Unresponsive;
1115 }
1116
Jeff Brown01ce2e92010-09-26 22:20:12 -07001117 // Figure out whether splitting will be allowed for this window.
Jeff Brownaeec2bf2010-09-28 13:24:41 -07001118 if (newTouchedWindow
1119 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001120 // New window supports splitting.
1121 isSplit = true;
1122 } else if (isSplit) {
1123 // New window does not support splitting but we have already split events.
1124 // Assign the pointer to the first foreground window we find.
1125 // (May be NULL which is why we put this code block before the next check.)
1126 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1127 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001128
Jeff Brownb88102f2010-09-08 11:49:43 -07001129 // If we did not find a touched window then fail.
1130 if (! newTouchedWindow) {
1131 if (mFocusedApplication) {
1132#if DEBUG_FOCUS
1133 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001134 "focused application that may eventually add a new window: %s.",
1135 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001136#endif
1137 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1138 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001139 goto Unresponsive;
1140 }
1141
1142 LOGI("Dropping event because there is no touched window or focused application.");
1143 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001144 goto Failed;
1145 }
1146
Jeff Brown19dfc832010-10-05 12:26:23 -07001147 // Set target flags.
1148 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1149 if (isSplit) {
1150 targetFlags |= InputTarget::FLAG_SPLIT;
1151 }
1152 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1153 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1154 }
1155
Jeff Brown01ce2e92010-09-26 22:20:12 -07001156 // Update the temporary touch state.
1157 BitSet32 pointerIds;
1158 if (isSplit) {
1159 uint32_t pointerId = entry->pointerIds[pointerIndex];
1160 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001161 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001162 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001163 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001164 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001165
1166 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001167 if (! mTempTouchState.down) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001168 LOGI("Dropping event because the pointer is not down.");
1169 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001170 goto Failed;
1171 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001172 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001173
Jeff Brown01ce2e92010-09-26 22:20:12 -07001174 // Check permission to inject into all touched foreground windows and ensure there
1175 // is at least one touched foreground window.
1176 {
1177 bool haveForegroundWindow = false;
1178 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1179 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1180 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1181 haveForegroundWindow = true;
1182 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1183 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1184 injectionPermission = INJECTION_PERMISSION_DENIED;
1185 goto Failed;
1186 }
1187 }
1188 }
1189 if (! haveForegroundWindow) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001190#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown01ce2e92010-09-26 22:20:12 -07001191 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001192#endif
1193 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001194 goto Failed;
1195 }
1196
Jeff Brown01ce2e92010-09-26 22:20:12 -07001197 // Permission granted to injection into all touched foreground windows.
1198 injectionPermission = INJECTION_PERMISSION_GRANTED;
1199 }
Jeff Brown519e0242010-09-15 15:18:56 -07001200
Jeff Brown01ce2e92010-09-26 22:20:12 -07001201 // Ensure all touched foreground windows are ready for new input.
1202 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1203 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1204 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1205 // If the touched window is paused then keep waiting.
1206 if (touchedWindow.window->paused) {
1207#if DEBUG_INPUT_DISPATCHER_POLICY
1208 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001209#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001210 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1211 NULL, touchedWindow.window, nextWakeupTime);
1212 goto Unresponsive;
1213 }
1214
1215 // If the touched window is still working on previous events then keep waiting.
1216 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1217#if DEBUG_FOCUS
1218 LOGD("Waiting because touched window still processing previous input.");
1219#endif
1220 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1221 NULL, touchedWindow.window, nextWakeupTime);
1222 goto Unresponsive;
1223 }
1224 }
1225 }
1226
1227 // If this is the first pointer going down and the touched window has a wallpaper
1228 // then also add the touched wallpaper windows so they are locked in for the duration
1229 // of the touch gesture.
1230 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1231 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1232 if (foregroundWindow->hasWallpaper) {
1233 for (size_t i = 0; i < mWindows.size(); i++) {
1234 const InputWindow* window = & mWindows[i];
1235 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001236 mTempTouchState.addOrUpdateWindow(window,
1237 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001238 }
1239 }
1240 }
1241 }
1242
Jeff Brownb88102f2010-09-08 11:49:43 -07001243 // Success! Output targets.
1244 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001245
Jeff Brown01ce2e92010-09-26 22:20:12 -07001246 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1247 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1248 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1249 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001250 }
1251
Jeff Brown01ce2e92010-09-26 22:20:12 -07001252 // Drop the outside touch window since we will not care about them in the next iteration.
1253 mTempTouchState.removeOutsideTouchWindows();
1254
Jeff Brownb88102f2010-09-08 11:49:43 -07001255Failed:
1256 // Check injection permission once and for all.
1257 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001258 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001259 injectionPermission = INJECTION_PERMISSION_GRANTED;
1260 } else {
1261 injectionPermission = INJECTION_PERMISSION_DENIED;
1262 }
1263 }
1264
1265 // Update final pieces of touch state if the injector had permission.
1266 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001267 if (maskedAction == AMOTION_EVENT_ACTION_UP
1268 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1269 // All pointers up or canceled.
1270 mTempTouchState.reset();
1271 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1272 // First pointer went down.
1273 if (mTouchState.down) {
Jeff Brownb6997262010-10-08 22:31:17 -07001274#if DEBUG_FOCUS
1275 LOGD("Pointer down received while already down.");
1276#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001277 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001278 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1279 // One pointer went up.
1280 if (isSplit) {
1281 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1282 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001283
Jeff Brown01ce2e92010-09-26 22:20:12 -07001284 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1285 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1286 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1287 touchedWindow.pointerIds.clearBit(pointerId);
1288 if (touchedWindow.pointerIds.isEmpty()) {
1289 mTempTouchState.windows.removeAt(i);
1290 continue;
1291 }
1292 }
1293 i += 1;
1294 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001295 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001296 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001297
1298 // Save changes to touch state.
1299 mTouchState.copyFrom(mTempTouchState);
Jeff Brownb88102f2010-09-08 11:49:43 -07001300 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001301#if DEBUG_FOCUS
1302 LOGD("Not updating touch focus because injection was denied.");
1303#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001304 }
1305
1306Unresponsive:
Jeff Brown120a4592010-10-27 18:43:51 -07001307 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1308 mTempTouchState.reset();
1309
Jeff Brown519e0242010-09-15 15:18:56 -07001310 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1311 updateDispatchStatisticsLocked(currentTime, entry,
1312 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001313#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001314 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1315 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001316 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001317#endif
1318 return injectionResult;
1319}
1320
Jeff Brown01ce2e92010-09-26 22:20:12 -07001321void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1322 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001323 mCurrentInputTargets.push();
1324
1325 InputTarget& target = mCurrentInputTargets.editTop();
1326 target.inputChannel = window->inputChannel;
1327 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001328 target.xOffset = - window->frameLeft;
1329 target.yOffset = - window->frameTop;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001330 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001331}
1332
1333void InputDispatcher::addMonitoringTargetsLocked() {
1334 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1335 mCurrentInputTargets.push();
1336
1337 InputTarget& target = mCurrentInputTargets.editTop();
1338 target.inputChannel = mMonitoringChannels[i];
1339 target.flags = 0;
Jeff Brownb88102f2010-09-08 11:49:43 -07001340 target.xOffset = 0;
1341 target.yOffset = 0;
1342 }
1343}
1344
1345bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001346 const InjectionState* injectionState) {
1347 if (injectionState
Jeff Brownb6997262010-10-08 22:31:17 -07001348 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1349 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1350 if (window) {
1351 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1352 "with input channel %s owned by uid %d",
1353 injectionState->injectorPid, injectionState->injectorUid,
1354 window->inputChannel->getName().string(),
1355 window->ownerUid);
1356 } else {
1357 LOGW("Permission denied: injecting event from pid %d uid %d",
1358 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001359 }
Jeff Brownb6997262010-10-08 22:31:17 -07001360 return false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001361 }
1362 return true;
1363}
1364
Jeff Brown19dfc832010-10-05 12:26:23 -07001365bool InputDispatcher::isWindowObscuredAtPointLocked(
1366 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07001367 size_t numWindows = mWindows.size();
1368 for (size_t i = 0; i < numWindows; i++) {
1369 const InputWindow* other = & mWindows.itemAt(i);
1370 if (other == window) {
1371 break;
1372 }
Jeff Brown19dfc832010-10-05 12:26:23 -07001373 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001374 return true;
1375 }
1376 }
1377 return false;
1378}
1379
Jeff Brown519e0242010-09-15 15:18:56 -07001380bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1381 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1382 if (connectionIndex >= 0) {
1383 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1384 return connection->outboundQueue.isEmpty();
1385 } else {
1386 return true;
1387 }
1388}
1389
1390String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1391 const InputWindow* window) {
1392 if (application) {
1393 if (window) {
1394 String8 label(application->name);
1395 label.append(" - ");
1396 label.append(window->name);
1397 return label;
1398 } else {
1399 return application->name;
1400 }
1401 } else if (window) {
1402 return window->name;
1403 } else {
1404 return String8("<unknown application or window>");
1405 }
1406}
1407
Jeff Browne2fe69e2010-10-18 13:21:23 -07001408void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1409 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Browneb9f7a02010-10-29 21:50:21 -07001410 switch (eventEntry->type) {
1411 case EventEntry::TYPE_MOTION: {
Jeff Browne2fe69e2010-10-18 13:21:23 -07001412 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Browneb9f7a02010-10-29 21:50:21 -07001413 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1414 return;
1415 }
1416
Jeff Browne2fe69e2010-10-18 13:21:23 -07001417 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1418 switch (motionEntry->action) {
1419 case AMOTION_EVENT_ACTION_DOWN:
1420 eventType = POWER_MANAGER_TOUCH_EVENT;
1421 break;
1422 case AMOTION_EVENT_ACTION_UP:
1423 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
1424 break;
1425 default:
Jeff Browna87ea462010-11-01 20:35:46 -07001426 if (motionEntry->eventTime - motionEntry->downTime < LONG_TOUCH_DELAY) {
Jeff Browne2fe69e2010-10-18 13:21:23 -07001427 eventType = POWER_MANAGER_TOUCH_EVENT;
1428 } else {
1429 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
1430 }
1431 break;
1432 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001433 }
Jeff Browneb9f7a02010-10-29 21:50:21 -07001434 break;
1435 }
1436 case EventEntry::TYPE_KEY: {
1437 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1438 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1439 return;
1440 }
1441 break;
1442 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001443 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001444
Jeff Brownb88102f2010-09-08 11:49:43 -07001445 CommandEntry* commandEntry = postCommandLocked(
1446 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Browne2fe69e2010-10-18 13:21:23 -07001447 commandEntry->eventTime = eventEntry->eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001448 commandEntry->userActivityEventType = eventType;
1449}
1450
Jeff Brown7fbdc842010-06-17 20:52:56 -07001451void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1452 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001453 bool resumeWithAppendedMotionSample) {
1454#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001455 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001456 "xOffset=%f, yOffset=%f, "
1457 "windowType=%d, pointerIds=0x%x, "
1458 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001459 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001460 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001461 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001462 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac02010-04-22 18:58:52 -07001463#endif
1464
Jeff Brown01ce2e92010-09-26 22:20:12 -07001465 // Make sure we are never called for streaming when splitting across multiple windows.
1466 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1467 assert(! (resumeWithAppendedMotionSample && isSplit));
1468
Jeff Brown46b9ac02010-04-22 18:58:52 -07001469 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001470 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac02010-04-22 18:58:52 -07001471 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb6997262010-10-08 22:31:17 -07001472#if DEBUG_DISPATCH_CYCLE
1473 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001474 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brownb6997262010-10-08 22:31:17 -07001475#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -07001476 return;
1477 }
1478
Jeff Brown01ce2e92010-09-26 22:20:12 -07001479 // Split a motion event if needed.
1480 if (isSplit) {
1481 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1482
1483 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1484 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1485 MotionEntry* splitMotionEntry = splitMotionEvent(
1486 originalMotionEntry, inputTarget->pointerIds);
1487#if DEBUG_FOCUS
1488 LOGD("channel '%s' ~ Split motion event.",
1489 connection->getInputChannelName());
1490 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1491#endif
1492 eventEntry = splitMotionEntry;
1493 }
1494 }
1495
Jeff Brown46b9ac02010-04-22 18:58:52 -07001496 // Resume the dispatch cycle with a freshly appended motion sample.
1497 // First we check that the last dispatch entry in the outbound queue is for the same
1498 // motion event to which we appended the motion sample. If we find such a dispatch
1499 // entry, and if it is currently in progress then we try to stream the new sample.
1500 bool wasEmpty = connection->outboundQueue.isEmpty();
1501
1502 if (! wasEmpty && resumeWithAppendedMotionSample) {
1503 DispatchEntry* motionEventDispatchEntry =
1504 connection->findQueuedDispatchEntryForEvent(eventEntry);
1505 if (motionEventDispatchEntry) {
1506 // If the dispatch entry is not in progress, then we must be busy dispatching an
1507 // earlier event. Not a problem, the motion event is on the outbound queue and will
1508 // be dispatched later.
1509 if (! motionEventDispatchEntry->inProgress) {
1510#if DEBUG_BATCHING
1511 LOGD("channel '%s' ~ Not streaming because the motion event has "
1512 "not yet been dispatched. "
1513 "(Waiting for earlier events to be consumed.)",
1514 connection->getInputChannelName());
1515#endif
1516 return;
1517 }
1518
1519 // If the dispatch entry is in progress but it already has a tail of pending
1520 // motion samples, then it must mean that the shared memory buffer filled up.
1521 // Not a problem, when this dispatch cycle is finished, we will eventually start
1522 // a new dispatch cycle to process the tail and that tail includes the newly
1523 // appended motion sample.
1524 if (motionEventDispatchEntry->tailMotionSample) {
1525#if DEBUG_BATCHING
1526 LOGD("channel '%s' ~ Not streaming because no new samples can "
1527 "be appended to the motion event in this dispatch cycle. "
1528 "(Waiting for next dispatch cycle to start.)",
1529 connection->getInputChannelName());
1530#endif
1531 return;
1532 }
1533
1534 // The dispatch entry is in progress and is still potentially open for streaming.
1535 // Try to stream the new motion sample. This might fail if the consumer has already
1536 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001537 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1538 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001539 status_t status = connection->inputPublisher.appendMotionSample(
1540 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1541 if (status == OK) {
1542#if DEBUG_BATCHING
1543 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1544 connection->getInputChannelName());
1545#endif
1546 return;
1547 }
1548
1549#if DEBUG_BATCHING
1550 if (status == NO_MEMORY) {
1551 LOGD("channel '%s' ~ Could not append motion sample to currently "
1552 "dispatched move event because the shared memory buffer is full. "
1553 "(Waiting for next dispatch cycle to start.)",
1554 connection->getInputChannelName());
1555 } else if (status == status_t(FAILED_TRANSACTION)) {
1556 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001557 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac02010-04-22 18:58:52 -07001558 "(Waiting for next dispatch cycle to start.)",
1559 connection->getInputChannelName());
1560 } else {
1561 LOGD("channel '%s' ~ Could not append motion sample to currently "
1562 "dispatched move event due to an error, status=%d. "
1563 "(Waiting for next dispatch cycle to start.)",
1564 connection->getInputChannelName(), status);
1565 }
1566#endif
1567 // Failed to stream. Start a new tail of pending motion samples to dispatch
1568 // in the next cycle.
1569 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1570 return;
1571 }
1572 }
1573
1574 // This is a new event.
1575 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001576 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown519e0242010-09-15 15:18:56 -07001577 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1578 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001579 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001580 }
1581
Jeff Brown46b9ac02010-04-22 18:58:52 -07001582 // Handle the case where we could not stream a new motion sample because the consumer has
1583 // already consumed the motion event (otherwise the corresponding dispatch entry would
1584 // still be in the outbound queue for this connection). We set the head motion sample
1585 // to the list starting with the newly appended motion sample.
1586 if (resumeWithAppendedMotionSample) {
1587#if DEBUG_BATCHING
1588 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1589 "that cannot be streamed because the motion event has already been consumed.",
1590 connection->getInputChannelName());
1591#endif
1592 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1593 dispatchEntry->headMotionSample = appendedMotionSample;
1594 }
1595
1596 // Enqueue the dispatch entry.
1597 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1598
1599 // If the outbound queue was previously empty, start the dispatch cycle going.
1600 if (wasEmpty) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001601 activateConnectionLocked(connection.get());
Jeff Brown519e0242010-09-15 15:18:56 -07001602 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001603 }
1604}
1605
Jeff Brown7fbdc842010-06-17 20:52:56 -07001606void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001607 const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001608#if DEBUG_DISPATCH_CYCLE
1609 LOGD("channel '%s' ~ startDispatchCycle",
1610 connection->getInputChannelName());
1611#endif
1612
1613 assert(connection->status == Connection::STATUS_NORMAL);
1614 assert(! connection->outboundQueue.isEmpty());
1615
Jeff Brownb88102f2010-09-08 11:49:43 -07001616 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001617 assert(! dispatchEntry->inProgress);
1618
Jeff Brownb88102f2010-09-08 11:49:43 -07001619 // Mark the dispatch entry as in progress.
1620 dispatchEntry->inProgress = true;
1621
1622 // Update the connection's input state.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001623 EventEntry* eventEntry = dispatchEntry->eventEntry;
1624 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001625
1626#if FILTER_INPUT_EVENTS
1627 // Filter out inconsistent sequences of input events.
1628 // The input system may drop or inject events in a way that could violate implicit
1629 // invariants on input state and potentially cause an application to crash
1630 // or think that a key or pointer is stuck down. Technically we make no guarantees
1631 // of consistency but it would be nice to improve on this where possible.
1632 // XXX: This code is a proof of concept only. Not ready for prime time.
1633 if (consistency == InputState::TOLERABLE) {
1634#if DEBUG_DISPATCH_CYCLE
1635 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1636 "current input state but that is likely to be tolerated by the application.",
1637 connection->getInputChannelName());
1638#endif
1639 } else if (consistency == InputState::BROKEN) {
1640 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1641 "current input state and that is likely to cause the application to crash.",
1642 connection->getInputChannelName());
1643 startNextDispatchCycleLocked(currentTime, connection);
1644 return;
1645 }
1646#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -07001647
1648 // Publish the event.
1649 status_t status;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001650 switch (eventEntry->type) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001651 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001652 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001653
1654 // Apply target flags.
1655 int32_t action = keyEntry->action;
1656 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001657
1658 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001659 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001660 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1661 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1662 keyEntry->eventTime);
1663
1664 if (status) {
1665 LOGE("channel '%s' ~ Could not publish key event, "
1666 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001667 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001668 return;
1669 }
1670 break;
1671 }
1672
1673 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001674 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001675
1676 // Apply target flags.
1677 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001678 int32_t flags = motionEntry->flags;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001679 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001680 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001681 }
Jeff Brown85a31762010-09-01 17:01:00 -07001682 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1683 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1684 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001685
1686 // If headMotionSample is non-NULL, then it points to the first new sample that we
1687 // were unable to dispatch during the previous cycle so we resume dispatching from
1688 // that point in the list of motion samples.
1689 // Otherwise, we just start from the first sample of the motion event.
1690 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1691 if (! firstMotionSample) {
1692 firstMotionSample = & motionEntry->firstSample;
1693 }
1694
Jeff Brownd3616592010-07-16 17:21:06 -07001695 // Set the X and Y offset depending on the input source.
1696 float xOffset, yOffset;
1697 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1698 xOffset = dispatchEntry->xOffset;
1699 yOffset = dispatchEntry->yOffset;
1700 } else {
1701 xOffset = 0.0f;
1702 yOffset = 0.0f;
1703 }
1704
Jeff Brown46b9ac02010-04-22 18:58:52 -07001705 // Publish the motion event and the first motion sample.
1706 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07001707 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownd3616592010-07-16 17:21:06 -07001708 xOffset, yOffset,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001709 motionEntry->xPrecision, motionEntry->yPrecision,
1710 motionEntry->downTime, firstMotionSample->eventTime,
1711 motionEntry->pointerCount, motionEntry->pointerIds,
1712 firstMotionSample->pointerCoords);
1713
1714 if (status) {
1715 LOGE("channel '%s' ~ Could not publish motion event, "
1716 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001717 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001718 return;
1719 }
1720
1721 // Append additional motion samples.
1722 MotionSample* nextMotionSample = firstMotionSample->next;
1723 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1724 status = connection->inputPublisher.appendMotionSample(
1725 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1726 if (status == NO_MEMORY) {
1727#if DEBUG_DISPATCH_CYCLE
1728 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1729 "be sent in the next dispatch cycle.",
1730 connection->getInputChannelName());
1731#endif
1732 break;
1733 }
1734 if (status != OK) {
1735 LOGE("channel '%s' ~ Could not append motion sample "
1736 "for a reason other than out of memory, status=%d",
1737 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001738 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001739 return;
1740 }
1741 }
1742
1743 // Remember the next motion sample that we could not dispatch, in case we ran out
1744 // of space in the shared memory buffer.
1745 dispatchEntry->tailMotionSample = nextMotionSample;
1746 break;
1747 }
1748
1749 default: {
1750 assert(false);
1751 }
1752 }
1753
1754 // Send the dispatch signal.
1755 status = connection->inputPublisher.sendDispatchSignal();
1756 if (status) {
1757 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1758 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001759 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001760 return;
1761 }
1762
1763 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001764 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001765 connection->lastDispatchTime = currentTime;
1766
Jeff Brown46b9ac02010-04-22 18:58:52 -07001767 // Notify other system components.
1768 onDispatchCycleStartedLocked(currentTime, connection);
1769}
1770
Jeff Brown7fbdc842010-06-17 20:52:56 -07001771void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1772 const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001773#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001774 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown46b9ac02010-04-22 18:58:52 -07001775 "%01.1fms since dispatch",
1776 connection->getInputChannelName(),
1777 connection->getEventLatencyMillis(currentTime),
1778 connection->getDispatchLatencyMillis(currentTime));
1779#endif
1780
Jeff Brown9c3cda02010-06-15 01:31:58 -07001781 if (connection->status == Connection::STATUS_BROKEN
1782 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001783 return;
1784 }
1785
Jeff Brown519e0242010-09-15 15:18:56 -07001786 // Notify other system components.
1787 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001788
1789 // Reset the publisher since the event has been consumed.
1790 // We do this now so that the publisher can release some of its internal resources
1791 // while waiting for the next dispatch cycle to begin.
1792 status_t status = connection->inputPublisher.reset();
1793 if (status) {
1794 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1795 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001796 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001797 return;
1798 }
1799
Jeff Brownb88102f2010-09-08 11:49:43 -07001800 startNextDispatchCycleLocked(currentTime, connection);
1801}
1802
1803void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1804 const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001805 // Start the next dispatch cycle for this connection.
1806 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001807 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001808 if (dispatchEntry->inProgress) {
1809 // Finish or resume current event in progress.
1810 if (dispatchEntry->tailMotionSample) {
1811 // We have a tail of undispatched motion samples.
1812 // Reuse the same DispatchEntry and start a new cycle.
1813 dispatchEntry->inProgress = false;
1814 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1815 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07001816 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001817 return;
1818 }
1819 // Finished.
1820 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07001821 if (dispatchEntry->hasForegroundTarget()) {
1822 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001823 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001824 mAllocator.releaseDispatchEntry(dispatchEntry);
1825 } else {
1826 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07001827 // progress event, which means we actually aborted it.
Jeff Brown46b9ac02010-04-22 18:58:52 -07001828 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07001829 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001830 return;
1831 }
1832 }
1833
1834 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07001835 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac02010-04-22 18:58:52 -07001836}
1837
Jeff Brownb6997262010-10-08 22:31:17 -07001838void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1839 const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001840#if DEBUG_DISPATCH_CYCLE
Jeff Brownb6997262010-10-08 22:31:17 -07001841 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001842 connection->getInputChannelName(), toString(broken));
Jeff Brown46b9ac02010-04-22 18:58:52 -07001843#endif
1844
Jeff Brownb88102f2010-09-08 11:49:43 -07001845 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07001846 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac02010-04-22 18:58:52 -07001847
Jeff Brownb6997262010-10-08 22:31:17 -07001848 // The connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07001849 // Ignore already broken or zombie connections.
Jeff Brownb6997262010-10-08 22:31:17 -07001850 if (connection->status == Connection::STATUS_NORMAL) {
1851 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001852
Jeff Brownb6997262010-10-08 22:31:17 -07001853 // Notify other system components.
1854 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001855 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001856}
1857
Jeff Brown519e0242010-09-15 15:18:56 -07001858void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1859 while (! connection->outboundQueue.isEmpty()) {
1860 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1861 if (dispatchEntry->hasForegroundTarget()) {
1862 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001863 }
1864 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001865 }
1866
Jeff Brown519e0242010-09-15 15:18:56 -07001867 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07001868}
1869
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001870int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001871 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1872
1873 { // acquire lock
1874 AutoMutex _l(d->mLock);
1875
1876 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1877 if (connectionIndex < 0) {
1878 LOGE("Received spurious receive callback for unknown input channel. "
1879 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001880 return 0; // remove the callback
Jeff Brown46b9ac02010-04-22 18:58:52 -07001881 }
1882
Jeff Brown7fbdc842010-06-17 20:52:56 -07001883 nsecs_t currentTime = now();
Jeff Brown46b9ac02010-04-22 18:58:52 -07001884
1885 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001886 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001887 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1888 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brownb6997262010-10-08 22:31:17 -07001889 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001890 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001891 return 0; // remove the callback
Jeff Brown46b9ac02010-04-22 18:58:52 -07001892 }
1893
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001894 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001895 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1896 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001897 return 1;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001898 }
1899
1900 status_t status = connection->inputPublisher.receiveFinishedSignal();
1901 if (status) {
1902 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1903 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001904 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001905 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001906 return 0; // remove the callback
Jeff Brown46b9ac02010-04-22 18:58:52 -07001907 }
1908
Jeff Brown7fbdc842010-06-17 20:52:56 -07001909 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001910 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001911 return 1;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001912 } // release lock
1913}
1914
Jeff Brownb6997262010-10-08 22:31:17 -07001915void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1916 InputState::CancelationOptions options, const char* reason) {
1917 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1918 synthesizeCancelationEventsForConnectionLocked(
1919 mConnectionsByReceiveFd.valueAt(i), options, reason);
1920 }
1921}
1922
1923void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1924 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1925 const char* reason) {
1926 ssize_t index = getConnectionIndexLocked(channel);
1927 if (index >= 0) {
1928 synthesizeCancelationEventsForConnectionLocked(
1929 mConnectionsByReceiveFd.valueAt(index), options, reason);
1930 }
1931}
1932
1933void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1934 const sp<Connection>& connection, InputState::CancelationOptions options,
1935 const char* reason) {
1936 nsecs_t currentTime = now();
1937
1938 mTempCancelationEvents.clear();
1939 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1940 mTempCancelationEvents, options);
1941
1942 if (! mTempCancelationEvents.isEmpty()
1943 && connection->status != Connection::STATUS_BROKEN) {
1944#if DEBUG_OUTBOUND_EVENT_DETAILS
1945 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1946 "with reality: %s, options=%d.",
1947 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1948#endif
1949 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1950 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1951 switch (cancelationEventEntry->type) {
1952 case EventEntry::TYPE_KEY:
1953 logOutboundKeyDetailsLocked("cancel - ",
1954 static_cast<KeyEntry*>(cancelationEventEntry));
1955 break;
1956 case EventEntry::TYPE_MOTION:
1957 logOutboundMotionDetailsLocked("cancel - ",
1958 static_cast<MotionEntry*>(cancelationEventEntry));
1959 break;
1960 }
1961
1962 int32_t xOffset, yOffset;
1963 const InputWindow* window = getWindowLocked(connection->inputChannel);
1964 if (window) {
1965 xOffset = -window->frameLeft;
1966 yOffset = -window->frameTop;
1967 } else {
1968 xOffset = 0;
1969 yOffset = 0;
1970 }
1971
1972 DispatchEntry* cancelationDispatchEntry =
1973 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1974 0, xOffset, yOffset);
1975 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1976
1977 mAllocator.releaseEventEntry(cancelationEventEntry);
1978 }
1979
1980 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1981 startDispatchCycleLocked(currentTime, connection);
1982 }
1983 }
1984}
1985
Jeff Brown01ce2e92010-09-26 22:20:12 -07001986InputDispatcher::MotionEntry*
1987InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1988 assert(pointerIds.value != 0);
1989
1990 uint32_t splitPointerIndexMap[MAX_POINTERS];
1991 int32_t splitPointerIds[MAX_POINTERS];
1992 PointerCoords splitPointerCoords[MAX_POINTERS];
1993
1994 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1995 uint32_t splitPointerCount = 0;
1996
1997 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1998 originalPointerIndex++) {
1999 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
2000 if (pointerIds.hasBit(pointerId)) {
2001 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2002 splitPointerIds[splitPointerCount] = pointerId;
2003 splitPointerCoords[splitPointerCount] =
2004 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
2005 splitPointerCount += 1;
2006 }
2007 }
2008 assert(splitPointerCount == pointerIds.count());
2009
2010 int32_t action = originalMotionEntry->action;
2011 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2012 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2013 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2014 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2015 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2016 if (pointerIds.hasBit(pointerId)) {
2017 if (pointerIds.count() == 1) {
2018 // The first/last pointer went down/up.
2019 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2020 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07002021 } else {
2022 // A secondary pointer went down/up.
2023 uint32_t splitPointerIndex = 0;
2024 while (pointerId != splitPointerIds[splitPointerIndex]) {
2025 splitPointerIndex += 1;
2026 }
2027 action = maskedAction | (splitPointerIndex
2028 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002029 }
2030 } else {
2031 // An unrelated pointer changed.
2032 action = AMOTION_EVENT_ACTION_MOVE;
2033 }
2034 }
2035
2036 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2037 originalMotionEntry->eventTime,
2038 originalMotionEntry->deviceId,
2039 originalMotionEntry->source,
2040 originalMotionEntry->policyFlags,
2041 action,
2042 originalMotionEntry->flags,
2043 originalMotionEntry->metaState,
2044 originalMotionEntry->edgeFlags,
2045 originalMotionEntry->xPrecision,
2046 originalMotionEntry->yPrecision,
2047 originalMotionEntry->downTime,
2048 splitPointerCount, splitPointerIds, splitPointerCoords);
2049
2050 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2051 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2052 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2053 splitPointerIndex++) {
2054 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2055 splitPointerCoords[splitPointerIndex] =
2056 originalMotionSample->pointerCoords[originalPointerIndex];
2057 }
2058
2059 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2060 splitPointerCoords);
2061 }
2062
2063 return splitMotionEntry;
2064}
2065
Jeff Brown9c3cda02010-06-15 01:31:58 -07002066void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002067#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07002068 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002069#endif
2070
Jeff Brownb88102f2010-09-08 11:49:43 -07002071 bool needWake;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002072 { // acquire lock
2073 AutoMutex _l(mLock);
2074
Jeff Brown7fbdc842010-06-17 20:52:56 -07002075 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07002076 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002077 } // release lock
2078
Jeff Brownb88102f2010-09-08 11:49:43 -07002079 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002080 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002081 }
2082}
2083
Jeff Brownc5ed5912010-07-14 18:48:53 -07002084void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002085 uint32_t policyFlags, int32_t action, int32_t flags,
2086 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2087#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brownc5ed5912010-07-14 18:48:53 -07002088 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac02010-04-22 18:58:52 -07002089 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07002090 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002091 keyCode, scanCode, metaState, downTime);
2092#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002093 if (! validateKeyEvent(action)) {
2094 return;
2095 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002096
Jeff Brownb931a1b2010-10-11 14:20:19 -07002097 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002098 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2099 keyCode, scanCode, /*byref*/ policyFlags);
2100
Jeff Brownb88102f2010-09-08 11:49:43 -07002101 bool needWake;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002102 { // acquire lock
2103 AutoMutex _l(mLock);
2104
Jeff Brown7fbdc842010-06-17 20:52:56 -07002105 int32_t repeatCount = 0;
2106 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002107 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002108 metaState, repeatCount, downTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002109
Jeff Brownb88102f2010-09-08 11:49:43 -07002110 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002111 } // release lock
2112
Jeff Brownb88102f2010-09-08 11:49:43 -07002113 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002114 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002115 }
2116}
2117
Jeff Brownc5ed5912010-07-14 18:48:53 -07002118void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002119 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002120 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2121 float xPrecision, float yPrecision, nsecs_t downTime) {
2122#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brownc5ed5912010-07-14 18:48:53 -07002123 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002124 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2125 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2126 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002127 xPrecision, yPrecision, downTime);
2128 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002129 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002130 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002131 "orientation=%f",
Jeff Brown46b9ac02010-04-22 18:58:52 -07002132 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown8d608662010-08-30 03:02:23 -07002133 pointerCoords[i].pressure, pointerCoords[i].size,
2134 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2135 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2136 pointerCoords[i].orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002137 }
2138#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002139 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2140 return;
2141 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002142
Jeff Brownb931a1b2010-10-11 14:20:19 -07002143 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002144 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2145
Jeff Brownb88102f2010-09-08 11:49:43 -07002146 bool needWake;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002147 { // acquire lock
2148 AutoMutex _l(mLock);
2149
2150 // Attempt batching and streaming of move events.
Jeff Brownc5ed5912010-07-14 18:48:53 -07002151 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002152 // BATCHING CASE
2153 //
2154 // Try to append a move sample to the tail of the inbound queue for this device.
2155 // Give up if we encounter a non-move motion event for this device since that
2156 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002157 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2158 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002159 if (entry->type != EventEntry::TYPE_MOTION) {
2160 // Keep looking for motion events.
2161 continue;
2162 }
2163
2164 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2165 if (motionEntry->deviceId != deviceId) {
2166 // Keep looking for this device.
2167 continue;
2168 }
2169
Jeff Brownc5ed5912010-07-14 18:48:53 -07002170 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown7fbdc842010-06-17 20:52:56 -07002171 || motionEntry->pointerCount != pointerCount
2172 || motionEntry->isInjected()) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002173 // Last motion event in the queue for this device is not compatible for
2174 // appending new samples. Stop here.
2175 goto NoBatchingOrStreaming;
2176 }
2177
2178 // The last motion event is a move and is compatible for appending.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002179 // Do the batching magic.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002180 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002181#if DEBUG_BATCHING
2182 LOGD("Appended motion sample onto batch for most recent "
2183 "motion event for this device in the inbound queue.");
2184#endif
Jeff Brown9c3cda02010-06-15 01:31:58 -07002185 return; // done!
Jeff Brown46b9ac02010-04-22 18:58:52 -07002186 }
2187
2188 // STREAMING CASE
2189 //
2190 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002191 // Search the outbound queue for the current foreground targets to find a dispatched
2192 // motion event that is still in progress. If found, then, appen the new sample to
2193 // that event and push it out to all current targets. The logic in
2194 // prepareDispatchCycleLocked takes care of the case where some targets may
2195 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002196 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002197 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2198 const InputTarget& inputTarget = mCurrentInputTargets[i];
2199 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2200 // Skip non-foreground targets. We only want to stream if there is at
2201 // least one foreground target whose dispatch is still in progress.
2202 continue;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002203 }
Jeff Brown519e0242010-09-15 15:18:56 -07002204
2205 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2206 if (connectionIndex < 0) {
2207 // Connection must no longer be valid.
2208 continue;
2209 }
2210
2211 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2212 if (connection->outboundQueue.isEmpty()) {
2213 // This foreground target has an empty outbound queue.
2214 continue;
2215 }
2216
2217 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2218 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002219 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2220 || dispatchEntry->isSplit()) {
2221 // No motion event is being dispatched, or it is being split across
2222 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002223 continue;
2224 }
2225
2226 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2227 dispatchEntry->eventEntry);
2228 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2229 || motionEntry->deviceId != deviceId
2230 || motionEntry->pointerCount != pointerCount
2231 || motionEntry->isInjected()) {
2232 // The motion event is not compatible with this move.
2233 continue;
2234 }
2235
2236 // Hurray! This foreground target is currently dispatching a move event
2237 // that we can stream onto. Append the motion sample and resume dispatch.
2238 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2239#if DEBUG_BATCHING
2240 LOGD("Appended motion sample onto batch for most recently dispatched "
2241 "motion event for this device in the outbound queues. "
2242 "Attempting to stream the motion sample.");
2243#endif
2244 nsecs_t currentTime = now();
2245 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2246 true /*resumeWithAppendedMotionSample*/);
2247
2248 runCommandsLockedInterruptible();
2249 return; // done!
Jeff Brown46b9ac02010-04-22 18:58:52 -07002250 }
2251 }
2252
2253NoBatchingOrStreaming:;
2254 }
2255
2256 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002257 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002258 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002259 xPrecision, yPrecision, downTime,
2260 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002261
Jeff Brownb88102f2010-09-08 11:49:43 -07002262 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002263 } // release lock
2264
Jeff Brownb88102f2010-09-08 11:49:43 -07002265 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002266 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002267 }
2268}
2269
Jeff Brownb6997262010-10-08 22:31:17 -07002270void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2271 uint32_t policyFlags) {
2272#if DEBUG_INBOUND_EVENT_DETAILS
2273 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2274 switchCode, switchValue, policyFlags);
2275#endif
2276
Jeff Brownb931a1b2010-10-11 14:20:19 -07002277 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002278 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2279}
2280
Jeff Brown7fbdc842010-06-17 20:52:56 -07002281int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002282 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002283#if DEBUG_INBOUND_EVENT_DETAILS
2284 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002285 "syncMode=%d, timeoutMillis=%d",
2286 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002287#endif
2288
2289 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brownb931a1b2010-10-11 14:20:19 -07002290
2291 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2292 if (hasInjectionPermission(injectorPid, injectorUid)) {
2293 policyFlags |= POLICY_FLAG_TRUSTED;
2294 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002295
Jeff Brownb6997262010-10-08 22:31:17 -07002296 EventEntry* injectedEntry;
2297 switch (event->getType()) {
2298 case AINPUT_EVENT_TYPE_KEY: {
2299 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2300 int32_t action = keyEvent->getAction();
2301 if (! validateKeyEvent(action)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002302 return INPUT_EVENT_INJECTION_FAILED;
2303 }
2304
Jeff Brownb6997262010-10-08 22:31:17 -07002305 nsecs_t eventTime = keyEvent->getEventTime();
2306 int32_t deviceId = keyEvent->getDeviceId();
2307 int32_t flags = keyEvent->getFlags();
2308 int32_t keyCode = keyEvent->getKeyCode();
2309 int32_t scanCode = keyEvent->getScanCode();
Jeff Brownb931a1b2010-10-11 14:20:19 -07002310 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2311 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002312
Jeff Brownb6997262010-10-08 22:31:17 -07002313 mLock.lock();
2314 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2315 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2316 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2317 break;
2318 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002319
Jeff Brownb6997262010-10-08 22:31:17 -07002320 case AINPUT_EVENT_TYPE_MOTION: {
2321 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2322 int32_t action = motionEvent->getAction();
2323 size_t pointerCount = motionEvent->getPointerCount();
2324 const int32_t* pointerIds = motionEvent->getPointerIds();
2325 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2326 return INPUT_EVENT_INJECTION_FAILED;
2327 }
2328
2329 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brownb931a1b2010-10-11 14:20:19 -07002330 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002331
2332 mLock.lock();
2333 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2334 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2335 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2336 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2337 action, motionEvent->getFlags(),
2338 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2339 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2340 motionEvent->getDownTime(), uint32_t(pointerCount),
2341 pointerIds, samplePointerCoords);
2342 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2343 sampleEventTimes += 1;
2344 samplePointerCoords += pointerCount;
2345 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2346 }
2347 injectedEntry = motionEntry;
2348 break;
2349 }
2350
2351 default:
2352 LOGW("Cannot inject event of type %d", event->getType());
2353 return INPUT_EVENT_INJECTION_FAILED;
2354 }
2355
2356 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2357 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2358 injectionState->injectionIsAsync = true;
2359 }
2360
2361 injectionState->refCount += 1;
2362 injectedEntry->injectionState = injectionState;
2363
2364 bool needWake = enqueueInboundEventLocked(injectedEntry);
2365 mLock.unlock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002366
Jeff Brownb88102f2010-09-08 11:49:43 -07002367 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002368 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002369 }
2370
2371 int32_t injectionResult;
2372 { // acquire lock
2373 AutoMutex _l(mLock);
2374
Jeff Brown6ec402b2010-07-28 15:48:59 -07002375 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2376 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2377 } else {
2378 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002379 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002380 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2381 break;
2382 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002383
Jeff Brown7fbdc842010-06-17 20:52:56 -07002384 nsecs_t remainingTimeout = endTime - now();
2385 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002386#if DEBUG_INJECTION
2387 LOGD("injectInputEvent - Timed out waiting for injection result "
2388 "to become available.");
2389#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002390 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2391 break;
2392 }
2393
Jeff Brown6ec402b2010-07-28 15:48:59 -07002394 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2395 }
2396
2397 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2398 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002399 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002400#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002401 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002402 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002403#endif
2404 nsecs_t remainingTimeout = endTime - now();
2405 if (remainingTimeout <= 0) {
2406#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002407 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002408 "dispatches to finish.");
2409#endif
2410 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2411 break;
2412 }
2413
2414 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2415 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002416 }
2417 }
2418
Jeff Brown01ce2e92010-09-26 22:20:12 -07002419 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002420 } // release lock
2421
Jeff Brown6ec402b2010-07-28 15:48:59 -07002422#if DEBUG_INJECTION
2423 LOGD("injectInputEvent - Finished with result %d. "
2424 "injectorPid=%d, injectorUid=%d",
2425 injectionResult, injectorPid, injectorUid);
2426#endif
2427
Jeff Brown7fbdc842010-06-17 20:52:56 -07002428 return injectionResult;
2429}
2430
Jeff Brownb6997262010-10-08 22:31:17 -07002431bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2432 return injectorUid == 0
2433 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2434}
2435
Jeff Brown7fbdc842010-06-17 20:52:56 -07002436void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002437 InjectionState* injectionState = entry->injectionState;
2438 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002439#if DEBUG_INJECTION
2440 LOGD("Setting input event injection result to %d. "
2441 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002442 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002443#endif
2444
Jeff Brown01ce2e92010-09-26 22:20:12 -07002445 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002446 // Log the outcome since the injector did not wait for the injection result.
2447 switch (injectionResult) {
2448 case INPUT_EVENT_INJECTION_SUCCEEDED:
2449 LOGV("Asynchronous input event injection succeeded.");
2450 break;
2451 case INPUT_EVENT_INJECTION_FAILED:
2452 LOGW("Asynchronous input event injection failed.");
2453 break;
2454 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2455 LOGW("Asynchronous input event injection permission denied.");
2456 break;
2457 case INPUT_EVENT_INJECTION_TIMED_OUT:
2458 LOGW("Asynchronous input event injection timed out.");
2459 break;
2460 }
2461 }
2462
Jeff Brown01ce2e92010-09-26 22:20:12 -07002463 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002464 mInjectionResultAvailableCondition.broadcast();
2465 }
2466}
2467
Jeff Brown01ce2e92010-09-26 22:20:12 -07002468void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2469 InjectionState* injectionState = entry->injectionState;
2470 if (injectionState) {
2471 injectionState->pendingForegroundDispatches += 1;
2472 }
2473}
2474
Jeff Brown519e0242010-09-15 15:18:56 -07002475void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002476 InjectionState* injectionState = entry->injectionState;
2477 if (injectionState) {
2478 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002479
Jeff Brown01ce2e92010-09-26 22:20:12 -07002480 if (injectionState->pendingForegroundDispatches == 0) {
2481 mInjectionSyncFinishedCondition.broadcast();
2482 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002483 }
2484}
2485
Jeff Brown01ce2e92010-09-26 22:20:12 -07002486const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2487 for (size_t i = 0; i < mWindows.size(); i++) {
2488 const InputWindow* window = & mWindows[i];
2489 if (window->inputChannel == inputChannel) {
2490 return window;
2491 }
2492 }
2493 return NULL;
2494}
2495
Jeff Brownb88102f2010-09-08 11:49:43 -07002496void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2497#if DEBUG_FOCUS
2498 LOGD("setInputWindows");
2499#endif
2500 { // acquire lock
2501 AutoMutex _l(mLock);
2502
Jeff Brown01ce2e92010-09-26 22:20:12 -07002503 // Clear old window pointers.
Jeff Brownb6997262010-10-08 22:31:17 -07002504 sp<InputChannel> oldFocusedWindowChannel;
2505 if (mFocusedWindow) {
2506 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2507 mFocusedWindow = NULL;
2508 }
2509
Jeff Brownb88102f2010-09-08 11:49:43 -07002510 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002511
2512 // Loop over new windows and rebuild the necessary window pointers for
2513 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002514 mWindows.appendVector(inputWindows);
2515
2516 size_t numWindows = mWindows.size();
2517 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002518 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002519 if (window->hasFocus) {
2520 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002521 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002522 }
2523 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002524
Jeff Brownb6997262010-10-08 22:31:17 -07002525 if (oldFocusedWindowChannel != NULL) {
2526 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2527#if DEBUG_FOCUS
2528 LOGD("Focus left window: %s",
2529 oldFocusedWindowChannel->getName().string());
2530#endif
2531 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2532 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2533 oldFocusedWindowChannel.clear();
2534 }
2535 }
2536 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2537#if DEBUG_FOCUS
2538 LOGD("Focus entered window: %s",
2539 mFocusedWindow->inputChannel->getName().string());
2540#endif
2541 }
2542
Jeff Brown01ce2e92010-09-26 22:20:12 -07002543 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2544 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2545 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2546 if (window) {
2547 touchedWindow.window = window;
2548 i += 1;
2549 } else {
Jeff Brownb6997262010-10-08 22:31:17 -07002550#if DEBUG_FOCUS
2551 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2552#endif
Jeff Brownb6997262010-10-08 22:31:17 -07002553 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2554 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownaf48cae2010-10-15 16:20:51 -07002555 mTouchState.windows.removeAt(i);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002556 }
2557 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002558
Jeff Brownb88102f2010-09-08 11:49:43 -07002559#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002560 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002561#endif
2562 } // release lock
2563
2564 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002565 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002566}
2567
2568void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2569#if DEBUG_FOCUS
2570 LOGD("setFocusedApplication");
2571#endif
2572 { // acquire lock
2573 AutoMutex _l(mLock);
2574
2575 releaseFocusedApplicationLocked();
2576
2577 if (inputApplication) {
2578 mFocusedApplicationStorage = *inputApplication;
2579 mFocusedApplication = & mFocusedApplicationStorage;
2580 }
2581
2582#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002583 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002584#endif
2585 } // release lock
2586
2587 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002588 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002589}
2590
2591void InputDispatcher::releaseFocusedApplicationLocked() {
2592 if (mFocusedApplication) {
2593 mFocusedApplication = NULL;
2594 mFocusedApplicationStorage.handle.clear();
2595 }
2596}
2597
2598void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2599#if DEBUG_FOCUS
2600 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2601#endif
2602
2603 bool changed;
2604 { // acquire lock
2605 AutoMutex _l(mLock);
2606
2607 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brown120a4592010-10-27 18:43:51 -07002608 if (mDispatchFrozen && !frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002609 resetANRTimeoutsLocked();
2610 }
2611
Jeff Brown120a4592010-10-27 18:43:51 -07002612 if (mDispatchEnabled && !enabled) {
2613 resetAndDropEverythingLocked("dispatcher is being disabled");
2614 }
2615
Jeff Brownb88102f2010-09-08 11:49:43 -07002616 mDispatchEnabled = enabled;
2617 mDispatchFrozen = frozen;
2618 changed = true;
2619 } else {
2620 changed = false;
2621 }
2622
2623#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002624 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002625#endif
2626 } // release lock
2627
2628 if (changed) {
2629 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002630 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002631 }
2632}
2633
Jeff Brown120a4592010-10-27 18:43:51 -07002634void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2635#if DEBUG_FOCUS
2636 LOGD("Resetting and dropping all events (%s).", reason);
2637#endif
2638
2639 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2640
2641 resetKeyRepeatLocked();
2642 releasePendingEventLocked();
2643 drainInboundQueueLocked();
2644 resetTargetsLocked();
2645
2646 mTouchState.reset();
2647}
2648
Jeff Brownb88102f2010-09-08 11:49:43 -07002649void InputDispatcher::logDispatchStateLocked() {
2650 String8 dump;
2651 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002652
2653 char* text = dump.lockBuffer(dump.size());
2654 char* start = text;
2655 while (*start != '\0') {
2656 char* end = strchr(start, '\n');
2657 if (*end == '\n') {
2658 *(end++) = '\0';
2659 }
2660 LOGD("%s", start);
2661 start = end;
2662 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002663}
2664
2665void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002666 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2667 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07002668
2669 if (mFocusedApplication) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002670 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002671 mFocusedApplication->name.string(),
2672 mFocusedApplication->dispatchingTimeout / 1000000.0);
2673 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002674 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002675 }
Jeff Brownf2f487182010-10-01 17:46:21 -07002676 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002677 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f487182010-10-01 17:46:21 -07002678
2679 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2680 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2681 if (!mTouchState.windows.isEmpty()) {
2682 dump.append(INDENT "TouchedWindows:\n");
2683 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2684 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2685 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2686 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2687 touchedWindow.targetFlags);
2688 }
2689 } else {
2690 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002691 }
2692
Jeff Brownf2f487182010-10-01 17:46:21 -07002693 if (!mWindows.isEmpty()) {
2694 dump.append(INDENT "Windows:\n");
2695 for (size_t i = 0; i < mWindows.size(); i++) {
2696 const InputWindow& window = mWindows[i];
2697 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2698 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2699 "frame=[%d,%d][%d,%d], "
2700 "visibleFrame=[%d,%d][%d,%d], "
2701 "touchableArea=[%d,%d][%d,%d], "
2702 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2703 i, window.name.string(),
2704 toString(window.paused),
2705 toString(window.hasFocus),
2706 toString(window.hasWallpaper),
2707 toString(window.visible),
2708 toString(window.canReceiveKeys),
2709 window.layoutParamsFlags, window.layoutParamsType,
2710 window.layer,
2711 window.frameLeft, window.frameTop,
2712 window.frameRight, window.frameBottom,
2713 window.visibleFrameLeft, window.visibleFrameTop,
2714 window.visibleFrameRight, window.visibleFrameBottom,
2715 window.touchableAreaLeft, window.touchableAreaTop,
2716 window.touchableAreaRight, window.touchableAreaBottom,
2717 window.ownerPid, window.ownerUid,
2718 window.dispatchingTimeout / 1000000.0);
2719 }
2720 } else {
2721 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002722 }
2723
Jeff Brownf2f487182010-10-01 17:46:21 -07002724 if (!mMonitoringChannels.isEmpty()) {
2725 dump.append(INDENT "MonitoringChannels:\n");
2726 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2727 const sp<InputChannel>& channel = mMonitoringChannels[i];
2728 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2729 }
2730 } else {
2731 dump.append(INDENT "MonitoringChannels: <none>\n");
2732 }
Jeff Brown519e0242010-09-15 15:18:56 -07002733
Jeff Brownf2f487182010-10-01 17:46:21 -07002734 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2735
2736 if (!mActiveConnections.isEmpty()) {
2737 dump.append(INDENT "ActiveConnections:\n");
2738 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2739 const Connection* connection = mActiveConnections[i];
2740 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
Jeff Brownb6997262010-10-08 22:31:17 -07002741 "inputState.isNeutral=%s\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07002742 i, connection->getInputChannelName(), connection->getStatusLabel(),
2743 connection->outboundQueue.count(),
Jeff Brownb6997262010-10-08 22:31:17 -07002744 toString(connection->inputState.isNeutral()));
Jeff Brownf2f487182010-10-01 17:46:21 -07002745 }
2746 } else {
2747 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002748 }
2749
2750 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002751 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002752 (mAppSwitchDueTime - now()) / 1000000.0);
2753 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002754 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002755 }
2756}
2757
2758status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002759#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07002760 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2761 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07002762#endif
2763
Jeff Brown46b9ac02010-04-22 18:58:52 -07002764 { // acquire lock
2765 AutoMutex _l(mLock);
2766
Jeff Brown519e0242010-09-15 15:18:56 -07002767 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002768 LOGW("Attempted to register already registered input channel '%s'",
2769 inputChannel->getName().string());
2770 return BAD_VALUE;
2771 }
2772
2773 sp<Connection> connection = new Connection(inputChannel);
2774 status_t status = connection->initialize();
2775 if (status) {
2776 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2777 inputChannel->getName().string(), status);
2778 return status;
2779 }
2780
Jeff Brown2cbecea2010-08-17 15:59:26 -07002781 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002782 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002783
Jeff Brownb88102f2010-09-08 11:49:43 -07002784 if (monitor) {
2785 mMonitoringChannels.push(inputChannel);
2786 }
2787
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002788 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07002789
Jeff Brown9c3cda02010-06-15 01:31:58 -07002790 runCommandsLockedInterruptible();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002791 } // release lock
Jeff Brown46b9ac02010-04-22 18:58:52 -07002792 return OK;
2793}
2794
2795status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002796#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07002797 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07002798#endif
2799
Jeff Brown46b9ac02010-04-22 18:58:52 -07002800 { // acquire lock
2801 AutoMutex _l(mLock);
2802
Jeff Brown519e0242010-09-15 15:18:56 -07002803 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002804 if (connectionIndex < 0) {
2805 LOGW("Attempted to unregister already unregistered input channel '%s'",
2806 inputChannel->getName().string());
2807 return BAD_VALUE;
2808 }
2809
2810 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2811 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2812
2813 connection->status = Connection::STATUS_ZOMBIE;
2814
Jeff Brownb88102f2010-09-08 11:49:43 -07002815 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2816 if (mMonitoringChannels[i] == inputChannel) {
2817 mMonitoringChannels.removeAt(i);
2818 break;
2819 }
2820 }
2821
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002822 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07002823
Jeff Brown7fbdc842010-06-17 20:52:56 -07002824 nsecs_t currentTime = now();
Jeff Brownb6997262010-10-08 22:31:17 -07002825 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002826
2827 runCommandsLockedInterruptible();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002828 } // release lock
2829
Jeff Brown46b9ac02010-04-22 18:58:52 -07002830 // Wake the poll loop because removing the connection may have changed the current
2831 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002832 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002833 return OK;
2834}
2835
Jeff Brown519e0242010-09-15 15:18:56 -07002836ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07002837 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2838 if (connectionIndex >= 0) {
2839 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2840 if (connection->inputChannel.get() == inputChannel.get()) {
2841 return connectionIndex;
2842 }
2843 }
2844
2845 return -1;
2846}
2847
Jeff Brown46b9ac02010-04-22 18:58:52 -07002848void InputDispatcher::activateConnectionLocked(Connection* connection) {
2849 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2850 if (mActiveConnections.itemAt(i) == connection) {
2851 return;
2852 }
2853 }
2854 mActiveConnections.add(connection);
2855}
2856
2857void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2858 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2859 if (mActiveConnections.itemAt(i) == connection) {
2860 mActiveConnections.removeAt(i);
2861 return;
2862 }
2863 }
2864}
2865
Jeff Brown9c3cda02010-06-15 01:31:58 -07002866void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002867 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002868}
2869
Jeff Brown9c3cda02010-06-15 01:31:58 -07002870void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002871 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002872}
2873
Jeff Brown9c3cda02010-06-15 01:31:58 -07002874void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002875 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002876 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2877 connection->getInputChannelName());
2878
Jeff Brown9c3cda02010-06-15 01:31:58 -07002879 CommandEntry* commandEntry = postCommandLocked(
2880 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002881 commandEntry->connection = connection;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002882}
2883
Jeff Brown519e0242010-09-15 15:18:56 -07002884void InputDispatcher::onANRLocked(
2885 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2886 nsecs_t eventTime, nsecs_t waitStartTime) {
2887 LOGI("Application is not responding: %s. "
2888 "%01.1fms since event, %01.1fms since wait started",
2889 getApplicationWindowLabelLocked(application, window).string(),
2890 (currentTime - eventTime) / 1000000.0,
2891 (currentTime - waitStartTime) / 1000000.0);
2892
2893 CommandEntry* commandEntry = postCommandLocked(
2894 & InputDispatcher::doNotifyANRLockedInterruptible);
2895 if (application) {
2896 commandEntry->inputApplicationHandle = application->handle;
2897 }
2898 if (window) {
2899 commandEntry->inputChannel = window->inputChannel;
2900 }
2901}
2902
Jeff Brownb88102f2010-09-08 11:49:43 -07002903void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2904 CommandEntry* commandEntry) {
2905 mLock.unlock();
2906
2907 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2908
2909 mLock.lock();
2910}
2911
Jeff Brown9c3cda02010-06-15 01:31:58 -07002912void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2913 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002914 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07002915
Jeff Brown7fbdc842010-06-17 20:52:56 -07002916 if (connection->status != Connection::STATUS_ZOMBIE) {
2917 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002918
Jeff Brown7fbdc842010-06-17 20:52:56 -07002919 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2920
2921 mLock.lock();
2922 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07002923}
2924
Jeff Brown519e0242010-09-15 15:18:56 -07002925void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07002926 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07002927 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002928
Jeff Brown519e0242010-09-15 15:18:56 -07002929 nsecs_t newTimeout = mPolicy->notifyANR(
2930 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002931
Jeff Brown519e0242010-09-15 15:18:56 -07002932 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002933
Jeff Brown519e0242010-09-15 15:18:56 -07002934 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002935}
2936
Jeff Brownb88102f2010-09-08 11:49:43 -07002937void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2938 CommandEntry* commandEntry) {
2939 KeyEntry* entry = commandEntry->keyEntry;
2940 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2941 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2942 entry->downTime, entry->eventTime);
2943
2944 mLock.unlock();
2945
2946 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2947 & mReusableKeyEvent, entry->policyFlags);
2948
2949 mLock.lock();
2950
2951 entry->interceptKeyResult = consumed
2952 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2953 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2954 mAllocator.releaseKeyEntry(entry);
2955}
2956
2957void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2958 mLock.unlock();
2959
Jeff Brown01ce2e92010-09-26 22:20:12 -07002960 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07002961
2962 mLock.lock();
2963}
2964
Jeff Brown519e0242010-09-15 15:18:56 -07002965void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
2966 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
2967 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07002968}
2969
2970void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002971 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002972 dumpDispatchStateLocked(dump);
2973}
2974
Jeff Brown9c3cda02010-06-15 01:31:58 -07002975
Jeff Brown519e0242010-09-15 15:18:56 -07002976// --- InputDispatcher::Queue ---
2977
2978template <typename T>
2979uint32_t InputDispatcher::Queue<T>::count() const {
2980 uint32_t result = 0;
2981 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
2982 result += 1;
2983 }
2984 return result;
2985}
2986
2987
Jeff Brown46b9ac02010-04-22 18:58:52 -07002988// --- InputDispatcher::Allocator ---
2989
2990InputDispatcher::Allocator::Allocator() {
2991}
2992
Jeff Brown01ce2e92010-09-26 22:20:12 -07002993InputDispatcher::InjectionState*
2994InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
2995 InjectionState* injectionState = mInjectionStatePool.alloc();
2996 injectionState->refCount = 1;
2997 injectionState->injectorPid = injectorPid;
2998 injectionState->injectorUid = injectorUid;
2999 injectionState->injectionIsAsync = false;
3000 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3001 injectionState->pendingForegroundDispatches = 0;
3002 return injectionState;
3003}
3004
Jeff Brown7fbdc842010-06-17 20:52:56 -07003005void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brownb6997262010-10-08 22:31:17 -07003006 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003007 entry->type = type;
3008 entry->refCount = 1;
3009 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07003010 entry->eventTime = eventTime;
Jeff Brownb6997262010-10-08 22:31:17 -07003011 entry->policyFlags = policyFlags;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003012 entry->injectionState = NULL;
3013}
3014
3015void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3016 if (entry->injectionState) {
3017 releaseInjectionState(entry->injectionState);
3018 entry->injectionState = NULL;
3019 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07003020}
3021
Jeff Brown46b9ac02010-04-22 18:58:52 -07003022InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07003023InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003024 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003025 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003026 return entry;
3027}
3028
Jeff Brown7fbdc842010-06-17 20:52:56 -07003029InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07003030 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003031 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3032 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003033 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003034 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003035
3036 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003037 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003038 entry->action = action;
3039 entry->flags = flags;
3040 entry->keyCode = keyCode;
3041 entry->scanCode = scanCode;
3042 entry->metaState = metaState;
3043 entry->repeatCount = repeatCount;
3044 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003045 entry->syntheticRepeat = false;
3046 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003047 return entry;
3048}
3049
Jeff Brown7fbdc842010-06-17 20:52:56 -07003050InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07003051 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003052 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3053 nsecs_t downTime, uint32_t pointerCount,
3054 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003055 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003056 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003057
3058 entry->eventTime = eventTime;
3059 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003060 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003061 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07003062 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003063 entry->metaState = metaState;
3064 entry->edgeFlags = edgeFlags;
3065 entry->xPrecision = xPrecision;
3066 entry->yPrecision = yPrecision;
3067 entry->downTime = downTime;
3068 entry->pointerCount = pointerCount;
3069 entry->firstSample.eventTime = eventTime;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003070 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003071 entry->lastSample = & entry->firstSample;
3072 for (uint32_t i = 0; i < pointerCount; i++) {
3073 entry->pointerIds[i] = pointerIds[i];
3074 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3075 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07003076 return entry;
3077}
3078
3079InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07003080 EventEntry* eventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07003081 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003082 DispatchEntry* entry = mDispatchEntryPool.alloc();
3083 entry->eventEntry = eventEntry;
3084 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07003085 entry->targetFlags = targetFlags;
3086 entry->xOffset = xOffset;
3087 entry->yOffset = yOffset;
Jeff Brownb88102f2010-09-08 11:49:43 -07003088 entry->inProgress = false;
3089 entry->headMotionSample = NULL;
3090 entry->tailMotionSample = NULL;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003091 return entry;
3092}
3093
Jeff Brown9c3cda02010-06-15 01:31:58 -07003094InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3095 CommandEntry* entry = mCommandEntryPool.alloc();
3096 entry->command = command;
3097 return entry;
3098}
3099
Jeff Brown01ce2e92010-09-26 22:20:12 -07003100void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3101 injectionState->refCount -= 1;
3102 if (injectionState->refCount == 0) {
3103 mInjectionStatePool.free(injectionState);
3104 } else {
3105 assert(injectionState->refCount > 0);
3106 }
3107}
3108
Jeff Brown46b9ac02010-04-22 18:58:52 -07003109void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3110 switch (entry->type) {
3111 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3112 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3113 break;
3114 case EventEntry::TYPE_KEY:
3115 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3116 break;
3117 case EventEntry::TYPE_MOTION:
3118 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3119 break;
3120 default:
3121 assert(false);
3122 break;
3123 }
3124}
3125
3126void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3127 ConfigurationChangedEntry* entry) {
3128 entry->refCount -= 1;
3129 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003130 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003131 mConfigurationChangeEntryPool.free(entry);
3132 } else {
3133 assert(entry->refCount > 0);
3134 }
3135}
3136
3137void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3138 entry->refCount -= 1;
3139 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003140 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003141 mKeyEntryPool.free(entry);
3142 } else {
3143 assert(entry->refCount > 0);
3144 }
3145}
3146
3147void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3148 entry->refCount -= 1;
3149 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003150 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003151 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3152 MotionSample* next = sample->next;
3153 mMotionSamplePool.free(sample);
3154 sample = next;
3155 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07003156 mMotionEntryPool.free(entry);
3157 } else {
3158 assert(entry->refCount > 0);
3159 }
3160}
3161
3162void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3163 releaseEventEntry(entry->eventEntry);
3164 mDispatchEntryPool.free(entry);
3165}
3166
Jeff Brown9c3cda02010-06-15 01:31:58 -07003167void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3168 mCommandEntryPool.free(entry);
3169}
3170
Jeff Brown46b9ac02010-04-22 18:58:52 -07003171void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003172 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003173 MotionSample* sample = mMotionSamplePool.alloc();
3174 sample->eventTime = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003175 uint32_t pointerCount = motionEntry->pointerCount;
3176 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003177 sample->pointerCoords[i] = pointerCoords[i];
3178 }
3179
3180 sample->next = NULL;
3181 motionEntry->lastSample->next = sample;
3182 motionEntry->lastSample = sample;
3183}
3184
Jeff Brown01ce2e92010-09-26 22:20:12 -07003185void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3186 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003187
Jeff Brown01ce2e92010-09-26 22:20:12 -07003188 keyEntry->dispatchInProgress = false;
3189 keyEntry->syntheticRepeat = false;
3190 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003191}
3192
3193
Jeff Brownae9fc032010-08-18 15:51:08 -07003194// --- InputDispatcher::MotionEntry ---
3195
3196uint32_t InputDispatcher::MotionEntry::countSamples() const {
3197 uint32_t count = 1;
3198 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3199 count += 1;
3200 }
3201 return count;
3202}
3203
Jeff Brownb88102f2010-09-08 11:49:43 -07003204
3205// --- InputDispatcher::InputState ---
3206
Jeff Brownb6997262010-10-08 22:31:17 -07003207InputDispatcher::InputState::InputState() {
Jeff Brownb88102f2010-09-08 11:49:43 -07003208}
3209
3210InputDispatcher::InputState::~InputState() {
3211}
3212
3213bool InputDispatcher::InputState::isNeutral() const {
3214 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3215}
3216
Jeff Brownb88102f2010-09-08 11:49:43 -07003217InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3218 const EventEntry* entry) {
3219 switch (entry->type) {
3220 case EventEntry::TYPE_KEY:
3221 return trackKey(static_cast<const KeyEntry*>(entry));
3222
3223 case EventEntry::TYPE_MOTION:
3224 return trackMotion(static_cast<const MotionEntry*>(entry));
3225
3226 default:
3227 return CONSISTENT;
3228 }
3229}
3230
3231InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3232 const KeyEntry* entry) {
3233 int32_t action = entry->action;
3234 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3235 KeyMemento& memento = mKeyMementos.editItemAt(i);
3236 if (memento.deviceId == entry->deviceId
3237 && memento.source == entry->source
3238 && memento.keyCode == entry->keyCode
3239 && memento.scanCode == entry->scanCode) {
3240 switch (action) {
3241 case AKEY_EVENT_ACTION_UP:
3242 mKeyMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003243 return CONSISTENT;
3244
3245 case AKEY_EVENT_ACTION_DOWN:
3246 return TOLERABLE;
3247
3248 default:
3249 return BROKEN;
3250 }
3251 }
3252 }
3253
3254 switch (action) {
3255 case AKEY_EVENT_ACTION_DOWN: {
3256 mKeyMementos.push();
3257 KeyMemento& memento = mKeyMementos.editTop();
3258 memento.deviceId = entry->deviceId;
3259 memento.source = entry->source;
3260 memento.keyCode = entry->keyCode;
3261 memento.scanCode = entry->scanCode;
3262 memento.downTime = entry->downTime;
3263 return CONSISTENT;
3264 }
3265
3266 default:
3267 return BROKEN;
3268 }
3269}
3270
3271InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3272 const MotionEntry* entry) {
3273 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3274 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3275 MotionMemento& memento = mMotionMementos.editItemAt(i);
3276 if (memento.deviceId == entry->deviceId
3277 && memento.source == entry->source) {
3278 switch (action) {
3279 case AMOTION_EVENT_ACTION_UP:
3280 case AMOTION_EVENT_ACTION_CANCEL:
3281 mMotionMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003282 return CONSISTENT;
3283
3284 case AMOTION_EVENT_ACTION_DOWN:
3285 return TOLERABLE;
3286
3287 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3288 if (entry->pointerCount == memento.pointerCount + 1) {
3289 memento.setPointers(entry);
3290 return CONSISTENT;
3291 }
3292 return BROKEN;
3293
3294 case AMOTION_EVENT_ACTION_POINTER_UP:
3295 if (entry->pointerCount == memento.pointerCount - 1) {
3296 memento.setPointers(entry);
3297 return CONSISTENT;
3298 }
3299 return BROKEN;
3300
3301 case AMOTION_EVENT_ACTION_MOVE:
3302 if (entry->pointerCount == memento.pointerCount) {
3303 return CONSISTENT;
3304 }
3305 return BROKEN;
3306
3307 default:
3308 return BROKEN;
3309 }
3310 }
3311 }
3312
3313 switch (action) {
3314 case AMOTION_EVENT_ACTION_DOWN: {
3315 mMotionMementos.push();
3316 MotionMemento& memento = mMotionMementos.editTop();
3317 memento.deviceId = entry->deviceId;
3318 memento.source = entry->source;
3319 memento.xPrecision = entry->xPrecision;
3320 memento.yPrecision = entry->yPrecision;
3321 memento.downTime = entry->downTime;
3322 memento.setPointers(entry);
3323 return CONSISTENT;
3324 }
3325
3326 default:
3327 return BROKEN;
3328 }
3329}
3330
3331void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3332 pointerCount = entry->pointerCount;
3333 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3334 pointerIds[i] = entry->pointerIds[i];
3335 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3336 }
3337}
3338
Jeff Brownb6997262010-10-08 22:31:17 -07003339void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3340 Allocator* allocator, Vector<EventEntry*>& outEvents,
3341 CancelationOptions options) {
3342 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003343 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brownb6997262010-10-08 22:31:17 -07003344 if (shouldCancelEvent(memento.source, options)) {
3345 outEvents.push(allocator->obtainKeyEntry(currentTime,
3346 memento.deviceId, memento.source, 0,
3347 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3348 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3349 mKeyMementos.removeAt(i);
3350 } else {
3351 i += 1;
3352 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003353 }
3354
Jeff Browna1160a72010-10-11 18:22:53 -07003355 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003356 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brownb6997262010-10-08 22:31:17 -07003357 if (shouldCancelEvent(memento.source, options)) {
3358 outEvents.push(allocator->obtainMotionEntry(currentTime,
3359 memento.deviceId, memento.source, 0,
3360 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3361 memento.xPrecision, memento.yPrecision, memento.downTime,
3362 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3363 mMotionMementos.removeAt(i);
3364 } else {
3365 i += 1;
3366 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003367 }
3368}
3369
3370void InputDispatcher::InputState::clear() {
3371 mKeyMementos.clear();
3372 mMotionMementos.clear();
Jeff Brownb6997262010-10-08 22:31:17 -07003373}
3374
3375bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3376 CancelationOptions options) {
3377 switch (options) {
3378 case CANCEL_POINTER_EVENTS:
3379 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3380 case CANCEL_NON_POINTER_EVENTS:
3381 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3382 default:
3383 return true;
3384 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003385}
3386
3387
Jeff Brown46b9ac02010-04-22 18:58:52 -07003388// --- InputDispatcher::Connection ---
3389
3390InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3391 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown519e0242010-09-15 15:18:56 -07003392 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003393}
3394
3395InputDispatcher::Connection::~Connection() {
3396}
3397
3398status_t InputDispatcher::Connection::initialize() {
3399 return inputPublisher.initialize();
3400}
3401
Jeff Brown9c3cda02010-06-15 01:31:58 -07003402const char* InputDispatcher::Connection::getStatusLabel() const {
3403 switch (status) {
3404 case STATUS_NORMAL:
3405 return "NORMAL";
3406
3407 case STATUS_BROKEN:
3408 return "BROKEN";
3409
Jeff Brown9c3cda02010-06-15 01:31:58 -07003410 case STATUS_ZOMBIE:
3411 return "ZOMBIE";
3412
3413 default:
3414 return "UNKNOWN";
3415 }
3416}
3417
Jeff Brown46b9ac02010-04-22 18:58:52 -07003418InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3419 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07003420 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3421 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003422 if (dispatchEntry->eventEntry == eventEntry) {
3423 return dispatchEntry;
3424 }
3425 }
3426 return NULL;
3427}
3428
Jeff Brownb88102f2010-09-08 11:49:43 -07003429
Jeff Brown9c3cda02010-06-15 01:31:58 -07003430// --- InputDispatcher::CommandEntry ---
3431
Jeff Brownb88102f2010-09-08 11:49:43 -07003432InputDispatcher::CommandEntry::CommandEntry() :
3433 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003434}
3435
3436InputDispatcher::CommandEntry::~CommandEntry() {
3437}
3438
Jeff Brown46b9ac02010-04-22 18:58:52 -07003439
Jeff Brown01ce2e92010-09-26 22:20:12 -07003440// --- InputDispatcher::TouchState ---
3441
3442InputDispatcher::TouchState::TouchState() :
3443 down(false), split(false) {
3444}
3445
3446InputDispatcher::TouchState::~TouchState() {
3447}
3448
3449void InputDispatcher::TouchState::reset() {
3450 down = false;
3451 split = false;
3452 windows.clear();
3453}
3454
3455void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3456 down = other.down;
3457 split = other.split;
3458 windows.clear();
3459 windows.appendVector(other.windows);
3460}
3461
3462void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3463 int32_t targetFlags, BitSet32 pointerIds) {
3464 if (targetFlags & InputTarget::FLAG_SPLIT) {
3465 split = true;
3466 }
3467
3468 for (size_t i = 0; i < windows.size(); i++) {
3469 TouchedWindow& touchedWindow = windows.editItemAt(i);
3470 if (touchedWindow.window == window) {
3471 touchedWindow.targetFlags |= targetFlags;
3472 touchedWindow.pointerIds.value |= pointerIds.value;
3473 return;
3474 }
3475 }
3476
3477 windows.push();
3478
3479 TouchedWindow& touchedWindow = windows.editTop();
3480 touchedWindow.window = window;
3481 touchedWindow.targetFlags = targetFlags;
3482 touchedWindow.pointerIds = pointerIds;
3483 touchedWindow.channel = window->inputChannel;
3484}
3485
3486void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3487 for (size_t i = 0 ; i < windows.size(); ) {
3488 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3489 windows.removeAt(i);
3490 } else {
3491 i += 1;
3492 }
3493 }
3494}
3495
3496const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3497 for (size_t i = 0; i < windows.size(); i++) {
3498 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3499 return windows[i].window;
3500 }
3501 }
3502 return NULL;
3503}
3504
3505
Jeff Brown46b9ac02010-04-22 18:58:52 -07003506// --- InputDispatcherThread ---
3507
3508InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3509 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3510}
3511
3512InputDispatcherThread::~InputDispatcherThread() {
3513}
3514
3515bool InputDispatcherThread::threadLoop() {
3516 mDispatcher->dispatchOnce();
3517 return true;
3518}
3519
3520} // namespace android