blob: f9c0b9154b4abec821003be91d62ea694e541713 [file] [log] [blame]
Jeff Browne839a582010-04-22 18:58:52 -07001//
2// Copyright 2010 The Android Open Source Project
3//
4// The input dispatcher.
5//
6#define LOG_TAG "InputDispatcher"
7
8//#define LOG_NDEBUG 0
9
10// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown50de30a2010-06-22 01:27:15 -070011#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Browne839a582010-04-22 18:58:52 -070012
13// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown50de30a2010-06-22 01:27:15 -070014#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Browne839a582010-04-22 18:58:52 -070015
16// Log debug messages about batching.
Jeff Brown50de30a2010-06-22 01:27:15 -070017#define DEBUG_BATCHING 0
Jeff Browne839a582010-04-22 18:58:52 -070018
19// Log debug messages about the dispatch cycle.
Jeff Brown50de30a2010-06-22 01:27:15 -070020#define DEBUG_DISPATCH_CYCLE 0
Jeff Browne839a582010-04-22 18:58:52 -070021
Jeff Brown54bc2812010-06-15 01:31:58 -070022// Log debug messages about registrations.
Jeff Brown50de30a2010-06-22 01:27:15 -070023#define DEBUG_REGISTRATION 0
Jeff Brown54bc2812010-06-15 01:31:58 -070024
Jeff Browne839a582010-04-22 18:58:52 -070025// Log debug messages about performance statistics.
Jeff Brown50de30a2010-06-22 01:27:15 -070026#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Browne839a582010-04-22 18:58:52 -070027
Jeff Brown51d45a72010-06-17 20:52:56 -070028// Log debug messages about input event injection.
Jeff Brown50de30a2010-06-22 01:27:15 -070029#define DEBUG_INJECTION 0
Jeff Brown51d45a72010-06-17 20:52:56 -070030
Jeff Brown542412c2010-08-18 15:51:08 -070031// Log debug messages about input event throttling.
32#define DEBUG_THROTTLING 0
33
Jeff Browna665ca82010-09-08 11:49:43 -070034// Log debug messages about input focus tracking.
35#define DEBUG_FOCUS 0
36
37// Log debug messages about the app switch latency optimization.
38#define DEBUG_APP_SWITCH 0
39
Jeff Browne839a582010-04-22 18:58:52 -070040#include <cutils/log.h>
41#include <ui/InputDispatcher.h>
Jeff Browna665ca82010-09-08 11:49:43 -070042#include <ui/PowerManager.h>
Jeff Browne839a582010-04-22 18:58:52 -070043
44#include <stddef.h>
45#include <unistd.h>
Jeff Browne839a582010-04-22 18:58:52 -070046#include <errno.h>
47#include <limits.h>
Jeff Browne839a582010-04-22 18:58:52 -070048
Jeff Brown2806e382010-10-01 17:46:21 -070049#define INDENT " "
50#define INDENT2 " "
51
Jeff Browne839a582010-04-22 18:58:52 -070052namespace android {
53
Jeff Brownf6149c32010-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 Browna665ca82010-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 Browne839a582010-04-22 18:58:52 -070066
Jeff Brown51d45a72010-06-17 20:52:56 -070067static inline nsecs_t now() {
68 return systemTime(SYSTEM_TIME_MONOTONIC);
69}
70
Jeff Browna665ca82010-09-08 11:49:43 -070071static inline const char* toString(bool value) {
72 return value ? "true" : "false";
73}
74
Jeff Brownd1b0a2b2010-09-26 22:20:12 -070075static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
76 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
77 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
78}
79
80static bool isValidKeyAction(int32_t action) {
81 switch (action) {
82 case AKEY_EVENT_ACTION_DOWN:
83 case AKEY_EVENT_ACTION_UP:
84 return true;
85 default:
86 return false;
87 }
88}
89
90static bool validateKeyEvent(int32_t action) {
91 if (! isValidKeyAction(action)) {
92 LOGE("Key event has invalid action code 0x%x", action);
93 return false;
94 }
95 return true;
96}
97
Jeff Brown90f0cee2010-10-08 22:31:17 -070098static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -070099 switch (action & AMOTION_EVENT_ACTION_MASK) {
100 case AMOTION_EVENT_ACTION_DOWN:
101 case AMOTION_EVENT_ACTION_UP:
102 case AMOTION_EVENT_ACTION_CANCEL:
103 case AMOTION_EVENT_ACTION_MOVE:
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700104 case AMOTION_EVENT_ACTION_OUTSIDE:
105 return true;
Jeff Brown90f0cee2010-10-08 22:31:17 -0700106 case AMOTION_EVENT_ACTION_POINTER_DOWN:
107 case AMOTION_EVENT_ACTION_POINTER_UP: {
108 int32_t index = getMotionEventActionPointerIndex(action);
109 return index >= 0 && size_t(index) < pointerCount;
110 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700111 default:
112 return false;
113 }
114}
115
116static bool validateMotionEvent(int32_t action, size_t pointerCount,
117 const int32_t* pointerIds) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700118 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700119 LOGE("Motion event has invalid action code 0x%x", action);
120 return false;
121 }
122 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
123 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
124 pointerCount, MAX_POINTERS);
125 return false;
126 }
Jeff Brown3c3cc622010-10-20 15:33:38 -0700127 BitSet32 pointerIdBits;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700128 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brown3c3cc622010-10-20 15:33:38 -0700129 int32_t id = pointerIds[i];
130 if (id < 0 || id > MAX_POINTER_ID) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700131 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
Jeff Brown3c3cc622010-10-20 15:33:38 -0700132 id, MAX_POINTER_ID);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700133 return false;
134 }
Jeff Brown3c3cc622010-10-20 15:33:38 -0700135 if (pointerIdBits.hasBit(id)) {
136 LOGE("Motion event has duplicate pointer id %d", id);
137 return false;
138 }
139 pointerIdBits.markBit(id);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700140 }
141 return true;
142}
143
Jeff Browna665ca82010-09-08 11:49:43 -0700144
145// --- InputWindow ---
146
Jeff Browna665ca82010-09-08 11:49:43 -0700147bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
148 return x >= touchableAreaLeft && x <= touchableAreaRight
149 && y >= touchableAreaTop && y <= touchableAreaBottom;
150}
151
Jeff Brown35cf0e92010-10-05 12:26:23 -0700152bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
153 return x >= frameLeft && x <= frameRight
154 && y >= frameTop && y <= frameBottom;
155}
156
157bool InputWindow::isTrustedOverlay() const {
158 return layoutParamsType == TYPE_INPUT_METHOD
Jeff Browne68d9e02010-10-15 00:54:27 -0700159 || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
160 || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
Jeff Brown35cf0e92010-10-05 12:26:23 -0700161}
162
Jeff Browna665ca82010-09-08 11:49:43 -0700163
Jeff Browne839a582010-04-22 18:58:52 -0700164// --- InputDispatcher ---
165
Jeff Brown54bc2812010-06-15 01:31:58 -0700166InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Browna665ca82010-09-08 11:49:43 -0700167 mPolicy(policy),
168 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
169 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700170 mFocusedWindow(NULL),
Jeff Browna665ca82010-09-08 11:49:43 -0700171 mFocusedApplication(NULL),
172 mCurrentInputTargetsValid(false),
173 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown59abe7e2010-09-13 23:17:30 -0700174 mLooper = new Looper(false);
Jeff Browne839a582010-04-22 18:58:52 -0700175
Jeff Browna665ca82010-09-08 11:49:43 -0700176 mInboundQueue.headSentinel.refCount = -1;
177 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
178 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Browne839a582010-04-22 18:58:52 -0700179
Jeff Browna665ca82010-09-08 11:49:43 -0700180 mInboundQueue.tailSentinel.refCount = -1;
181 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
182 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Browne839a582010-04-22 18:58:52 -0700183
184 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown54bc2812010-06-15 01:31:58 -0700185
Jeff Brown542412c2010-08-18 15:51:08 -0700186 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
187 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
188 mThrottleState.lastDeviceId = -1;
189
190#if DEBUG_THROTTLING
191 mThrottleState.originalSampleCount = 0;
192 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
193#endif
Jeff Browne839a582010-04-22 18:58:52 -0700194}
195
196InputDispatcher::~InputDispatcher() {
Jeff Browna665ca82010-09-08 11:49:43 -0700197 { // acquire lock
198 AutoMutex _l(mLock);
199
200 resetKeyRepeatLocked();
Jeff Brownd8816c32010-09-16 14:07:33 -0700201 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700202 drainInboundQueueLocked();
203 }
Jeff Browne839a582010-04-22 18:58:52 -0700204
205 while (mConnectionsByReceiveFd.size() != 0) {
206 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
207 }
Jeff Browne839a582010-04-22 18:58:52 -0700208}
209
210void InputDispatcher::dispatchOnce() {
Jeff Brown54bc2812010-06-15 01:31:58 -0700211 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brown61ce3982010-09-07 10:44:57 -0700212 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Browne839a582010-04-22 18:58:52 -0700213
Jeff Browne839a582010-04-22 18:58:52 -0700214 nsecs_t nextWakeupTime = LONG_LONG_MAX;
215 { // acquire lock
216 AutoMutex _l(mLock);
Jeff Browna665ca82010-09-08 11:49:43 -0700217 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Browne839a582010-04-22 18:58:52 -0700218
Jeff Browna665ca82010-09-08 11:49:43 -0700219 if (runCommandsLockedInterruptible()) {
220 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Browne839a582010-04-22 18:58:52 -0700221 }
Jeff Browne839a582010-04-22 18:58:52 -0700222 } // release lock
223
Jeff Browna665ca82010-09-08 11:49:43 -0700224 // Wait for callback or timeout or wake. (make sure we round up, not down)
225 nsecs_t currentTime = now();
226 int32_t timeoutMillis;
227 if (nextWakeupTime > currentTime) {
228 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
229 timeout = (timeout + 999999LL) / 1000000LL;
230 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
231 } else {
232 timeoutMillis = 0;
233 }
234
Jeff Brown59abe7e2010-09-13 23:17:30 -0700235 mLooper->pollOnce(timeoutMillis);
Jeff Browna665ca82010-09-08 11:49:43 -0700236}
237
238void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
239 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
240 nsecs_t currentTime = now();
241
242 // Reset the key repeat timer whenever we disallow key events, even if the next event
243 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
244 // out of sleep.
245 if (keyRepeatTimeout < 0) {
246 resetKeyRepeatLocked();
247 }
248
Jeff Browna665ca82010-09-08 11:49:43 -0700249 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
250 if (mDispatchFrozen) {
251#if DEBUG_FOCUS
252 LOGD("Dispatch frozen. Waiting some more.");
253#endif
254 return;
255 }
256
257 // Optimize latency of app switches.
258 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
259 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
260 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
261 if (mAppSwitchDueTime < *nextWakeupTime) {
262 *nextWakeupTime = mAppSwitchDueTime;
263 }
264
Jeff Browna665ca82010-09-08 11:49:43 -0700265 // Ready to start a new event.
266 // If we don't already have a pending event, go grab one.
267 if (! mPendingEvent) {
268 if (mInboundQueue.isEmpty()) {
269 if (isAppSwitchDue) {
270 // The inbound queue is empty so the app switch key we were waiting
271 // for will never arrive. Stop waiting for it.
272 resetPendingAppSwitchLocked(false);
273 isAppSwitchDue = false;
274 }
275
276 // Synthesize a key repeat if appropriate.
277 if (mKeyRepeatState.lastKeyEntry) {
278 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
279 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
280 } else {
281 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
282 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
283 }
284 }
285 }
286 if (! mPendingEvent) {
287 return;
288 }
289 } else {
290 // Inbound queue has at least one entry.
291 EventEntry* entry = mInboundQueue.headSentinel.next;
292
293 // Throttle the entry if it is a move event and there are no
294 // other events behind it in the queue. Due to movement batching, additional
295 // samples may be appended to this event by the time the throttling timeout
296 // expires.
297 // TODO Make this smarter and consider throttling per device independently.
Jeff Brown90f0cee2010-10-08 22:31:17 -0700298 if (entry->type == EventEntry::TYPE_MOTION
299 && !isAppSwitchDue
300 && mDispatchEnabled
301 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
302 && !entry->isInjected()) {
Jeff Browna665ca82010-09-08 11:49:43 -0700303 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
304 int32_t deviceId = motionEntry->deviceId;
305 uint32_t source = motionEntry->source;
306 if (! isAppSwitchDue
307 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
308 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
309 && deviceId == mThrottleState.lastDeviceId
310 && source == mThrottleState.lastSource) {
311 nsecs_t nextTime = mThrottleState.lastEventTime
312 + mThrottleState.minTimeBetweenEvents;
313 if (currentTime < nextTime) {
314 // Throttle it!
315#if DEBUG_THROTTLING
316 LOGD("Throttling - Delaying motion event for "
317 "device 0x%x, source 0x%08x by up to %0.3fms.",
318 deviceId, source, (nextTime - currentTime) * 0.000001);
319#endif
320 if (nextTime < *nextWakeupTime) {
321 *nextWakeupTime = nextTime;
322 }
323 if (mThrottleState.originalSampleCount == 0) {
324 mThrottleState.originalSampleCount =
325 motionEntry->countSamples();
326 }
327 return;
328 }
329 }
330
331#if DEBUG_THROTTLING
332 if (mThrottleState.originalSampleCount != 0) {
333 uint32_t count = motionEntry->countSamples();
334 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
335 count - mThrottleState.originalSampleCount,
336 mThrottleState.originalSampleCount, count);
337 mThrottleState.originalSampleCount = 0;
338 }
339#endif
340
341 mThrottleState.lastEventTime = entry->eventTime < currentTime
342 ? entry->eventTime : currentTime;
343 mThrottleState.lastDeviceId = deviceId;
344 mThrottleState.lastSource = source;
345 }
346
347 mInboundQueue.dequeue(entry);
348 mPendingEvent = entry;
349 }
Jeff Brownef3a8232010-10-18 13:21:23 -0700350
351 // Poke user activity for this event.
352 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
353 pokeUserActivityLocked(mPendingEvent);
354 }
Jeff Browna665ca82010-09-08 11:49:43 -0700355 }
356
357 // Now we have an event to dispatch.
358 assert(mPendingEvent != NULL);
Jeff Brownd8816c32010-09-16 14:07:33 -0700359 bool done = false;
Jeff Brown90f0cee2010-10-08 22:31:17 -0700360 DropReason dropReason = DROP_REASON_NOT_DROPPED;
361 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
362 dropReason = DROP_REASON_POLICY;
363 } else if (!mDispatchEnabled) {
364 dropReason = DROP_REASON_DISABLED;
365 }
Jeff Browna665ca82010-09-08 11:49:43 -0700366 switch (mPendingEvent->type) {
367 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
368 ConfigurationChangedEntry* typedEntry =
369 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brownd8816c32010-09-16 14:07:33 -0700370 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700371 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Browna665ca82010-09-08 11:49:43 -0700372 break;
373 }
374
375 case EventEntry::TYPE_KEY: {
376 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700377 if (isAppSwitchDue) {
378 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700379 resetPendingAppSwitchLocked(true);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700380 isAppSwitchDue = false;
381 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
382 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700383 }
384 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700385 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Brown33d54ce2010-10-11 14:20:19 -0700386 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700387 break;
388 }
389
390 case EventEntry::TYPE_MOTION: {
391 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700392 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
393 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700394 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700395 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Brown33d54ce2010-10-11 14:20:19 -0700396 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700397 break;
398 }
399
400 default:
401 assert(false);
Jeff Browna665ca82010-09-08 11:49:43 -0700402 break;
403 }
404
Jeff Brownd8816c32010-09-16 14:07:33 -0700405 if (done) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700406 if (dropReason != DROP_REASON_NOT_DROPPED) {
407 dropInboundEventLocked(mPendingEvent, dropReason);
408 }
409
Jeff Brownd8816c32010-09-16 14:07:33 -0700410 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700411 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
412 }
413}
414
415bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
416 bool needWake = mInboundQueue.isEmpty();
417 mInboundQueue.enqueueAtTail(entry);
418
419 switch (entry->type) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700420 case EventEntry::TYPE_KEY: {
421 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
422 if (isAppSwitchKeyEventLocked(keyEntry)) {
423 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
424 mAppSwitchSawKeyDown = true;
425 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
426 if (mAppSwitchSawKeyDown) {
427#if DEBUG_APP_SWITCH
428 LOGD("App switch is pending!");
429#endif
430 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
431 mAppSwitchSawKeyDown = false;
432 needWake = true;
433 }
434 }
435 }
Jeff Browna665ca82010-09-08 11:49:43 -0700436 break;
437 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700438 }
Jeff Browna665ca82010-09-08 11:49:43 -0700439
440 return needWake;
441}
442
Jeff Brown90f0cee2010-10-08 22:31:17 -0700443void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
444 const char* reason;
445 switch (dropReason) {
446 case DROP_REASON_POLICY:
Jeff Brown33d54ce2010-10-11 14:20:19 -0700447#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Browna8ed8562010-10-11 23:32:49 -0700448 LOGD("Dropped event because policy consumed it.");
Jeff Brown33d54ce2010-10-11 14:20:19 -0700449#endif
Jeff Browna8ed8562010-10-11 23:32:49 -0700450 reason = "inbound event was dropped because the policy consumed it";
Jeff Brown90f0cee2010-10-08 22:31:17 -0700451 break;
452 case DROP_REASON_DISABLED:
453 LOGI("Dropped event because input dispatch is disabled.");
454 reason = "inbound event was dropped because input dispatch is disabled";
455 break;
456 case DROP_REASON_APP_SWITCH:
457 LOGI("Dropped event because of pending overdue app switch.");
458 reason = "inbound event was dropped because of pending overdue app switch";
459 break;
460 default:
461 assert(false);
462 return;
463 }
464
465 switch (entry->type) {
466 case EventEntry::TYPE_KEY:
467 synthesizeCancelationEventsForAllConnectionsLocked(
468 InputState::CANCEL_NON_POINTER_EVENTS, reason);
469 break;
470 case EventEntry::TYPE_MOTION: {
471 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
472 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
473 synthesizeCancelationEventsForAllConnectionsLocked(
474 InputState::CANCEL_POINTER_EVENTS, reason);
475 } else {
476 synthesizeCancelationEventsForAllConnectionsLocked(
477 InputState::CANCEL_NON_POINTER_EVENTS, reason);
478 }
479 break;
480 }
481 }
482}
483
484bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Browna665ca82010-09-08 11:49:43 -0700485 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
486}
487
Jeff Brown90f0cee2010-10-08 22:31:17 -0700488bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
489 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
490 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Brown33d54ce2010-10-11 14:20:19 -0700491 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brown90f0cee2010-10-08 22:31:17 -0700492 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
493}
494
Jeff Browna665ca82010-09-08 11:49:43 -0700495bool InputDispatcher::isAppSwitchPendingLocked() {
496 return mAppSwitchDueTime != LONG_LONG_MAX;
497}
498
Jeff Browna665ca82010-09-08 11:49:43 -0700499void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
500 mAppSwitchDueTime = LONG_LONG_MAX;
501
502#if DEBUG_APP_SWITCH
503 if (handled) {
504 LOGD("App switch has arrived.");
505 } else {
506 LOGD("App switch was abandoned.");
507 }
508#endif
Jeff Browne839a582010-04-22 18:58:52 -0700509}
510
Jeff Brown54bc2812010-06-15 01:31:58 -0700511bool InputDispatcher::runCommandsLockedInterruptible() {
512 if (mCommandQueue.isEmpty()) {
513 return false;
514 }
Jeff Browne839a582010-04-22 18:58:52 -0700515
Jeff Brown54bc2812010-06-15 01:31:58 -0700516 do {
517 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
518
519 Command command = commandEntry->command;
520 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
521
Jeff Brown51d45a72010-06-17 20:52:56 -0700522 commandEntry->connection.clear();
Jeff Brown54bc2812010-06-15 01:31:58 -0700523 mAllocator.releaseCommandEntry(commandEntry);
524 } while (! mCommandQueue.isEmpty());
525 return true;
Jeff Browne839a582010-04-22 18:58:52 -0700526}
527
Jeff Brown54bc2812010-06-15 01:31:58 -0700528InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
529 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
530 mCommandQueue.enqueueAtTail(commandEntry);
531 return commandEntry;
532}
533
Jeff Browna665ca82010-09-08 11:49:43 -0700534void InputDispatcher::drainInboundQueueLocked() {
535 while (! mInboundQueue.isEmpty()) {
536 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brownd8816c32010-09-16 14:07:33 -0700537 releaseInboundEventLocked(entry);
Jeff Browne839a582010-04-22 18:58:52 -0700538 }
Jeff Browne839a582010-04-22 18:58:52 -0700539}
540
Jeff Brownd8816c32010-09-16 14:07:33 -0700541void InputDispatcher::releasePendingEventLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700542 if (mPendingEvent) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700543 releaseInboundEventLocked(mPendingEvent);
Jeff Browna665ca82010-09-08 11:49:43 -0700544 mPendingEvent = NULL;
545 }
546}
547
Jeff Brownd8816c32010-09-16 14:07:33 -0700548void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700549 InjectionState* injectionState = entry->injectionState;
550 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Browna665ca82010-09-08 11:49:43 -0700551#if DEBUG_DISPATCH_CYCLE
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700552 LOGD("Injected inbound event was dropped.");
Jeff Browna665ca82010-09-08 11:49:43 -0700553#endif
554 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
555 }
556 mAllocator.releaseEventEntry(entry);
557}
558
Jeff Browna665ca82010-09-08 11:49:43 -0700559void InputDispatcher::resetKeyRepeatLocked() {
560 if (mKeyRepeatState.lastKeyEntry) {
561 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
562 mKeyRepeatState.lastKeyEntry = NULL;
563 }
564}
565
566InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brown61ce3982010-09-07 10:44:57 -0700567 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown50de30a2010-06-22 01:27:15 -0700568 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
569
Jeff Brown50de30a2010-06-22 01:27:15 -0700570 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown33d54ce2010-10-11 14:20:19 -0700571 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
572 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Browne839a582010-04-22 18:58:52 -0700573 if (entry->refCount == 1) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700574 mAllocator.recycleKeyEntry(entry);
Jeff Brown51d45a72010-06-17 20:52:56 -0700575 entry->eventTime = currentTime;
Jeff Brown51d45a72010-06-17 20:52:56 -0700576 entry->policyFlags = policyFlags;
Jeff Browne839a582010-04-22 18:58:52 -0700577 entry->repeatCount += 1;
578 } else {
Jeff Brown51d45a72010-06-17 20:52:56 -0700579 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700580 entry->deviceId, entry->source, policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700581 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brownf16c26d2010-07-02 15:37:36 -0700582 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Browne839a582010-04-22 18:58:52 -0700583
584 mKeyRepeatState.lastKeyEntry = newEntry;
585 mAllocator.releaseKeyEntry(entry);
586
587 entry = newEntry;
588 }
Jeff Browna665ca82010-09-08 11:49:43 -0700589 entry->syntheticRepeat = true;
590
591 // Increment reference count since we keep a reference to the event in
592 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
593 entry->refCount += 1;
Jeff Browne839a582010-04-22 18:58:52 -0700594
Jeff Brownf16c26d2010-07-02 15:37:36 -0700595 if (entry->repeatCount == 1) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700596 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brownf16c26d2010-07-02 15:37:36 -0700597 }
598
Jeff Brown61ce3982010-09-07 10:44:57 -0700599 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Browna665ca82010-09-08 11:49:43 -0700600 return entry;
Jeff Browne839a582010-04-22 18:58:52 -0700601}
602
Jeff Browna665ca82010-09-08 11:49:43 -0700603bool InputDispatcher::dispatchConfigurationChangedLocked(
604 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Browne839a582010-04-22 18:58:52 -0700605#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Browna665ca82010-09-08 11:49:43 -0700606 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
607#endif
608
609 // Reset key repeating in case a keyboard device was added or removed or something.
610 resetKeyRepeatLocked();
611
612 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
613 CommandEntry* commandEntry = postCommandLocked(
614 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
615 commandEntry->eventTime = entry->eventTime;
616 return true;
617}
618
619bool InputDispatcher::dispatchKeyLocked(
620 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brown33d54ce2010-10-11 14:20:19 -0700621 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brown92988aa2010-11-02 17:58:22 -0700622 // Preprocessing.
623 if (! entry->dispatchInProgress) {
624 if (entry->repeatCount == 0
625 && entry->action == AKEY_EVENT_ACTION_DOWN
626 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
627 && !entry->isInjected()) {
628 if (mKeyRepeatState.lastKeyEntry
629 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
630 // We have seen two identical key downs in a row which indicates that the device
631 // driver is automatically generating key repeats itself. We take note of the
632 // repeat here, but we disable our own next key repeat timer since it is clear that
633 // we will not need to synthesize key repeats ourselves.
634 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
635 resetKeyRepeatLocked();
636 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
637 } else {
638 // Not a repeat. Save key down state in case we do see a repeat later.
639 resetKeyRepeatLocked();
640 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
641 }
642 mKeyRepeatState.lastKeyEntry = entry;
643 entry->refCount += 1;
644 } else if (! entry->syntheticRepeat) {
645 resetKeyRepeatLocked();
646 }
647
648 entry->dispatchInProgress = true;
649 resetTargetsLocked();
650
651 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
652 }
653
Jeff Brownd8816c32010-09-16 14:07:33 -0700654 // Give the policy a chance to intercept the key.
655 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Brown33d54ce2010-10-11 14:20:19 -0700656 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700657 CommandEntry* commandEntry = postCommandLocked(
658 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Brown33d54ce2010-10-11 14:20:19 -0700659 if (mFocusedWindow) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700660 commandEntry->inputChannel = mFocusedWindow->inputChannel;
661 }
662 commandEntry->keyEntry = entry;
663 entry->refCount += 1;
664 return false; // wait for the command to run
665 } else {
666 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
667 }
668 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Brown33d54ce2010-10-11 14:20:19 -0700669 if (*dropReason == DROP_REASON_NOT_DROPPED) {
670 *dropReason = DROP_REASON_POLICY;
671 }
Jeff Brownd8816c32010-09-16 14:07:33 -0700672 }
673
674 // Clean up if dropping the event.
Jeff Brown33d54ce2010-10-11 14:20:19 -0700675 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700676 resetTargetsLocked();
Jeff Browna8ed8562010-10-11 23:32:49 -0700677 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
678 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brownd8816c32010-09-16 14:07:33 -0700679 return true;
680 }
681
Jeff Browna665ca82010-09-08 11:49:43 -0700682 // Identify targets.
683 if (! mCurrentInputTargetsValid) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700684 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
685 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700686 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
687 return false;
688 }
689
690 setInjectionResultLocked(entry, injectionResult);
691 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
692 return true;
693 }
694
695 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700696 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700697 }
698
699 // Dispatch the key.
700 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Browna665ca82010-09-08 11:49:43 -0700701 return true;
702}
703
704void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
705#if DEBUG_OUTBOUND_EVENT_DETAILS
706 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
707 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
Jeff Brown92988aa2010-11-02 17:58:22 -0700708 "repeatCount=%d, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700709 prefix,
710 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
711 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Jeff Brown92988aa2010-11-02 17:58:22 -0700712 entry->repeatCount, entry->downTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700713#endif
714}
715
716bool InputDispatcher::dispatchMotionLocked(
Jeff Brown33d54ce2010-10-11 14:20:19 -0700717 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brown92988aa2010-11-02 17:58:22 -0700718 // Preprocessing.
719 if (! entry->dispatchInProgress) {
720 entry->dispatchInProgress = true;
721 resetTargetsLocked();
722
723 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
724 }
725
Jeff Brownd8816c32010-09-16 14:07:33 -0700726 // Clean up if dropping the event.
Jeff Brown33d54ce2010-10-11 14:20:19 -0700727 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700728 resetTargetsLocked();
Jeff Browna8ed8562010-10-11 23:32:49 -0700729 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
730 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brownd8816c32010-09-16 14:07:33 -0700731 return true;
732 }
733
Jeff Browna665ca82010-09-08 11:49:43 -0700734 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
735
736 // Identify targets.
737 if (! mCurrentInputTargetsValid) {
Jeff Browna665ca82010-09-08 11:49:43 -0700738 int32_t injectionResult;
739 if (isPointerEvent) {
740 // Pointer event. (eg. touchscreen)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700741 injectionResult = findTouchedWindowTargetsLocked(currentTime,
742 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700743 } else {
744 // Non touch event. (eg. trackball)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700745 injectionResult = findFocusedWindowTargetsLocked(currentTime,
746 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700747 }
748 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
749 return false;
750 }
751
752 setInjectionResultLocked(entry, injectionResult);
753 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
754 return true;
755 }
756
757 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700758 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700759 }
760
761 // Dispatch the motion.
762 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Browna665ca82010-09-08 11:49:43 -0700763 return true;
764}
765
766
767void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
768#if DEBUG_OUTBOUND_EVENT_DETAILS
769 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700770 "action=0x%x, flags=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700771 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700772 prefix,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700773 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
774 entry->action, entry->flags,
Jeff Browne839a582010-04-22 18:58:52 -0700775 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
776 entry->downTime);
777
778 // Print the most recent sample that we have available, this may change due to batching.
779 size_t sampleCount = 1;
Jeff Browna665ca82010-09-08 11:49:43 -0700780 const MotionSample* sample = & entry->firstSample;
Jeff Browne839a582010-04-22 18:58:52 -0700781 for (; sample->next != NULL; sample = sample->next) {
782 sampleCount += 1;
783 }
784 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -0700785 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700786 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -0700787 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -0700788 i, entry->pointerIds[i],
Jeff Brown38a7fab2010-08-30 03:02:23 -0700789 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
790 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
791 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
792 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
793 sample->pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -0700794 }
795
796 // Keep in mind that due to batching, it is possible for the number of samples actually
797 // dispatched to change before the application finally consumed them.
Jeff Brown5c1ed842010-07-14 18:48:53 -0700798 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -0700799 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
800 }
801#endif
Jeff Browne839a582010-04-22 18:58:52 -0700802}
803
804void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
805 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
806#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700807 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700808 "resumeWithAppendedMotionSample=%s",
Jeff Browna665ca82010-09-08 11:49:43 -0700809 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -0700810#endif
811
Jeff Brown54bc2812010-06-15 01:31:58 -0700812 assert(eventEntry->dispatchInProgress); // should already have been set to true
813
Jeff Brownef3a8232010-10-18 13:21:23 -0700814 pokeUserActivityLocked(eventEntry);
815
Jeff Browne839a582010-04-22 18:58:52 -0700816 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
817 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
818
Jeff Brown53a415e2010-09-15 15:18:56 -0700819 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -0700820 if (connectionIndex >= 0) {
821 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown51d45a72010-06-17 20:52:56 -0700822 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -0700823 resumeWithAppendedMotionSample);
824 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700825#if DEBUG_FOCUS
826 LOGD("Dropping event delivery to target with channel '%s' because it "
827 "is no longer registered with the input dispatcher.",
Jeff Browne839a582010-04-22 18:58:52 -0700828 inputTarget.inputChannel->getName().string());
Jeff Brown90f0cee2010-10-08 22:31:17 -0700829#endif
Jeff Browne839a582010-04-22 18:58:52 -0700830 }
831 }
832}
833
Jeff Brownd8816c32010-09-16 14:07:33 -0700834void InputDispatcher::resetTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700835 mCurrentInputTargetsValid = false;
836 mCurrentInputTargets.clear();
Jeff Browna665ca82010-09-08 11:49:43 -0700837 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
838}
839
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700840void InputDispatcher::commitTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700841 mCurrentInputTargetsValid = true;
842}
843
844int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
845 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
846 nsecs_t* nextWakeupTime) {
847 if (application == NULL && window == NULL) {
848 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
849#if DEBUG_FOCUS
850 LOGD("Waiting for system to become ready for input.");
851#endif
852 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
853 mInputTargetWaitStartTime = currentTime;
854 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
855 mInputTargetWaitTimeoutExpired = false;
856 }
857 } else {
858 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
859#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700860 LOGD("Waiting for application to become ready for input: %s",
861 getApplicationWindowLabelLocked(application, window).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700862#endif
863 nsecs_t timeout = window ? window->dispatchingTimeout :
864 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
865
866 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
867 mInputTargetWaitStartTime = currentTime;
868 mInputTargetWaitTimeoutTime = currentTime + timeout;
869 mInputTargetWaitTimeoutExpired = false;
870 }
871 }
872
873 if (mInputTargetWaitTimeoutExpired) {
874 return INPUT_EVENT_INJECTION_TIMED_OUT;
875 }
876
877 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown53a415e2010-09-15 15:18:56 -0700878 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700879
880 // Force poll loop to wake up immediately on next iteration once we get the
881 // ANR response back from the policy.
882 *nextWakeupTime = LONG_LONG_MIN;
883 return INPUT_EVENT_INJECTION_PENDING;
884 } else {
885 // Force poll loop to wake up when timeout is due.
886 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
887 *nextWakeupTime = mInputTargetWaitTimeoutTime;
888 }
889 return INPUT_EVENT_INJECTION_PENDING;
890 }
891}
892
Jeff Brown53a415e2010-09-15 15:18:56 -0700893void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
894 const sp<InputChannel>& inputChannel) {
Jeff Browna665ca82010-09-08 11:49:43 -0700895 if (newTimeout > 0) {
896 // Extend the timeout.
897 mInputTargetWaitTimeoutTime = now() + newTimeout;
898 } else {
899 // Give up.
900 mInputTargetWaitTimeoutExpired = true;
Jeff Brown53a415e2010-09-15 15:18:56 -0700901
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700902 // Release the touch targets.
903 mTouchState.reset();
Jeff Brown405a1d32010-09-16 12:31:46 -0700904
Jeff Brown53a415e2010-09-15 15:18:56 -0700905 // Input state will not be realistic. Mark it out of sync.
Jeff Brown40ad4702010-09-16 11:02:16 -0700906 if (inputChannel.get()) {
907 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
908 if (connectionIndex >= 0) {
909 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700910 synthesizeCancelationEventsForConnectionLocked(
911 connection, InputState::CANCEL_ALL_EVENTS,
912 "application not responding");
Jeff Brown40ad4702010-09-16 11:02:16 -0700913 }
Jeff Brown53a415e2010-09-15 15:18:56 -0700914 }
Jeff Browna665ca82010-09-08 11:49:43 -0700915 }
916}
917
Jeff Brown53a415e2010-09-15 15:18:56 -0700918nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Browna665ca82010-09-08 11:49:43 -0700919 nsecs_t currentTime) {
920 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
921 return currentTime - mInputTargetWaitStartTime;
922 }
923 return 0;
924}
925
926void InputDispatcher::resetANRTimeoutsLocked() {
927#if DEBUG_FOCUS
928 LOGD("Resetting ANR timeouts.");
929#endif
930
Jeff Browna665ca82010-09-08 11:49:43 -0700931 // Reset input target wait timeout.
932 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
933}
934
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700935int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
936 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -0700937 mCurrentInputTargets.clear();
938
939 int32_t injectionResult;
940
941 // If there is no currently focused window and no focused application
942 // then drop the event.
943 if (! mFocusedWindow) {
944 if (mFocusedApplication) {
945#if DEBUG_FOCUS
946 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -0700947 "focused application that may eventually add a window: %s.",
948 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700949#endif
950 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
951 mFocusedApplication, NULL, nextWakeupTime);
952 goto Unresponsive;
953 }
954
955 LOGI("Dropping event because there is no focused window or focused application.");
956 injectionResult = INPUT_EVENT_INJECTION_FAILED;
957 goto Failed;
958 }
959
960 // Check permissions.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700961 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700962 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
963 goto Failed;
964 }
965
966 // If the currently focused window is paused then keep waiting.
967 if (mFocusedWindow->paused) {
968#if DEBUG_FOCUS
969 LOGD("Waiting because focused window is paused.");
970#endif
971 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
972 mFocusedApplication, mFocusedWindow, nextWakeupTime);
973 goto Unresponsive;
974 }
975
Jeff Brown53a415e2010-09-15 15:18:56 -0700976 // If the currently focused window is still working on previous events then keep waiting.
977 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
978#if DEBUG_FOCUS
979 LOGD("Waiting because focused window still processing previous input.");
980#endif
981 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
982 mFocusedApplication, mFocusedWindow, nextWakeupTime);
983 goto Unresponsive;
984 }
985
Jeff Browna665ca82010-09-08 11:49:43 -0700986 // Success! Output targets.
987 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700988 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -0700989
990 // Done.
991Failed:
992Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -0700993 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
994 updateDispatchStatisticsLocked(currentTime, entry,
995 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -0700996#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700997 LOGD("findFocusedWindow finished: injectionResult=%d, "
998 "timeSpendWaitingForApplication=%0.1fms",
999 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001000#endif
1001 return injectionResult;
1002}
1003
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001004int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1005 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -07001006 enum InjectionPermission {
1007 INJECTION_PERMISSION_UNKNOWN,
1008 INJECTION_PERMISSION_GRANTED,
1009 INJECTION_PERMISSION_DENIED
1010 };
1011
Jeff Browna665ca82010-09-08 11:49:43 -07001012 mCurrentInputTargets.clear();
1013
1014 nsecs_t startTime = now();
1015
1016 // For security reasons, we defer updating the touch state until we are sure that
1017 // event injection will be allowed.
1018 //
1019 // FIXME In the original code, screenWasOff could never be set to true.
1020 // The reason is that the POLICY_FLAG_WOKE_HERE
1021 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1022 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1023 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1024 // events upon which no preprocessing took place. So policyFlags was always 0.
1025 // In the new native input dispatcher we're a bit more careful about event
1026 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1027 // Unfortunately we obtain undesirable behavior.
1028 //
1029 // Here's what happens:
1030 //
1031 // When the device dims in anticipation of going to sleep, touches
1032 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1033 // the device to brighten and reset the user activity timer.
1034 // Touches on other windows (such as the launcher window)
1035 // are dropped. Then after a moment, the device goes to sleep. Oops.
1036 //
1037 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1038 // instead of POLICY_FLAG_WOKE_HERE...
1039 //
1040 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1041
1042 int32_t action = entry->action;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001043 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Browna665ca82010-09-08 11:49:43 -07001044
1045 // Update the touch state as needed based on the properties of the touch event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001046 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1047 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1048 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1049 mTempTouchState.reset();
1050 mTempTouchState.down = true;
1051 } else {
1052 mTempTouchState.copyFrom(mTouchState);
1053 }
Jeff Browna665ca82010-09-08 11:49:43 -07001054
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001055 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1056 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1057 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1058 /* Case 1: New splittable pointer going down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001059
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001060 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1061 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1062 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1063 const InputWindow* newTouchedWindow = NULL;
1064 const InputWindow* topErrorWindow = NULL;
Jeff Browna665ca82010-09-08 11:49:43 -07001065
1066 // Traverse windows from front to back to find touched window and outside targets.
1067 size_t numWindows = mWindows.size();
1068 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001069 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07001070 int32_t flags = window->layoutParamsFlags;
1071
1072 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1073 if (! topErrorWindow) {
1074 topErrorWindow = window;
1075 }
1076 }
1077
1078 if (window->visible) {
1079 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1080 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1081 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1082 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1083 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1084 newTouchedWindow = window;
Jeff Browna665ca82010-09-08 11:49:43 -07001085 }
1086 break; // found touched window, exit window loop
1087 }
1088 }
1089
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001090 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1091 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001092 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1093 if (isWindowObscuredAtPointLocked(window, x, y)) {
1094 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1095 }
1096
1097 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -07001098 }
1099 }
1100 }
1101
1102 // If there is an error window but it is not taking focus (typically because
1103 // it is invisible) then wait for it. Any other focused window may in
1104 // fact be in ANR state.
1105 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1106#if DEBUG_FOCUS
1107 LOGD("Waiting because system error window is pending.");
1108#endif
1109 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1110 NULL, NULL, nextWakeupTime);
1111 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1112 goto Unresponsive;
1113 }
1114
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001115 // Figure out whether splitting will be allowed for this window.
Jeff Brown3c2450f2010-09-28 13:24:41 -07001116 if (newTouchedWindow
1117 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001118 // New window supports splitting.
1119 isSplit = true;
1120 } else if (isSplit) {
1121 // New window does not support splitting but we have already split events.
1122 // Assign the pointer to the first foreground window we find.
1123 // (May be NULL which is why we put this code block before the next check.)
1124 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1125 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001126
Jeff Browna665ca82010-09-08 11:49:43 -07001127 // If we did not find a touched window then fail.
1128 if (! newTouchedWindow) {
1129 if (mFocusedApplication) {
1130#if DEBUG_FOCUS
1131 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -07001132 "focused application that may eventually add a new window: %s.",
1133 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -07001134#endif
1135 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1136 mFocusedApplication, NULL, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -07001137 goto Unresponsive;
1138 }
1139
1140 LOGI("Dropping event because there is no touched window or focused application.");
1141 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001142 goto Failed;
1143 }
1144
Jeff Brown35cf0e92010-10-05 12:26:23 -07001145 // Set target flags.
1146 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1147 if (isSplit) {
1148 targetFlags |= InputTarget::FLAG_SPLIT;
1149 }
1150 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1151 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1152 }
1153
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001154 // Update the temporary touch state.
1155 BitSet32 pointerIds;
1156 if (isSplit) {
1157 uint32_t pointerId = entry->pointerIds[pointerIndex];
1158 pointerIds.markBit(pointerId);
Jeff Browna665ca82010-09-08 11:49:43 -07001159 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001160 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001161 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001162 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001163
1164 // If the pointer is not currently down, then ignore the event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001165 if (! mTempTouchState.down) {
Jeff Brown53f291e2010-10-25 17:37:46 -07001166#if DEBUG_INPUT_DISPATCHER_POLICY
1167 LOGD("Dropping event because the pointer is not down or we previously "
1168 "dropped the pointer down event.");
1169#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001170 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001171 goto Failed;
1172 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001173 }
Jeff Browna665ca82010-09-08 11:49:43 -07001174
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001175 // Check permission to inject into all touched foreground windows and ensure there
1176 // is at least one touched foreground window.
1177 {
1178 bool haveForegroundWindow = false;
1179 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1180 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1181 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1182 haveForegroundWindow = true;
1183 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1184 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1185 injectionPermission = INJECTION_PERMISSION_DENIED;
1186 goto Failed;
1187 }
1188 }
1189 }
1190 if (! haveForegroundWindow) {
Jeff Browna665ca82010-09-08 11:49:43 -07001191#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001192 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Browna665ca82010-09-08 11:49:43 -07001193#endif
1194 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001195 goto Failed;
1196 }
1197
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001198 // Permission granted to injection into all touched foreground windows.
1199 injectionPermission = INJECTION_PERMISSION_GRANTED;
1200 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001201
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001202 // Ensure all touched foreground windows are ready for new input.
1203 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1204 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1205 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1206 // If the touched window is paused then keep waiting.
1207 if (touchedWindow.window->paused) {
1208#if DEBUG_INPUT_DISPATCHER_POLICY
1209 LOGD("Waiting because touched window is paused.");
Jeff Brown53a415e2010-09-15 15:18:56 -07001210#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001211 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1212 NULL, touchedWindow.window, nextWakeupTime);
1213 goto Unresponsive;
1214 }
1215
1216 // If the touched window is still working on previous events then keep waiting.
1217 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1218#if DEBUG_FOCUS
1219 LOGD("Waiting because touched window still processing previous input.");
1220#endif
1221 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1222 NULL, touchedWindow.window, nextWakeupTime);
1223 goto Unresponsive;
1224 }
1225 }
1226 }
1227
1228 // If this is the first pointer going down and the touched window has a wallpaper
1229 // then also add the touched wallpaper windows so they are locked in for the duration
1230 // of the touch gesture.
1231 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1232 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1233 if (foregroundWindow->hasWallpaper) {
1234 for (size_t i = 0; i < mWindows.size(); i++) {
1235 const InputWindow* window = & mWindows[i];
1236 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001237 mTempTouchState.addOrUpdateWindow(window,
1238 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001239 }
1240 }
1241 }
1242 }
1243
Jeff Browna665ca82010-09-08 11:49:43 -07001244 // Success! Output targets.
1245 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Browna665ca82010-09-08 11:49:43 -07001246
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001247 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1248 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1249 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1250 touchedWindow.pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001251 }
1252
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001253 // Drop the outside touch window since we will not care about them in the next iteration.
1254 mTempTouchState.removeOutsideTouchWindows();
1255
Jeff Browna665ca82010-09-08 11:49:43 -07001256Failed:
1257 // Check injection permission once and for all.
1258 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001259 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001260 injectionPermission = INJECTION_PERMISSION_GRANTED;
1261 } else {
1262 injectionPermission = INJECTION_PERMISSION_DENIED;
1263 }
1264 }
1265
1266 // Update final pieces of touch state if the injector had permission.
1267 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001268 if (maskedAction == AMOTION_EVENT_ACTION_UP
1269 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1270 // All pointers up or canceled.
1271 mTempTouchState.reset();
1272 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1273 // First pointer went down.
1274 if (mTouchState.down) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001275#if DEBUG_FOCUS
1276 LOGD("Pointer down received while already down.");
1277#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001278 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001279 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1280 // One pointer went up.
1281 if (isSplit) {
1282 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1283 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Browna665ca82010-09-08 11:49:43 -07001284
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001285 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1286 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1287 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1288 touchedWindow.pointerIds.clearBit(pointerId);
1289 if (touchedWindow.pointerIds.isEmpty()) {
1290 mTempTouchState.windows.removeAt(i);
1291 continue;
1292 }
1293 }
1294 i += 1;
1295 }
Jeff Browna665ca82010-09-08 11:49:43 -07001296 }
Jeff Browna665ca82010-09-08 11:49:43 -07001297 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001298
1299 // Save changes to touch state.
1300 mTouchState.copyFrom(mTempTouchState);
Jeff Browna665ca82010-09-08 11:49:43 -07001301 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001302#if DEBUG_FOCUS
1303 LOGD("Not updating touch focus because injection was denied.");
1304#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001305 }
1306
1307Unresponsive:
Jeff Brownfef5b042010-10-27 18:43:51 -07001308 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1309 mTempTouchState.reset();
1310
Jeff Brown53a415e2010-09-15 15:18:56 -07001311 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1312 updateDispatchStatisticsLocked(currentTime, entry,
1313 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001314#if DEBUG_FOCUS
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001315 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1316 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown53a415e2010-09-15 15:18:56 -07001317 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001318#endif
1319 return injectionResult;
1320}
1321
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001322void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1323 BitSet32 pointerIds) {
Jeff Browna665ca82010-09-08 11:49:43 -07001324 mCurrentInputTargets.push();
1325
1326 InputTarget& target = mCurrentInputTargets.editTop();
1327 target.inputChannel = window->inputChannel;
1328 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001329 target.xOffset = - window->frameLeft;
1330 target.yOffset = - window->frameTop;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001331 target.pointerIds = pointerIds;
Jeff Browna665ca82010-09-08 11:49:43 -07001332}
1333
1334void InputDispatcher::addMonitoringTargetsLocked() {
1335 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1336 mCurrentInputTargets.push();
1337
1338 InputTarget& target = mCurrentInputTargets.editTop();
1339 target.inputChannel = mMonitoringChannels[i];
1340 target.flags = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07001341 target.xOffset = 0;
1342 target.yOffset = 0;
1343 }
1344}
1345
1346bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001347 const InjectionState* injectionState) {
1348 if (injectionState
Jeff Brown90f0cee2010-10-08 22:31:17 -07001349 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1350 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1351 if (window) {
1352 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1353 "with input channel %s owned by uid %d",
1354 injectionState->injectorPid, injectionState->injectorUid,
1355 window->inputChannel->getName().string(),
1356 window->ownerUid);
1357 } else {
1358 LOGW("Permission denied: injecting event from pid %d uid %d",
1359 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-09-08 11:49:43 -07001360 }
Jeff Brown90f0cee2010-10-08 22:31:17 -07001361 return false;
Jeff Browna665ca82010-09-08 11:49:43 -07001362 }
1363 return true;
1364}
1365
Jeff Brown35cf0e92010-10-05 12:26:23 -07001366bool InputDispatcher::isWindowObscuredAtPointLocked(
1367 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Browna665ca82010-09-08 11:49:43 -07001368 size_t numWindows = mWindows.size();
1369 for (size_t i = 0; i < numWindows; i++) {
1370 const InputWindow* other = & mWindows.itemAt(i);
1371 if (other == window) {
1372 break;
1373 }
Jeff Brown35cf0e92010-10-05 12:26:23 -07001374 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001375 return true;
1376 }
1377 }
1378 return false;
1379}
1380
Jeff Brown53a415e2010-09-15 15:18:56 -07001381bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1382 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1383 if (connectionIndex >= 0) {
1384 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1385 return connection->outboundQueue.isEmpty();
1386 } else {
1387 return true;
1388 }
1389}
1390
1391String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1392 const InputWindow* window) {
1393 if (application) {
1394 if (window) {
1395 String8 label(application->name);
1396 label.append(" - ");
1397 label.append(window->name);
1398 return label;
1399 } else {
1400 return application->name;
1401 }
1402 } else if (window) {
1403 return window->name;
1404 } else {
1405 return String8("<unknown application or window>");
1406 }
1407}
1408
Jeff Brownef3a8232010-10-18 13:21:23 -07001409void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1410 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brownfd749c62010-10-29 21:50:21 -07001411 switch (eventEntry->type) {
1412 case EventEntry::TYPE_MOTION: {
Jeff Brownef3a8232010-10-18 13:21:23 -07001413 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Brownfd749c62010-10-29 21:50:21 -07001414 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1415 return;
1416 }
1417
Jeff Brownef3a8232010-10-18 13:21:23 -07001418 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1419 switch (motionEntry->action) {
1420 case AMOTION_EVENT_ACTION_DOWN:
1421 eventType = POWER_MANAGER_TOUCH_EVENT;
1422 break;
1423 case AMOTION_EVENT_ACTION_UP:
1424 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
1425 break;
1426 default:
Jeff Brownf6149c32010-11-01 20:35:46 -07001427 if (motionEntry->eventTime - motionEntry->downTime < LONG_TOUCH_DELAY) {
Jeff Brownef3a8232010-10-18 13:21:23 -07001428 eventType = POWER_MANAGER_TOUCH_EVENT;
1429 } else {
1430 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
1431 }
1432 break;
1433 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001434 }
Jeff Brownfd749c62010-10-29 21:50:21 -07001435 break;
1436 }
1437 case EventEntry::TYPE_KEY: {
1438 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1439 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1440 return;
1441 }
1442 break;
1443 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001444 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001445
Jeff Browna665ca82010-09-08 11:49:43 -07001446 CommandEntry* commandEntry = postCommandLocked(
1447 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Brownef3a8232010-10-18 13:21:23 -07001448 commandEntry->eventTime = eventEntry->eventTime;
Jeff Browna665ca82010-09-08 11:49:43 -07001449 commandEntry->userActivityEventType = eventType;
1450}
1451
Jeff Brown51d45a72010-06-17 20:52:56 -07001452void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1453 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -07001454 bool resumeWithAppendedMotionSample) {
1455#if DEBUG_DISPATCH_CYCLE
Jeff Brown53a415e2010-09-15 15:18:56 -07001456 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001457 "xOffset=%f, yOffset=%f, "
1458 "windowType=%d, pointerIds=0x%x, "
1459 "resumeWithAppendedMotionSample=%s",
Jeff Brown53a415e2010-09-15 15:18:56 -07001460 connection->getInputChannelName(), inputTarget->flags,
Jeff Browne839a582010-04-22 18:58:52 -07001461 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001462 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Browna665ca82010-09-08 11:49:43 -07001463 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -07001464#endif
1465
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001466 // Make sure we are never called for streaming when splitting across multiple windows.
1467 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1468 assert(! (resumeWithAppendedMotionSample && isSplit));
1469
Jeff Browne839a582010-04-22 18:58:52 -07001470 // Skip this event if the connection status is not normal.
Jeff Brown53a415e2010-09-15 15:18:56 -07001471 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Browne839a582010-04-22 18:58:52 -07001472 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001473#if DEBUG_DISPATCH_CYCLE
1474 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Browna665ca82010-09-08 11:49:43 -07001475 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown90f0cee2010-10-08 22:31:17 -07001476#endif
Jeff Browne839a582010-04-22 18:58:52 -07001477 return;
1478 }
1479
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001480 // Split a motion event if needed.
1481 if (isSplit) {
1482 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1483
1484 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1485 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1486 MotionEntry* splitMotionEntry = splitMotionEvent(
1487 originalMotionEntry, inputTarget->pointerIds);
1488#if DEBUG_FOCUS
1489 LOGD("channel '%s' ~ Split motion event.",
1490 connection->getInputChannelName());
1491 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1492#endif
1493 eventEntry = splitMotionEntry;
1494 }
1495 }
1496
Jeff Browne839a582010-04-22 18:58:52 -07001497 // Resume the dispatch cycle with a freshly appended motion sample.
1498 // First we check that the last dispatch entry in the outbound queue is for the same
1499 // motion event to which we appended the motion sample. If we find such a dispatch
1500 // entry, and if it is currently in progress then we try to stream the new sample.
1501 bool wasEmpty = connection->outboundQueue.isEmpty();
1502
1503 if (! wasEmpty && resumeWithAppendedMotionSample) {
1504 DispatchEntry* motionEventDispatchEntry =
1505 connection->findQueuedDispatchEntryForEvent(eventEntry);
1506 if (motionEventDispatchEntry) {
1507 // If the dispatch entry is not in progress, then we must be busy dispatching an
1508 // earlier event. Not a problem, the motion event is on the outbound queue and will
1509 // be dispatched later.
1510 if (! motionEventDispatchEntry->inProgress) {
1511#if DEBUG_BATCHING
1512 LOGD("channel '%s' ~ Not streaming because the motion event has "
1513 "not yet been dispatched. "
1514 "(Waiting for earlier events to be consumed.)",
1515 connection->getInputChannelName());
1516#endif
1517 return;
1518 }
1519
1520 // If the dispatch entry is in progress but it already has a tail of pending
1521 // motion samples, then it must mean that the shared memory buffer filled up.
1522 // Not a problem, when this dispatch cycle is finished, we will eventually start
1523 // a new dispatch cycle to process the tail and that tail includes the newly
1524 // appended motion sample.
1525 if (motionEventDispatchEntry->tailMotionSample) {
1526#if DEBUG_BATCHING
1527 LOGD("channel '%s' ~ Not streaming because no new samples can "
1528 "be appended to the motion event in this dispatch cycle. "
1529 "(Waiting for next dispatch cycle to start.)",
1530 connection->getInputChannelName());
1531#endif
1532 return;
1533 }
1534
1535 // The dispatch entry is in progress and is still potentially open for streaming.
1536 // Try to stream the new motion sample. This might fail if the consumer has already
1537 // consumed the motion event (or if the channel is broken).
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001538 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1539 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Browne839a582010-04-22 18:58:52 -07001540 status_t status = connection->inputPublisher.appendMotionSample(
1541 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1542 if (status == OK) {
1543#if DEBUG_BATCHING
1544 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1545 connection->getInputChannelName());
1546#endif
1547 return;
1548 }
1549
1550#if DEBUG_BATCHING
1551 if (status == NO_MEMORY) {
1552 LOGD("channel '%s' ~ Could not append motion sample to currently "
1553 "dispatched move event because the shared memory buffer is full. "
1554 "(Waiting for next dispatch cycle to start.)",
1555 connection->getInputChannelName());
1556 } else if (status == status_t(FAILED_TRANSACTION)) {
1557 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown50de30a2010-06-22 01:27:15 -07001558 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-04-22 18:58:52 -07001559 "(Waiting for next dispatch cycle to start.)",
1560 connection->getInputChannelName());
1561 } else {
1562 LOGD("channel '%s' ~ Could not append motion sample to currently "
1563 "dispatched move event due to an error, status=%d. "
1564 "(Waiting for next dispatch cycle to start.)",
1565 connection->getInputChannelName(), status);
1566 }
1567#endif
1568 // Failed to stream. Start a new tail of pending motion samples to dispatch
1569 // in the next cycle.
1570 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1571 return;
1572 }
1573 }
1574
1575 // This is a new event.
1576 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Browna665ca82010-09-08 11:49:43 -07001577 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown53a415e2010-09-15 15:18:56 -07001578 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1579 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001580 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001581 }
1582
Jeff Browne839a582010-04-22 18:58:52 -07001583 // Handle the case where we could not stream a new motion sample because the consumer has
1584 // already consumed the motion event (otherwise the corresponding dispatch entry would
1585 // still be in the outbound queue for this connection). We set the head motion sample
1586 // to the list starting with the newly appended motion sample.
1587 if (resumeWithAppendedMotionSample) {
1588#if DEBUG_BATCHING
1589 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1590 "that cannot be streamed because the motion event has already been consumed.",
1591 connection->getInputChannelName());
1592#endif
1593 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1594 dispatchEntry->headMotionSample = appendedMotionSample;
1595 }
1596
1597 // Enqueue the dispatch entry.
1598 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1599
1600 // If the outbound queue was previously empty, start the dispatch cycle going.
1601 if (wasEmpty) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001602 activateConnectionLocked(connection.get());
Jeff Brown53a415e2010-09-15 15:18:56 -07001603 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001604 }
1605}
1606
Jeff Brown51d45a72010-06-17 20:52:56 -07001607void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown53a415e2010-09-15 15:18:56 -07001608 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001609#if DEBUG_DISPATCH_CYCLE
1610 LOGD("channel '%s' ~ startDispatchCycle",
1611 connection->getInputChannelName());
1612#endif
1613
1614 assert(connection->status == Connection::STATUS_NORMAL);
1615 assert(! connection->outboundQueue.isEmpty());
1616
Jeff Browna665ca82010-09-08 11:49:43 -07001617 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001618 assert(! dispatchEntry->inProgress);
1619
Jeff Browna665ca82010-09-08 11:49:43 -07001620 // Mark the dispatch entry as in progress.
1621 dispatchEntry->inProgress = true;
1622
1623 // Update the connection's input state.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001624 EventEntry* eventEntry = dispatchEntry->eventEntry;
1625 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001626
1627#if FILTER_INPUT_EVENTS
1628 // Filter out inconsistent sequences of input events.
1629 // The input system may drop or inject events in a way that could violate implicit
1630 // invariants on input state and potentially cause an application to crash
1631 // or think that a key or pointer is stuck down. Technically we make no guarantees
1632 // of consistency but it would be nice to improve on this where possible.
1633 // XXX: This code is a proof of concept only. Not ready for prime time.
1634 if (consistency == InputState::TOLERABLE) {
1635#if DEBUG_DISPATCH_CYCLE
1636 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1637 "current input state but that is likely to be tolerated by the application.",
1638 connection->getInputChannelName());
1639#endif
1640 } else if (consistency == InputState::BROKEN) {
1641 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1642 "current input state and that is likely to cause the application to crash.",
1643 connection->getInputChannelName());
1644 startNextDispatchCycleLocked(currentTime, connection);
1645 return;
1646 }
1647#endif
Jeff Browne839a582010-04-22 18:58:52 -07001648
1649 // Publish the event.
1650 status_t status;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001651 switch (eventEntry->type) {
Jeff Browne839a582010-04-22 18:58:52 -07001652 case EventEntry::TYPE_KEY: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001653 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001654
1655 // Apply target flags.
1656 int32_t action = keyEntry->action;
1657 int32_t flags = keyEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001658
1659 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001660 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-04-22 18:58:52 -07001661 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1662 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1663 keyEntry->eventTime);
1664
1665 if (status) {
1666 LOGE("channel '%s' ~ Could not publish key event, "
1667 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001668 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001669 return;
1670 }
1671 break;
1672 }
1673
1674 case EventEntry::TYPE_MOTION: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001675 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001676
1677 // Apply target flags.
1678 int32_t action = motionEntry->action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07001679 int32_t flags = motionEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001680 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001681 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -07001682 }
Jeff Brownaf30ff62010-09-01 17:01:00 -07001683 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1684 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1685 }
Jeff Browne839a582010-04-22 18:58:52 -07001686
1687 // If headMotionSample is non-NULL, then it points to the first new sample that we
1688 // were unable to dispatch during the previous cycle so we resume dispatching from
1689 // that point in the list of motion samples.
1690 // Otherwise, we just start from the first sample of the motion event.
1691 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1692 if (! firstMotionSample) {
1693 firstMotionSample = & motionEntry->firstSample;
1694 }
1695
Jeff Brownf26db0d2010-07-16 17:21:06 -07001696 // Set the X and Y offset depending on the input source.
1697 float xOffset, yOffset;
1698 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1699 xOffset = dispatchEntry->xOffset;
1700 yOffset = dispatchEntry->yOffset;
1701 } else {
1702 xOffset = 0.0f;
1703 yOffset = 0.0f;
1704 }
1705
Jeff Browne839a582010-04-22 18:58:52 -07001706 // Publish the motion event and the first motion sample.
1707 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001708 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -07001709 xOffset, yOffset,
Jeff Browne839a582010-04-22 18:58:52 -07001710 motionEntry->xPrecision, motionEntry->yPrecision,
1711 motionEntry->downTime, firstMotionSample->eventTime,
1712 motionEntry->pointerCount, motionEntry->pointerIds,
1713 firstMotionSample->pointerCoords);
1714
1715 if (status) {
1716 LOGE("channel '%s' ~ Could not publish motion event, "
1717 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001718 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001719 return;
1720 }
1721
1722 // Append additional motion samples.
1723 MotionSample* nextMotionSample = firstMotionSample->next;
1724 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1725 status = connection->inputPublisher.appendMotionSample(
1726 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1727 if (status == NO_MEMORY) {
1728#if DEBUG_DISPATCH_CYCLE
1729 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1730 "be sent in the next dispatch cycle.",
1731 connection->getInputChannelName());
1732#endif
1733 break;
1734 }
1735 if (status != OK) {
1736 LOGE("channel '%s' ~ Could not append motion sample "
1737 "for a reason other than out of memory, status=%d",
1738 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001739 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001740 return;
1741 }
1742 }
1743
1744 // Remember the next motion sample that we could not dispatch, in case we ran out
1745 // of space in the shared memory buffer.
1746 dispatchEntry->tailMotionSample = nextMotionSample;
1747 break;
1748 }
1749
1750 default: {
1751 assert(false);
1752 }
1753 }
1754
1755 // Send the dispatch signal.
1756 status = connection->inputPublisher.sendDispatchSignal();
1757 if (status) {
1758 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1759 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001760 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001761 return;
1762 }
1763
1764 // Record information about the newly started dispatch cycle.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001765 connection->lastEventTime = eventEntry->eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07001766 connection->lastDispatchTime = currentTime;
1767
Jeff Browne839a582010-04-22 18:58:52 -07001768 // Notify other system components.
1769 onDispatchCycleStartedLocked(currentTime, connection);
1770}
1771
Jeff Brown51d45a72010-06-17 20:52:56 -07001772void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1773 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001774#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001775 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -07001776 "%01.1fms since dispatch",
1777 connection->getInputChannelName(),
1778 connection->getEventLatencyMillis(currentTime),
1779 connection->getDispatchLatencyMillis(currentTime));
1780#endif
1781
Jeff Brown54bc2812010-06-15 01:31:58 -07001782 if (connection->status == Connection::STATUS_BROKEN
1783 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001784 return;
1785 }
1786
Jeff Brown53a415e2010-09-15 15:18:56 -07001787 // Notify other system components.
1788 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001789
1790 // Reset the publisher since the event has been consumed.
1791 // We do this now so that the publisher can release some of its internal resources
1792 // while waiting for the next dispatch cycle to begin.
1793 status_t status = connection->inputPublisher.reset();
1794 if (status) {
1795 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1796 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001797 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001798 return;
1799 }
1800
Jeff Browna665ca82010-09-08 11:49:43 -07001801 startNextDispatchCycleLocked(currentTime, connection);
1802}
1803
1804void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1805 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001806 // Start the next dispatch cycle for this connection.
1807 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001808 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001809 if (dispatchEntry->inProgress) {
1810 // Finish or resume current event in progress.
1811 if (dispatchEntry->tailMotionSample) {
1812 // We have a tail of undispatched motion samples.
1813 // Reuse the same DispatchEntry and start a new cycle.
1814 dispatchEntry->inProgress = false;
1815 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1816 dispatchEntry->tailMotionSample = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07001817 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001818 return;
1819 }
1820 // Finished.
1821 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001822 if (dispatchEntry->hasForegroundTarget()) {
1823 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001824 }
Jeff Browne839a582010-04-22 18:58:52 -07001825 mAllocator.releaseDispatchEntry(dispatchEntry);
1826 } else {
1827 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown53a415e2010-09-15 15:18:56 -07001828 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001829 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001830 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001831 return;
1832 }
1833 }
1834
1835 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001836 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001837}
1838
Jeff Brown90f0cee2010-10-08 22:31:17 -07001839void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1840 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001841#if DEBUG_DISPATCH_CYCLE
Jeff Brown90f0cee2010-10-08 22:31:17 -07001842 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001843 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001844#endif
1845
Jeff Browna665ca82010-09-08 11:49:43 -07001846 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001847 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001848
Jeff Brown90f0cee2010-10-08 22:31:17 -07001849 // The connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001850 // Ignore already broken or zombie connections.
Jeff Brown90f0cee2010-10-08 22:31:17 -07001851 if (connection->status == Connection::STATUS_NORMAL) {
1852 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001853
Jeff Brown90f0cee2010-10-08 22:31:17 -07001854 // Notify other system components.
1855 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001856 }
Jeff Browne839a582010-04-22 18:58:52 -07001857}
1858
Jeff Brown53a415e2010-09-15 15:18:56 -07001859void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1860 while (! connection->outboundQueue.isEmpty()) {
1861 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1862 if (dispatchEntry->hasForegroundTarget()) {
1863 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001864 }
1865 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001866 }
1867
Jeff Brown53a415e2010-09-15 15:18:56 -07001868 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001869}
1870
Jeff Brown59abe7e2010-09-13 23:17:30 -07001871int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-04-22 18:58:52 -07001872 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1873
1874 { // acquire lock
1875 AutoMutex _l(d->mLock);
1876
1877 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1878 if (connectionIndex < 0) {
1879 LOGE("Received spurious receive callback for unknown input channel. "
1880 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001881 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001882 }
1883
Jeff Brown51d45a72010-06-17 20:52:56 -07001884 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001885
1886 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001887 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-04-22 18:58:52 -07001888 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1889 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001890 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001891 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001892 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001893 }
1894
Jeff Brown59abe7e2010-09-13 23:17:30 -07001895 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001896 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1897 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001898 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001899 }
1900
1901 status_t status = connection->inputPublisher.receiveFinishedSignal();
1902 if (status) {
1903 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1904 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001905 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001906 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001907 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001908 }
1909
Jeff Brown51d45a72010-06-17 20:52:56 -07001910 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001911 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001912 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001913 } // release lock
1914}
1915
Jeff Brown90f0cee2010-10-08 22:31:17 -07001916void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1917 InputState::CancelationOptions options, const char* reason) {
1918 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1919 synthesizeCancelationEventsForConnectionLocked(
1920 mConnectionsByReceiveFd.valueAt(i), options, reason);
1921 }
1922}
1923
1924void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1925 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1926 const char* reason) {
1927 ssize_t index = getConnectionIndexLocked(channel);
1928 if (index >= 0) {
1929 synthesizeCancelationEventsForConnectionLocked(
1930 mConnectionsByReceiveFd.valueAt(index), options, reason);
1931 }
1932}
1933
1934void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1935 const sp<Connection>& connection, InputState::CancelationOptions options,
1936 const char* reason) {
1937 nsecs_t currentTime = now();
1938
1939 mTempCancelationEvents.clear();
1940 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1941 mTempCancelationEvents, options);
1942
1943 if (! mTempCancelationEvents.isEmpty()
1944 && connection->status != Connection::STATUS_BROKEN) {
1945#if DEBUG_OUTBOUND_EVENT_DETAILS
1946 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1947 "with reality: %s, options=%d.",
1948 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1949#endif
1950 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1951 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1952 switch (cancelationEventEntry->type) {
1953 case EventEntry::TYPE_KEY:
1954 logOutboundKeyDetailsLocked("cancel - ",
1955 static_cast<KeyEntry*>(cancelationEventEntry));
1956 break;
1957 case EventEntry::TYPE_MOTION:
1958 logOutboundMotionDetailsLocked("cancel - ",
1959 static_cast<MotionEntry*>(cancelationEventEntry));
1960 break;
1961 }
1962
1963 int32_t xOffset, yOffset;
1964 const InputWindow* window = getWindowLocked(connection->inputChannel);
1965 if (window) {
1966 xOffset = -window->frameLeft;
1967 yOffset = -window->frameTop;
1968 } else {
1969 xOffset = 0;
1970 yOffset = 0;
1971 }
1972
1973 DispatchEntry* cancelationDispatchEntry =
1974 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1975 0, xOffset, yOffset);
1976 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1977
1978 mAllocator.releaseEventEntry(cancelationEventEntry);
1979 }
1980
1981 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1982 startDispatchCycleLocked(currentTime, connection);
1983 }
1984 }
1985}
1986
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001987InputDispatcher::MotionEntry*
1988InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1989 assert(pointerIds.value != 0);
1990
1991 uint32_t splitPointerIndexMap[MAX_POINTERS];
1992 int32_t splitPointerIds[MAX_POINTERS];
1993 PointerCoords splitPointerCoords[MAX_POINTERS];
1994
1995 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1996 uint32_t splitPointerCount = 0;
1997
1998 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1999 originalPointerIndex++) {
2000 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
2001 if (pointerIds.hasBit(pointerId)) {
2002 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2003 splitPointerIds[splitPointerCount] = pointerId;
2004 splitPointerCoords[splitPointerCount] =
2005 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
2006 splitPointerCount += 1;
2007 }
2008 }
2009 assert(splitPointerCount == pointerIds.count());
2010
2011 int32_t action = originalMotionEntry->action;
2012 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2013 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2014 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2015 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2016 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2017 if (pointerIds.hasBit(pointerId)) {
2018 if (pointerIds.count() == 1) {
2019 // The first/last pointer went down/up.
2020 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2021 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brownffb16d62010-09-27 16:35:11 -07002022 } else {
2023 // A secondary pointer went down/up.
2024 uint32_t splitPointerIndex = 0;
2025 while (pointerId != splitPointerIds[splitPointerIndex]) {
2026 splitPointerIndex += 1;
2027 }
2028 action = maskedAction | (splitPointerIndex
2029 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002030 }
2031 } else {
2032 // An unrelated pointer changed.
2033 action = AMOTION_EVENT_ACTION_MOVE;
2034 }
2035 }
2036
2037 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2038 originalMotionEntry->eventTime,
2039 originalMotionEntry->deviceId,
2040 originalMotionEntry->source,
2041 originalMotionEntry->policyFlags,
2042 action,
2043 originalMotionEntry->flags,
2044 originalMotionEntry->metaState,
2045 originalMotionEntry->edgeFlags,
2046 originalMotionEntry->xPrecision,
2047 originalMotionEntry->yPrecision,
2048 originalMotionEntry->downTime,
2049 splitPointerCount, splitPointerIds, splitPointerCoords);
2050
2051 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2052 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2053 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2054 splitPointerIndex++) {
2055 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2056 splitPointerCoords[splitPointerIndex] =
2057 originalMotionSample->pointerCoords[originalPointerIndex];
2058 }
2059
2060 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2061 splitPointerCoords);
2062 }
2063
2064 return splitMotionEntry;
2065}
2066
Jeff Brown54bc2812010-06-15 01:31:58 -07002067void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002068#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -07002069 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07002070#endif
2071
Jeff Browna665ca82010-09-08 11:49:43 -07002072 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002073 { // acquire lock
2074 AutoMutex _l(mLock);
2075
Jeff Brown51d45a72010-06-17 20:52:56 -07002076 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browna665ca82010-09-08 11:49:43 -07002077 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002078 } // release lock
2079
Jeff Browna665ca82010-09-08 11:49:43 -07002080 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002081 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002082 }
2083}
2084
Jeff Brown5c1ed842010-07-14 18:48:53 -07002085void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -07002086 uint32_t policyFlags, int32_t action, int32_t flags,
2087 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2088#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002089 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07002090 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07002091 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -07002092 keyCode, scanCode, metaState, downTime);
2093#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002094 if (! validateKeyEvent(action)) {
2095 return;
2096 }
Jeff Browne839a582010-04-22 18:58:52 -07002097
Jeff Brown33d54ce2010-10-11 14:20:19 -07002098 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002099 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2100 keyCode, scanCode, /*byref*/ policyFlags);
2101
Jeff Browna665ca82010-09-08 11:49:43 -07002102 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002103 { // acquire lock
2104 AutoMutex _l(mLock);
2105
Jeff Brown51d45a72010-06-17 20:52:56 -07002106 int32_t repeatCount = 0;
2107 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002108 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07002109 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07002110
Jeff Browna665ca82010-09-08 11:49:43 -07002111 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002112 } // release lock
2113
Jeff Browna665ca82010-09-08 11:49:43 -07002114 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002115 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002116 }
2117}
2118
Jeff Brown5c1ed842010-07-14 18:48:53 -07002119void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002120 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002121 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2122 float xPrecision, float yPrecision, nsecs_t downTime) {
2123#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002124 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002125 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2126 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2127 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002128 xPrecision, yPrecision, downTime);
2129 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07002130 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002131 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07002132 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07002133 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-08-30 03:02:23 -07002134 pointerCoords[i].pressure, pointerCoords[i].size,
2135 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2136 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2137 pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -07002138 }
2139#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002140 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2141 return;
2142 }
Jeff Browne839a582010-04-22 18:58:52 -07002143
Jeff Brown33d54ce2010-10-11 14:20:19 -07002144 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002145 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2146
Jeff Browna665ca82010-09-08 11:49:43 -07002147 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002148 { // acquire lock
2149 AutoMutex _l(mLock);
2150
2151 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07002152 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07002153 // BATCHING CASE
2154 //
2155 // Try to append a move sample to the tail of the inbound queue for this device.
2156 // Give up if we encounter a non-move motion event for this device since that
2157 // means we cannot append any new samples until a new motion event has started.
Jeff Browna665ca82010-09-08 11:49:43 -07002158 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2159 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07002160 if (entry->type != EventEntry::TYPE_MOTION) {
2161 // Keep looking for motion events.
2162 continue;
2163 }
2164
2165 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2166 if (motionEntry->deviceId != deviceId) {
2167 // Keep looking for this device.
2168 continue;
2169 }
2170
Jeff Brown5c1ed842010-07-14 18:48:53 -07002171 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07002172 || motionEntry->pointerCount != pointerCount
2173 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07002174 // Last motion event in the queue for this device is not compatible for
2175 // appending new samples. Stop here.
2176 goto NoBatchingOrStreaming;
2177 }
2178
2179 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07002180 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07002181 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002182#if DEBUG_BATCHING
2183 LOGD("Appended motion sample onto batch for most recent "
2184 "motion event for this device in the inbound queue.");
2185#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07002186 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002187 }
2188
2189 // STREAMING CASE
2190 //
2191 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07002192 // Search the outbound queue for the current foreground targets to find a dispatched
2193 // motion event that is still in progress. If found, then, appen the new sample to
2194 // that event and push it out to all current targets. The logic in
2195 // prepareDispatchCycleLocked takes care of the case where some targets may
2196 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown54bc2812010-06-15 01:31:58 -07002197 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002198 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2199 const InputTarget& inputTarget = mCurrentInputTargets[i];
2200 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2201 // Skip non-foreground targets. We only want to stream if there is at
2202 // least one foreground target whose dispatch is still in progress.
2203 continue;
Jeff Browne839a582010-04-22 18:58:52 -07002204 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002205
2206 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2207 if (connectionIndex < 0) {
2208 // Connection must no longer be valid.
2209 continue;
2210 }
2211
2212 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2213 if (connection->outboundQueue.isEmpty()) {
2214 // This foreground target has an empty outbound queue.
2215 continue;
2216 }
2217
2218 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2219 if (! dispatchEntry->inProgress
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002220 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2221 || dispatchEntry->isSplit()) {
2222 // No motion event is being dispatched, or it is being split across
2223 // windows in which case we cannot stream.
Jeff Brown53a415e2010-09-15 15:18:56 -07002224 continue;
2225 }
2226
2227 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2228 dispatchEntry->eventEntry);
2229 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2230 || motionEntry->deviceId != deviceId
2231 || motionEntry->pointerCount != pointerCount
2232 || motionEntry->isInjected()) {
2233 // The motion event is not compatible with this move.
2234 continue;
2235 }
2236
2237 // Hurray! This foreground target is currently dispatching a move event
2238 // that we can stream onto. Append the motion sample and resume dispatch.
2239 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2240#if DEBUG_BATCHING
2241 LOGD("Appended motion sample onto batch for most recently dispatched "
2242 "motion event for this device in the outbound queues. "
2243 "Attempting to stream the motion sample.");
2244#endif
2245 nsecs_t currentTime = now();
2246 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2247 true /*resumeWithAppendedMotionSample*/);
2248
2249 runCommandsLockedInterruptible();
2250 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002251 }
2252 }
2253
2254NoBatchingOrStreaming:;
2255 }
2256
2257 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07002258 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002259 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002260 xPrecision, yPrecision, downTime,
2261 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002262
Jeff Browna665ca82010-09-08 11:49:43 -07002263 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002264 } // release lock
2265
Jeff Browna665ca82010-09-08 11:49:43 -07002266 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002267 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002268 }
2269}
2270
Jeff Brown90f0cee2010-10-08 22:31:17 -07002271void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2272 uint32_t policyFlags) {
2273#if DEBUG_INBOUND_EVENT_DETAILS
2274 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2275 switchCode, switchValue, policyFlags);
2276#endif
2277
Jeff Brown33d54ce2010-10-11 14:20:19 -07002278 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002279 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2280}
2281
Jeff Brown51d45a72010-06-17 20:52:56 -07002282int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07002283 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002284#if DEBUG_INBOUND_EVENT_DETAILS
2285 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002286 "syncMode=%d, timeoutMillis=%d",
2287 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07002288#endif
2289
2290 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brown33d54ce2010-10-11 14:20:19 -07002291
2292 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2293 if (hasInjectionPermission(injectorPid, injectorUid)) {
2294 policyFlags |= POLICY_FLAG_TRUSTED;
2295 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002296
Jeff Brown90f0cee2010-10-08 22:31:17 -07002297 EventEntry* injectedEntry;
2298 switch (event->getType()) {
2299 case AINPUT_EVENT_TYPE_KEY: {
2300 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2301 int32_t action = keyEvent->getAction();
2302 if (! validateKeyEvent(action)) {
Jeff Browna665ca82010-09-08 11:49:43 -07002303 return INPUT_EVENT_INJECTION_FAILED;
2304 }
2305
Jeff Brown90f0cee2010-10-08 22:31:17 -07002306 nsecs_t eventTime = keyEvent->getEventTime();
2307 int32_t deviceId = keyEvent->getDeviceId();
2308 int32_t flags = keyEvent->getFlags();
2309 int32_t keyCode = keyEvent->getKeyCode();
2310 int32_t scanCode = keyEvent->getScanCode();
Jeff Brown33d54ce2010-10-11 14:20:19 -07002311 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2312 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002313
Jeff Brown90f0cee2010-10-08 22:31:17 -07002314 mLock.lock();
2315 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2316 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2317 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2318 break;
2319 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002320
Jeff Brown90f0cee2010-10-08 22:31:17 -07002321 case AINPUT_EVENT_TYPE_MOTION: {
2322 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2323 int32_t action = motionEvent->getAction();
2324 size_t pointerCount = motionEvent->getPointerCount();
2325 const int32_t* pointerIds = motionEvent->getPointerIds();
2326 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2327 return INPUT_EVENT_INJECTION_FAILED;
2328 }
2329
2330 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown33d54ce2010-10-11 14:20:19 -07002331 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002332
2333 mLock.lock();
2334 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2335 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2336 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2337 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2338 action, motionEvent->getFlags(),
2339 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2340 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2341 motionEvent->getDownTime(), uint32_t(pointerCount),
2342 pointerIds, samplePointerCoords);
2343 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2344 sampleEventTimes += 1;
2345 samplePointerCoords += pointerCount;
2346 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2347 }
2348 injectedEntry = motionEntry;
2349 break;
2350 }
2351
2352 default:
2353 LOGW("Cannot inject event of type %d", event->getType());
2354 return INPUT_EVENT_INJECTION_FAILED;
2355 }
2356
2357 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2358 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2359 injectionState->injectionIsAsync = true;
2360 }
2361
2362 injectionState->refCount += 1;
2363 injectedEntry->injectionState = injectionState;
2364
2365 bool needWake = enqueueInboundEventLocked(injectedEntry);
2366 mLock.unlock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002367
Jeff Browna665ca82010-09-08 11:49:43 -07002368 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002369 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07002370 }
2371
2372 int32_t injectionResult;
2373 { // acquire lock
2374 AutoMutex _l(mLock);
2375
Jeff Brownf67c53e2010-07-28 15:48:59 -07002376 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2377 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2378 } else {
2379 for (;;) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002380 injectionResult = injectionState->injectionResult;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002381 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2382 break;
2383 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002384
Jeff Brown51d45a72010-06-17 20:52:56 -07002385 nsecs_t remainingTimeout = endTime - now();
2386 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002387#if DEBUG_INJECTION
2388 LOGD("injectInputEvent - Timed out waiting for injection result "
2389 "to become available.");
2390#endif
Jeff Brown51d45a72010-06-17 20:52:56 -07002391 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2392 break;
2393 }
2394
Jeff Brownf67c53e2010-07-28 15:48:59 -07002395 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2396 }
2397
2398 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2399 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002400 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002401#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002402 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002403 injectionState->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002404#endif
2405 nsecs_t remainingTimeout = endTime - now();
2406 if (remainingTimeout <= 0) {
2407#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002408 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002409 "dispatches to finish.");
2410#endif
2411 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2412 break;
2413 }
2414
2415 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2416 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002417 }
2418 }
2419
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002420 mAllocator.releaseInjectionState(injectionState);
Jeff Brown51d45a72010-06-17 20:52:56 -07002421 } // release lock
2422
Jeff Brownf67c53e2010-07-28 15:48:59 -07002423#if DEBUG_INJECTION
2424 LOGD("injectInputEvent - Finished with result %d. "
2425 "injectorPid=%d, injectorUid=%d",
2426 injectionResult, injectorPid, injectorUid);
2427#endif
2428
Jeff Brown51d45a72010-06-17 20:52:56 -07002429 return injectionResult;
2430}
2431
Jeff Brown90f0cee2010-10-08 22:31:17 -07002432bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2433 return injectorUid == 0
2434 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2435}
2436
Jeff Brown51d45a72010-06-17 20:52:56 -07002437void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002438 InjectionState* injectionState = entry->injectionState;
2439 if (injectionState) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002440#if DEBUG_INJECTION
2441 LOGD("Setting input event injection result to %d. "
2442 "injectorPid=%d, injectorUid=%d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002443 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002444#endif
2445
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002446 if (injectionState->injectionIsAsync) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002447 // Log the outcome since the injector did not wait for the injection result.
2448 switch (injectionResult) {
2449 case INPUT_EVENT_INJECTION_SUCCEEDED:
2450 LOGV("Asynchronous input event injection succeeded.");
2451 break;
2452 case INPUT_EVENT_INJECTION_FAILED:
2453 LOGW("Asynchronous input event injection failed.");
2454 break;
2455 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2456 LOGW("Asynchronous input event injection permission denied.");
2457 break;
2458 case INPUT_EVENT_INJECTION_TIMED_OUT:
2459 LOGW("Asynchronous input event injection timed out.");
2460 break;
2461 }
2462 }
2463
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002464 injectionState->injectionResult = injectionResult;
Jeff Brown51d45a72010-06-17 20:52:56 -07002465 mInjectionResultAvailableCondition.broadcast();
2466 }
2467}
2468
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002469void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2470 InjectionState* injectionState = entry->injectionState;
2471 if (injectionState) {
2472 injectionState->pendingForegroundDispatches += 1;
2473 }
2474}
2475
Jeff Brown53a415e2010-09-15 15:18:56 -07002476void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002477 InjectionState* injectionState = entry->injectionState;
2478 if (injectionState) {
2479 injectionState->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002480
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002481 if (injectionState->pendingForegroundDispatches == 0) {
2482 mInjectionSyncFinishedCondition.broadcast();
2483 }
Jeff Browna665ca82010-09-08 11:49:43 -07002484 }
2485}
2486
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002487const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2488 for (size_t i = 0; i < mWindows.size(); i++) {
2489 const InputWindow* window = & mWindows[i];
2490 if (window->inputChannel == inputChannel) {
2491 return window;
2492 }
2493 }
2494 return NULL;
2495}
2496
Jeff Browna665ca82010-09-08 11:49:43 -07002497void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2498#if DEBUG_FOCUS
2499 LOGD("setInputWindows");
2500#endif
2501 { // acquire lock
2502 AutoMutex _l(mLock);
2503
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002504 // Clear old window pointers.
Jeff Brown90f0cee2010-10-08 22:31:17 -07002505 sp<InputChannel> oldFocusedWindowChannel;
2506 if (mFocusedWindow) {
2507 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2508 mFocusedWindow = NULL;
2509 }
2510
Jeff Browna665ca82010-09-08 11:49:43 -07002511 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002512
2513 // Loop over new windows and rebuild the necessary window pointers for
2514 // tracking focus and touch.
Jeff Browna665ca82010-09-08 11:49:43 -07002515 mWindows.appendVector(inputWindows);
2516
2517 size_t numWindows = mWindows.size();
2518 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002519 const InputWindow* window = & mWindows.itemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07002520 if (window->hasFocus) {
2521 mFocusedWindow = window;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002522 break;
Jeff Browna665ca82010-09-08 11:49:43 -07002523 }
2524 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002525
Jeff Brown90f0cee2010-10-08 22:31:17 -07002526 if (oldFocusedWindowChannel != NULL) {
2527 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2528#if DEBUG_FOCUS
2529 LOGD("Focus left window: %s",
2530 oldFocusedWindowChannel->getName().string());
2531#endif
2532 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2533 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2534 oldFocusedWindowChannel.clear();
2535 }
2536 }
2537 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2538#if DEBUG_FOCUS
2539 LOGD("Focus entered window: %s",
2540 mFocusedWindow->inputChannel->getName().string());
2541#endif
2542 }
2543
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002544 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2545 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2546 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2547 if (window) {
2548 touchedWindow.window = window;
2549 i += 1;
2550 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -07002551#if DEBUG_FOCUS
2552 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2553#endif
Jeff Brown90f0cee2010-10-08 22:31:17 -07002554 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2555 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownb13d7b52010-10-15 16:20:51 -07002556 mTouchState.windows.removeAt(i);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002557 }
2558 }
Jeff Browna665ca82010-09-08 11:49:43 -07002559
Jeff Browna665ca82010-09-08 11:49:43 -07002560#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002561 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002562#endif
2563 } // release lock
2564
2565 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002566 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002567}
2568
2569void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2570#if DEBUG_FOCUS
2571 LOGD("setFocusedApplication");
2572#endif
2573 { // acquire lock
2574 AutoMutex _l(mLock);
2575
2576 releaseFocusedApplicationLocked();
2577
2578 if (inputApplication) {
2579 mFocusedApplicationStorage = *inputApplication;
2580 mFocusedApplication = & mFocusedApplicationStorage;
2581 }
2582
2583#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002584 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002585#endif
2586 } // release lock
2587
2588 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002589 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002590}
2591
2592void InputDispatcher::releaseFocusedApplicationLocked() {
2593 if (mFocusedApplication) {
2594 mFocusedApplication = NULL;
2595 mFocusedApplicationStorage.handle.clear();
2596 }
2597}
2598
2599void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2600#if DEBUG_FOCUS
2601 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2602#endif
2603
2604 bool changed;
2605 { // acquire lock
2606 AutoMutex _l(mLock);
2607
2608 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brownfef5b042010-10-27 18:43:51 -07002609 if (mDispatchFrozen && !frozen) {
Jeff Browna665ca82010-09-08 11:49:43 -07002610 resetANRTimeoutsLocked();
2611 }
2612
Jeff Brownfef5b042010-10-27 18:43:51 -07002613 if (mDispatchEnabled && !enabled) {
2614 resetAndDropEverythingLocked("dispatcher is being disabled");
2615 }
2616
Jeff Browna665ca82010-09-08 11:49:43 -07002617 mDispatchEnabled = enabled;
2618 mDispatchFrozen = frozen;
2619 changed = true;
2620 } else {
2621 changed = false;
2622 }
2623
2624#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002625 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002626#endif
2627 } // release lock
2628
2629 if (changed) {
2630 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002631 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002632 }
2633}
2634
Jeff Brown744c5592010-09-27 14:52:15 -07002635bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2636 const sp<InputChannel>& toChannel) {
2637#if DEBUG_FOCUS
2638 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2639 fromChannel->getName().string(), toChannel->getName().string());
2640#endif
2641 { // acquire lock
2642 AutoMutex _l(mLock);
2643
2644 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2645 const InputWindow* toWindow = getWindowLocked(toChannel);
2646 if (! fromWindow || ! toWindow) {
2647#if DEBUG_FOCUS
2648 LOGD("Cannot transfer focus because from or to window not found.");
2649#endif
2650 return false;
2651 }
2652 if (fromWindow == toWindow) {
2653#if DEBUG_FOCUS
2654 LOGD("Trivial transfer to same window.");
2655#endif
2656 return true;
2657 }
2658
2659 bool found = false;
2660 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2661 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2662 if (touchedWindow.window == fromWindow) {
2663 int32_t oldTargetFlags = touchedWindow.targetFlags;
2664 BitSet32 pointerIds = touchedWindow.pointerIds;
2665
2666 mTouchState.windows.removeAt(i);
2667
2668 int32_t newTargetFlags = 0;
2669 if (oldTargetFlags & InputTarget::FLAG_FOREGROUND) {
2670 newTargetFlags |= InputTarget::FLAG_FOREGROUND;
2671 if (toWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) {
2672 newTargetFlags |= InputTarget::FLAG_SPLIT;
2673 }
2674 }
2675 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2676
2677 found = true;
2678 break;
2679 }
2680 }
2681
2682 if (! found) {
2683#if DEBUG_FOCUS
2684 LOGD("Focus transfer failed because from window did not have focus.");
2685#endif
2686 return false;
2687 }
2688
Jeff Brownb6702e52010-10-11 18:32:20 -07002689 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2690 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2691 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2692 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2693 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2694
2695 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2696 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2697 InputState::CANCEL_POINTER_EVENTS,
2698 "transferring touch focus from this window to another window");
2699 }
2700
Jeff Brown744c5592010-09-27 14:52:15 -07002701#if DEBUG_FOCUS
2702 logDispatchStateLocked();
2703#endif
2704 } // release lock
2705
2706 // Wake up poll loop since it may need to make new input dispatching choices.
2707 mLooper->wake();
2708 return true;
2709}
2710
Jeff Brownfef5b042010-10-27 18:43:51 -07002711void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2712#if DEBUG_FOCUS
2713 LOGD("Resetting and dropping all events (%s).", reason);
2714#endif
2715
2716 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2717
2718 resetKeyRepeatLocked();
2719 releasePendingEventLocked();
2720 drainInboundQueueLocked();
2721 resetTargetsLocked();
2722
2723 mTouchState.reset();
2724}
2725
Jeff Browna665ca82010-09-08 11:49:43 -07002726void InputDispatcher::logDispatchStateLocked() {
2727 String8 dump;
2728 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002729
2730 char* text = dump.lockBuffer(dump.size());
2731 char* start = text;
2732 while (*start != '\0') {
2733 char* end = strchr(start, '\n');
2734 if (*end == '\n') {
2735 *(end++) = '\0';
2736 }
2737 LOGD("%s", start);
2738 start = end;
2739 }
Jeff Browna665ca82010-09-08 11:49:43 -07002740}
2741
2742void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002743 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2744 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002745
2746 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002747 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002748 mFocusedApplication->name.string(),
2749 mFocusedApplication->dispatchingTimeout / 1000000.0);
2750 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002751 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002752 }
Jeff Brown2806e382010-10-01 17:46:21 -07002753 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002754 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-10-01 17:46:21 -07002755
2756 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2757 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2758 if (!mTouchState.windows.isEmpty()) {
2759 dump.append(INDENT "TouchedWindows:\n");
2760 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2761 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2762 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2763 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2764 touchedWindow.targetFlags);
2765 }
2766 } else {
2767 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002768 }
2769
Jeff Brown2806e382010-10-01 17:46:21 -07002770 if (!mWindows.isEmpty()) {
2771 dump.append(INDENT "Windows:\n");
2772 for (size_t i = 0; i < mWindows.size(); i++) {
2773 const InputWindow& window = mWindows[i];
2774 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2775 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2776 "frame=[%d,%d][%d,%d], "
2777 "visibleFrame=[%d,%d][%d,%d], "
2778 "touchableArea=[%d,%d][%d,%d], "
2779 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2780 i, window.name.string(),
2781 toString(window.paused),
2782 toString(window.hasFocus),
2783 toString(window.hasWallpaper),
2784 toString(window.visible),
2785 toString(window.canReceiveKeys),
2786 window.layoutParamsFlags, window.layoutParamsType,
2787 window.layer,
2788 window.frameLeft, window.frameTop,
2789 window.frameRight, window.frameBottom,
2790 window.visibleFrameLeft, window.visibleFrameTop,
2791 window.visibleFrameRight, window.visibleFrameBottom,
2792 window.touchableAreaLeft, window.touchableAreaTop,
2793 window.touchableAreaRight, window.touchableAreaBottom,
2794 window.ownerPid, window.ownerUid,
2795 window.dispatchingTimeout / 1000000.0);
2796 }
2797 } else {
2798 dump.append(INDENT "Windows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002799 }
2800
Jeff Brown2806e382010-10-01 17:46:21 -07002801 if (!mMonitoringChannels.isEmpty()) {
2802 dump.append(INDENT "MonitoringChannels:\n");
2803 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2804 const sp<InputChannel>& channel = mMonitoringChannels[i];
2805 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2806 }
2807 } else {
2808 dump.append(INDENT "MonitoringChannels: <none>\n");
2809 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002810
Jeff Brown2806e382010-10-01 17:46:21 -07002811 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2812
2813 if (!mActiveConnections.isEmpty()) {
2814 dump.append(INDENT "ActiveConnections:\n");
2815 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2816 const Connection* connection = mActiveConnections[i];
Jeff Brown53f291e2010-10-25 17:37:46 -07002817 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brown90f0cee2010-10-08 22:31:17 -07002818 "inputState.isNeutral=%s\n",
Jeff Brown2806e382010-10-01 17:46:21 -07002819 i, connection->getInputChannelName(), connection->getStatusLabel(),
2820 connection->outboundQueue.count(),
Jeff Brown90f0cee2010-10-08 22:31:17 -07002821 toString(connection->inputState.isNeutral()));
Jeff Brown2806e382010-10-01 17:46:21 -07002822 }
2823 } else {
2824 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002825 }
2826
2827 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002828 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002829 (mAppSwitchDueTime - now()) / 1000000.0);
2830 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002831 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002832 }
2833}
2834
2835status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002836#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002837 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2838 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002839#endif
2840
Jeff Browne839a582010-04-22 18:58:52 -07002841 { // acquire lock
2842 AutoMutex _l(mLock);
2843
Jeff Brown53a415e2010-09-15 15:18:56 -07002844 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002845 LOGW("Attempted to register already registered input channel '%s'",
2846 inputChannel->getName().string());
2847 return BAD_VALUE;
2848 }
2849
2850 sp<Connection> connection = new Connection(inputChannel);
2851 status_t status = connection->initialize();
2852 if (status) {
2853 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2854 inputChannel->getName().string(), status);
2855 return status;
2856 }
2857
Jeff Brown0cacb872010-08-17 15:59:26 -07002858 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002859 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002860
Jeff Browna665ca82010-09-08 11:49:43 -07002861 if (monitor) {
2862 mMonitoringChannels.push(inputChannel);
2863 }
2864
Jeff Brown59abe7e2010-09-13 23:17:30 -07002865 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002866
Jeff Brown54bc2812010-06-15 01:31:58 -07002867 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002868 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002869 return OK;
2870}
2871
2872status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002873#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002874 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002875#endif
2876
Jeff Browne839a582010-04-22 18:58:52 -07002877 { // acquire lock
2878 AutoMutex _l(mLock);
2879
Jeff Brown53a415e2010-09-15 15:18:56 -07002880 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002881 if (connectionIndex < 0) {
2882 LOGW("Attempted to unregister already unregistered input channel '%s'",
2883 inputChannel->getName().string());
2884 return BAD_VALUE;
2885 }
2886
2887 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2888 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2889
2890 connection->status = Connection::STATUS_ZOMBIE;
2891
Jeff Browna665ca82010-09-08 11:49:43 -07002892 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2893 if (mMonitoringChannels[i] == inputChannel) {
2894 mMonitoringChannels.removeAt(i);
2895 break;
2896 }
2897 }
2898
Jeff Brown59abe7e2010-09-13 23:17:30 -07002899 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002900
Jeff Brown51d45a72010-06-17 20:52:56 -07002901 nsecs_t currentTime = now();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002902 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002903
2904 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002905 } // release lock
2906
Jeff Browne839a582010-04-22 18:58:52 -07002907 // Wake the poll loop because removing the connection may have changed the current
2908 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002909 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002910 return OK;
2911}
2912
Jeff Brown53a415e2010-09-15 15:18:56 -07002913ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002914 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2915 if (connectionIndex >= 0) {
2916 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2917 if (connection->inputChannel.get() == inputChannel.get()) {
2918 return connectionIndex;
2919 }
2920 }
2921
2922 return -1;
2923}
2924
Jeff Browne839a582010-04-22 18:58:52 -07002925void InputDispatcher::activateConnectionLocked(Connection* connection) {
2926 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2927 if (mActiveConnections.itemAt(i) == connection) {
2928 return;
2929 }
2930 }
2931 mActiveConnections.add(connection);
2932}
2933
2934void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2935 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2936 if (mActiveConnections.itemAt(i) == connection) {
2937 mActiveConnections.removeAt(i);
2938 return;
2939 }
2940 }
2941}
2942
Jeff Brown54bc2812010-06-15 01:31:58 -07002943void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002944 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002945}
2946
Jeff Brown54bc2812010-06-15 01:31:58 -07002947void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002948 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002949}
2950
Jeff Brown54bc2812010-06-15 01:31:58 -07002951void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002952 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002953 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2954 connection->getInputChannelName());
2955
Jeff Brown54bc2812010-06-15 01:31:58 -07002956 CommandEntry* commandEntry = postCommandLocked(
2957 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002958 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002959}
2960
Jeff Brown53a415e2010-09-15 15:18:56 -07002961void InputDispatcher::onANRLocked(
2962 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2963 nsecs_t eventTime, nsecs_t waitStartTime) {
2964 LOGI("Application is not responding: %s. "
2965 "%01.1fms since event, %01.1fms since wait started",
2966 getApplicationWindowLabelLocked(application, window).string(),
2967 (currentTime - eventTime) / 1000000.0,
2968 (currentTime - waitStartTime) / 1000000.0);
2969
2970 CommandEntry* commandEntry = postCommandLocked(
2971 & InputDispatcher::doNotifyANRLockedInterruptible);
2972 if (application) {
2973 commandEntry->inputApplicationHandle = application->handle;
2974 }
2975 if (window) {
2976 commandEntry->inputChannel = window->inputChannel;
2977 }
2978}
2979
Jeff Browna665ca82010-09-08 11:49:43 -07002980void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2981 CommandEntry* commandEntry) {
2982 mLock.unlock();
2983
2984 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2985
2986 mLock.lock();
2987}
2988
Jeff Brown54bc2812010-06-15 01:31:58 -07002989void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2990 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002991 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002992
Jeff Brown51d45a72010-06-17 20:52:56 -07002993 if (connection->status != Connection::STATUS_ZOMBIE) {
2994 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002995
Jeff Brown51d45a72010-06-17 20:52:56 -07002996 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2997
2998 mLock.lock();
2999 }
Jeff Brown54bc2812010-06-15 01:31:58 -07003000}
3001
Jeff Brown53a415e2010-09-15 15:18:56 -07003002void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07003003 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07003004 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07003005
Jeff Brown53a415e2010-09-15 15:18:56 -07003006 nsecs_t newTimeout = mPolicy->notifyANR(
3007 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07003008
Jeff Brown53a415e2010-09-15 15:18:56 -07003009 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07003010
Jeff Brown53a415e2010-09-15 15:18:56 -07003011 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07003012}
3013
Jeff Browna665ca82010-09-08 11:49:43 -07003014void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3015 CommandEntry* commandEntry) {
3016 KeyEntry* entry = commandEntry->keyEntry;
3017 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3018 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3019 entry->downTime, entry->eventTime);
3020
3021 mLock.unlock();
3022
3023 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
3024 & mReusableKeyEvent, entry->policyFlags);
3025
3026 mLock.lock();
3027
3028 entry->interceptKeyResult = consumed
3029 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
3030 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3031 mAllocator.releaseKeyEntry(entry);
3032}
3033
3034void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3035 mLock.unlock();
3036
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003037 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07003038
3039 mLock.lock();
3040}
3041
Jeff Brown53a415e2010-09-15 15:18:56 -07003042void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3043 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3044 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07003045}
3046
3047void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07003048 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07003049 dumpDispatchStateLocked(dump);
3050}
3051
Jeff Brown54bc2812010-06-15 01:31:58 -07003052
Jeff Brown53a415e2010-09-15 15:18:56 -07003053// --- InputDispatcher::Queue ---
3054
3055template <typename T>
3056uint32_t InputDispatcher::Queue<T>::count() const {
3057 uint32_t result = 0;
3058 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3059 result += 1;
3060 }
3061 return result;
3062}
3063
3064
Jeff Browne839a582010-04-22 18:58:52 -07003065// --- InputDispatcher::Allocator ---
3066
3067InputDispatcher::Allocator::Allocator() {
3068}
3069
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003070InputDispatcher::InjectionState*
3071InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3072 InjectionState* injectionState = mInjectionStatePool.alloc();
3073 injectionState->refCount = 1;
3074 injectionState->injectorPid = injectorPid;
3075 injectionState->injectorUid = injectorUid;
3076 injectionState->injectionIsAsync = false;
3077 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3078 injectionState->pendingForegroundDispatches = 0;
3079 return injectionState;
3080}
3081
Jeff Brown51d45a72010-06-17 20:52:56 -07003082void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brown90f0cee2010-10-08 22:31:17 -07003083 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown51d45a72010-06-17 20:52:56 -07003084 entry->type = type;
3085 entry->refCount = 1;
3086 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07003087 entry->eventTime = eventTime;
Jeff Brown90f0cee2010-10-08 22:31:17 -07003088 entry->policyFlags = policyFlags;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003089 entry->injectionState = NULL;
3090}
3091
3092void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3093 if (entry->injectionState) {
3094 releaseInjectionState(entry->injectionState);
3095 entry->injectionState = NULL;
3096 }
Jeff Brown51d45a72010-06-17 20:52:56 -07003097}
3098
Jeff Browne839a582010-04-22 18:58:52 -07003099InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07003100InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003101 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003102 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Browne839a582010-04-22 18:58:52 -07003103 return entry;
3104}
3105
Jeff Brown51d45a72010-06-17 20:52:56 -07003106InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07003107 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07003108 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3109 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003110 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003111 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003112
3113 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003114 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003115 entry->action = action;
3116 entry->flags = flags;
3117 entry->keyCode = keyCode;
3118 entry->scanCode = scanCode;
3119 entry->metaState = metaState;
3120 entry->repeatCount = repeatCount;
3121 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07003122 entry->syntheticRepeat = false;
3123 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07003124 return entry;
3125}
3126
Jeff Brown51d45a72010-06-17 20:52:56 -07003127InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07003128 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07003129 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3130 nsecs_t downTime, uint32_t pointerCount,
3131 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003132 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003133 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003134
3135 entry->eventTime = eventTime;
3136 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003137 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003138 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07003139 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07003140 entry->metaState = metaState;
3141 entry->edgeFlags = edgeFlags;
3142 entry->xPrecision = xPrecision;
3143 entry->yPrecision = yPrecision;
3144 entry->downTime = downTime;
3145 entry->pointerCount = pointerCount;
3146 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07003147 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07003148 entry->lastSample = & entry->firstSample;
3149 for (uint32_t i = 0; i < pointerCount; i++) {
3150 entry->pointerIds[i] = pointerIds[i];
3151 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3152 }
Jeff Browne839a582010-04-22 18:58:52 -07003153 return entry;
3154}
3155
3156InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07003157 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07003158 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07003159 DispatchEntry* entry = mDispatchEntryPool.alloc();
3160 entry->eventEntry = eventEntry;
3161 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07003162 entry->targetFlags = targetFlags;
3163 entry->xOffset = xOffset;
3164 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07003165 entry->inProgress = false;
3166 entry->headMotionSample = NULL;
3167 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07003168 return entry;
3169}
3170
Jeff Brown54bc2812010-06-15 01:31:58 -07003171InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3172 CommandEntry* entry = mCommandEntryPool.alloc();
3173 entry->command = command;
3174 return entry;
3175}
3176
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003177void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3178 injectionState->refCount -= 1;
3179 if (injectionState->refCount == 0) {
3180 mInjectionStatePool.free(injectionState);
3181 } else {
3182 assert(injectionState->refCount > 0);
3183 }
3184}
3185
Jeff Browne839a582010-04-22 18:58:52 -07003186void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3187 switch (entry->type) {
3188 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3189 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3190 break;
3191 case EventEntry::TYPE_KEY:
3192 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3193 break;
3194 case EventEntry::TYPE_MOTION:
3195 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3196 break;
3197 default:
3198 assert(false);
3199 break;
3200 }
3201}
3202
3203void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3204 ConfigurationChangedEntry* entry) {
3205 entry->refCount -= 1;
3206 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003207 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003208 mConfigurationChangeEntryPool.free(entry);
3209 } else {
3210 assert(entry->refCount > 0);
3211 }
3212}
3213
3214void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3215 entry->refCount -= 1;
3216 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003217 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003218 mKeyEntryPool.free(entry);
3219 } else {
3220 assert(entry->refCount > 0);
3221 }
3222}
3223
3224void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3225 entry->refCount -= 1;
3226 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003227 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -07003228 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3229 MotionSample* next = sample->next;
3230 mMotionSamplePool.free(sample);
3231 sample = next;
3232 }
Jeff Browne839a582010-04-22 18:58:52 -07003233 mMotionEntryPool.free(entry);
3234 } else {
3235 assert(entry->refCount > 0);
3236 }
3237}
3238
3239void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3240 releaseEventEntry(entry->eventEntry);
3241 mDispatchEntryPool.free(entry);
3242}
3243
Jeff Brown54bc2812010-06-15 01:31:58 -07003244void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3245 mCommandEntryPool.free(entry);
3246}
3247
Jeff Browne839a582010-04-22 18:58:52 -07003248void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003249 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003250 MotionSample* sample = mMotionSamplePool.alloc();
3251 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003252 uint32_t pointerCount = motionEntry->pointerCount;
3253 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07003254 sample->pointerCoords[i] = pointerCoords[i];
3255 }
3256
3257 sample->next = NULL;
3258 motionEntry->lastSample->next = sample;
3259 motionEntry->lastSample = sample;
3260}
3261
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003262void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3263 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003264
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003265 keyEntry->dispatchInProgress = false;
3266 keyEntry->syntheticRepeat = false;
3267 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003268}
3269
3270
Jeff Brown542412c2010-08-18 15:51:08 -07003271// --- InputDispatcher::MotionEntry ---
3272
3273uint32_t InputDispatcher::MotionEntry::countSamples() const {
3274 uint32_t count = 1;
3275 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3276 count += 1;
3277 }
3278 return count;
3279}
3280
Jeff Browna665ca82010-09-08 11:49:43 -07003281
3282// --- InputDispatcher::InputState ---
3283
Jeff Brown90f0cee2010-10-08 22:31:17 -07003284InputDispatcher::InputState::InputState() {
Jeff Browna665ca82010-09-08 11:49:43 -07003285}
3286
3287InputDispatcher::InputState::~InputState() {
3288}
3289
3290bool InputDispatcher::InputState::isNeutral() const {
3291 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3292}
3293
Jeff Browna665ca82010-09-08 11:49:43 -07003294InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3295 const EventEntry* entry) {
3296 switch (entry->type) {
3297 case EventEntry::TYPE_KEY:
3298 return trackKey(static_cast<const KeyEntry*>(entry));
3299
3300 case EventEntry::TYPE_MOTION:
3301 return trackMotion(static_cast<const MotionEntry*>(entry));
3302
3303 default:
3304 return CONSISTENT;
3305 }
3306}
3307
3308InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3309 const KeyEntry* entry) {
3310 int32_t action = entry->action;
3311 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3312 KeyMemento& memento = mKeyMementos.editItemAt(i);
3313 if (memento.deviceId == entry->deviceId
3314 && memento.source == entry->source
3315 && memento.keyCode == entry->keyCode
3316 && memento.scanCode == entry->scanCode) {
3317 switch (action) {
3318 case AKEY_EVENT_ACTION_UP:
3319 mKeyMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003320 return CONSISTENT;
3321
3322 case AKEY_EVENT_ACTION_DOWN:
3323 return TOLERABLE;
3324
3325 default:
3326 return BROKEN;
3327 }
3328 }
3329 }
3330
3331 switch (action) {
3332 case AKEY_EVENT_ACTION_DOWN: {
3333 mKeyMementos.push();
3334 KeyMemento& memento = mKeyMementos.editTop();
3335 memento.deviceId = entry->deviceId;
3336 memento.source = entry->source;
3337 memento.keyCode = entry->keyCode;
3338 memento.scanCode = entry->scanCode;
3339 memento.downTime = entry->downTime;
3340 return CONSISTENT;
3341 }
3342
3343 default:
3344 return BROKEN;
3345 }
3346}
3347
3348InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3349 const MotionEntry* entry) {
3350 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3351 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3352 MotionMemento& memento = mMotionMementos.editItemAt(i);
3353 if (memento.deviceId == entry->deviceId
3354 && memento.source == entry->source) {
3355 switch (action) {
3356 case AMOTION_EVENT_ACTION_UP:
3357 case AMOTION_EVENT_ACTION_CANCEL:
3358 mMotionMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003359 return CONSISTENT;
3360
3361 case AMOTION_EVENT_ACTION_DOWN:
3362 return TOLERABLE;
3363
3364 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3365 if (entry->pointerCount == memento.pointerCount + 1) {
3366 memento.setPointers(entry);
3367 return CONSISTENT;
3368 }
3369 return BROKEN;
3370
3371 case AMOTION_EVENT_ACTION_POINTER_UP:
3372 if (entry->pointerCount == memento.pointerCount - 1) {
3373 memento.setPointers(entry);
3374 return CONSISTENT;
3375 }
3376 return BROKEN;
3377
3378 case AMOTION_EVENT_ACTION_MOVE:
3379 if (entry->pointerCount == memento.pointerCount) {
3380 return CONSISTENT;
3381 }
3382 return BROKEN;
3383
3384 default:
3385 return BROKEN;
3386 }
3387 }
3388 }
3389
3390 switch (action) {
3391 case AMOTION_EVENT_ACTION_DOWN: {
3392 mMotionMementos.push();
3393 MotionMemento& memento = mMotionMementos.editTop();
3394 memento.deviceId = entry->deviceId;
3395 memento.source = entry->source;
3396 memento.xPrecision = entry->xPrecision;
3397 memento.yPrecision = entry->yPrecision;
3398 memento.downTime = entry->downTime;
3399 memento.setPointers(entry);
3400 return CONSISTENT;
3401 }
3402
3403 default:
3404 return BROKEN;
3405 }
3406}
3407
3408void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3409 pointerCount = entry->pointerCount;
3410 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3411 pointerIds[i] = entry->pointerIds[i];
3412 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3413 }
3414}
3415
Jeff Brown90f0cee2010-10-08 22:31:17 -07003416void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3417 Allocator* allocator, Vector<EventEntry*>& outEvents,
3418 CancelationOptions options) {
3419 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003420 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003421 if (shouldCancelEvent(memento.source, options)) {
3422 outEvents.push(allocator->obtainKeyEntry(currentTime,
3423 memento.deviceId, memento.source, 0,
3424 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3425 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3426 mKeyMementos.removeAt(i);
3427 } else {
3428 i += 1;
3429 }
Jeff Browna665ca82010-09-08 11:49:43 -07003430 }
3431
Jeff Brown316237d2010-10-11 18:22:53 -07003432 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003433 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003434 if (shouldCancelEvent(memento.source, options)) {
3435 outEvents.push(allocator->obtainMotionEntry(currentTime,
3436 memento.deviceId, memento.source, 0,
3437 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3438 memento.xPrecision, memento.yPrecision, memento.downTime,
3439 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3440 mMotionMementos.removeAt(i);
3441 } else {
3442 i += 1;
3443 }
Jeff Browna665ca82010-09-08 11:49:43 -07003444 }
3445}
3446
3447void InputDispatcher::InputState::clear() {
3448 mKeyMementos.clear();
3449 mMotionMementos.clear();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003450}
3451
Jeff Brownb6702e52010-10-11 18:32:20 -07003452void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3453 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3454 const MotionMemento& memento = mMotionMementos.itemAt(i);
3455 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3456 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3457 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3458 if (memento.deviceId == otherMemento.deviceId
3459 && memento.source == otherMemento.source) {
3460 other.mMotionMementos.removeAt(j);
3461 } else {
3462 j += 1;
3463 }
3464 }
3465 other.mMotionMementos.push(memento);
3466 }
3467 }
3468}
3469
Jeff Brown90f0cee2010-10-08 22:31:17 -07003470bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3471 CancelationOptions options) {
3472 switch (options) {
3473 case CANCEL_POINTER_EVENTS:
3474 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3475 case CANCEL_NON_POINTER_EVENTS:
3476 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3477 default:
3478 return true;
3479 }
Jeff Browna665ca82010-09-08 11:49:43 -07003480}
3481
3482
Jeff Browne839a582010-04-22 18:58:52 -07003483// --- InputDispatcher::Connection ---
3484
3485InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3486 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003487 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003488}
3489
3490InputDispatcher::Connection::~Connection() {
3491}
3492
3493status_t InputDispatcher::Connection::initialize() {
3494 return inputPublisher.initialize();
3495}
3496
Jeff Brown54bc2812010-06-15 01:31:58 -07003497const char* InputDispatcher::Connection::getStatusLabel() const {
3498 switch (status) {
3499 case STATUS_NORMAL:
3500 return "NORMAL";
3501
3502 case STATUS_BROKEN:
3503 return "BROKEN";
3504
Jeff Brown54bc2812010-06-15 01:31:58 -07003505 case STATUS_ZOMBIE:
3506 return "ZOMBIE";
3507
3508 default:
3509 return "UNKNOWN";
3510 }
3511}
3512
Jeff Browne839a582010-04-22 18:58:52 -07003513InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3514 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003515 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3516 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003517 if (dispatchEntry->eventEntry == eventEntry) {
3518 return dispatchEntry;
3519 }
3520 }
3521 return NULL;
3522}
3523
Jeff Browna665ca82010-09-08 11:49:43 -07003524
Jeff Brown54bc2812010-06-15 01:31:58 -07003525// --- InputDispatcher::CommandEntry ---
3526
Jeff Browna665ca82010-09-08 11:49:43 -07003527InputDispatcher::CommandEntry::CommandEntry() :
3528 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003529}
3530
3531InputDispatcher::CommandEntry::~CommandEntry() {
3532}
3533
Jeff Browne839a582010-04-22 18:58:52 -07003534
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003535// --- InputDispatcher::TouchState ---
3536
3537InputDispatcher::TouchState::TouchState() :
3538 down(false), split(false) {
3539}
3540
3541InputDispatcher::TouchState::~TouchState() {
3542}
3543
3544void InputDispatcher::TouchState::reset() {
3545 down = false;
3546 split = false;
3547 windows.clear();
3548}
3549
3550void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3551 down = other.down;
3552 split = other.split;
3553 windows.clear();
3554 windows.appendVector(other.windows);
3555}
3556
3557void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3558 int32_t targetFlags, BitSet32 pointerIds) {
3559 if (targetFlags & InputTarget::FLAG_SPLIT) {
3560 split = true;
3561 }
3562
3563 for (size_t i = 0; i < windows.size(); i++) {
3564 TouchedWindow& touchedWindow = windows.editItemAt(i);
3565 if (touchedWindow.window == window) {
3566 touchedWindow.targetFlags |= targetFlags;
3567 touchedWindow.pointerIds.value |= pointerIds.value;
3568 return;
3569 }
3570 }
3571
3572 windows.push();
3573
3574 TouchedWindow& touchedWindow = windows.editTop();
3575 touchedWindow.window = window;
3576 touchedWindow.targetFlags = targetFlags;
3577 touchedWindow.pointerIds = pointerIds;
3578 touchedWindow.channel = window->inputChannel;
3579}
3580
3581void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3582 for (size_t i = 0 ; i < windows.size(); ) {
3583 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3584 windows.removeAt(i);
3585 } else {
3586 i += 1;
3587 }
3588 }
3589}
3590
3591const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3592 for (size_t i = 0; i < windows.size(); i++) {
3593 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3594 return windows[i].window;
3595 }
3596 }
3597 return NULL;
3598}
3599
3600
Jeff Browne839a582010-04-22 18:58:52 -07003601// --- InputDispatcherThread ---
3602
3603InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3604 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3605}
3606
3607InputDispatcherThread::~InputDispatcherThread() {
3608}
3609
3610bool InputDispatcherThread::threadLoop() {
3611 mDispatcher->dispatchOnce();
3612 return true;
3613}
3614
3615} // namespace android