blob: 421ad663f8fd940f198a7d4a71c4063a47205bd0 [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 Brownd9dd44d2010-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 Brown1fe6dec2010-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 Brown1fe6dec2010-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 Brown1fe6dec2010-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 Brown1fe6dec2010-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 Brown1fe6dec2010-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 Brown1fe6dec2010-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 Brown1fe6dec2010-10-11 14:20:19 -0700621 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brown9cf416c2010-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 Brown1fe6dec2010-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 Brown1fe6dec2010-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 Brown1fe6dec2010-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 Brown1fe6dec2010-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 Brown9cf416c2010-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 Brown9cf416c2010-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 Brown1fe6dec2010-10-11 14:20:19 -0700717 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brown9cf416c2010-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 Brown1fe6dec2010-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 Brown1c322582010-09-28 13:24:41 -07001116 if (newTouchedWindow
1117 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001118 // New window supports splitting.
1119 isSplit = true;
1120 } else if (isSplit) {
1121 // New window does not support splitting but we have already split events.
1122 // Assign the pointer to the first foreground window we find.
1123 // (May be NULL which is why we put this code block before the next check.)
1124 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1125 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001126
Jeff Browna665ca82010-09-08 11:49:43 -07001127 // If we did not find a touched window then fail.
1128 if (! newTouchedWindow) {
1129 if (mFocusedApplication) {
1130#if DEBUG_FOCUS
1131 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -07001132 "focused application that may eventually add a new window: %s.",
1133 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -07001134#endif
1135 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1136 mFocusedApplication, NULL, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -07001137 goto Unresponsive;
1138 }
1139
1140 LOGI("Dropping event because there is no touched window or focused application.");
1141 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001142 goto Failed;
1143 }
1144
Jeff Brown35cf0e92010-10-05 12:26:23 -07001145 // Set target flags.
1146 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1147 if (isSplit) {
1148 targetFlags |= InputTarget::FLAG_SPLIT;
1149 }
1150 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1151 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1152 }
1153
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001154 // Update the temporary touch state.
1155 BitSet32 pointerIds;
1156 if (isSplit) {
1157 uint32_t pointerId = entry->pointerIds[pointerIndex];
1158 pointerIds.markBit(pointerId);
Jeff Browna665ca82010-09-08 11:49:43 -07001159 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001160 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001161 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001162 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001163
1164 // If the pointer is not currently down, then ignore the event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001165 if (! mTempTouchState.down) {
Jeff Browna665ca82010-09-08 11:49:43 -07001166 LOGI("Dropping event because the pointer is not down.");
1167 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001168 goto Failed;
1169 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001170 }
Jeff Browna665ca82010-09-08 11:49:43 -07001171
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001172 // Check permission to inject into all touched foreground windows and ensure there
1173 // is at least one touched foreground window.
1174 {
1175 bool haveForegroundWindow = false;
1176 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1177 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1178 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1179 haveForegroundWindow = true;
1180 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1181 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1182 injectionPermission = INJECTION_PERMISSION_DENIED;
1183 goto Failed;
1184 }
1185 }
1186 }
1187 if (! haveForegroundWindow) {
Jeff Browna665ca82010-09-08 11:49:43 -07001188#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001189 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Browna665ca82010-09-08 11:49:43 -07001190#endif
1191 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001192 goto Failed;
1193 }
1194
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001195 // Permission granted to injection into all touched foreground windows.
1196 injectionPermission = INJECTION_PERMISSION_GRANTED;
1197 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001198
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001199 // Ensure all touched foreground windows are ready for new input.
1200 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1201 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1202 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1203 // If the touched window is paused then keep waiting.
1204 if (touchedWindow.window->paused) {
1205#if DEBUG_INPUT_DISPATCHER_POLICY
1206 LOGD("Waiting because touched window is paused.");
Jeff Brown53a415e2010-09-15 15:18:56 -07001207#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001208 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1209 NULL, touchedWindow.window, nextWakeupTime);
1210 goto Unresponsive;
1211 }
1212
1213 // If the touched window is still working on previous events then keep waiting.
1214 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1215#if DEBUG_FOCUS
1216 LOGD("Waiting because touched window still processing previous input.");
1217#endif
1218 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1219 NULL, touchedWindow.window, nextWakeupTime);
1220 goto Unresponsive;
1221 }
1222 }
1223 }
1224
1225 // If this is the first pointer going down and the touched window has a wallpaper
1226 // then also add the touched wallpaper windows so they are locked in for the duration
1227 // of the touch gesture.
1228 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1229 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1230 if (foregroundWindow->hasWallpaper) {
1231 for (size_t i = 0; i < mWindows.size(); i++) {
1232 const InputWindow* window = & mWindows[i];
1233 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001234 mTempTouchState.addOrUpdateWindow(window,
1235 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001236 }
1237 }
1238 }
1239 }
1240
Jeff Browna665ca82010-09-08 11:49:43 -07001241 // Success! Output targets.
1242 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Browna665ca82010-09-08 11:49:43 -07001243
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001244 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1245 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1246 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1247 touchedWindow.pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001248 }
1249
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001250 // Drop the outside touch window since we will not care about them in the next iteration.
1251 mTempTouchState.removeOutsideTouchWindows();
1252
Jeff Browna665ca82010-09-08 11:49:43 -07001253Failed:
1254 // Check injection permission once and for all.
1255 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001256 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001257 injectionPermission = INJECTION_PERMISSION_GRANTED;
1258 } else {
1259 injectionPermission = INJECTION_PERMISSION_DENIED;
1260 }
1261 }
1262
1263 // Update final pieces of touch state if the injector had permission.
1264 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001265 if (maskedAction == AMOTION_EVENT_ACTION_UP
1266 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1267 // All pointers up or canceled.
1268 mTempTouchState.reset();
1269 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1270 // First pointer went down.
1271 if (mTouchState.down) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001272#if DEBUG_FOCUS
1273 LOGD("Pointer down received while already down.");
1274#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001275 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001276 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1277 // One pointer went up.
1278 if (isSplit) {
1279 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1280 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Browna665ca82010-09-08 11:49:43 -07001281
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001282 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1283 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1284 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1285 touchedWindow.pointerIds.clearBit(pointerId);
1286 if (touchedWindow.pointerIds.isEmpty()) {
1287 mTempTouchState.windows.removeAt(i);
1288 continue;
1289 }
1290 }
1291 i += 1;
1292 }
Jeff Browna665ca82010-09-08 11:49:43 -07001293 }
Jeff Browna665ca82010-09-08 11:49:43 -07001294 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001295
1296 // Save changes to touch state.
1297 mTouchState.copyFrom(mTempTouchState);
Jeff Browna665ca82010-09-08 11:49:43 -07001298 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001299#if DEBUG_FOCUS
1300 LOGD("Not updating touch focus because injection was denied.");
1301#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001302 }
1303
1304Unresponsive:
Jeff Brownfef5b042010-10-27 18:43:51 -07001305 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1306 mTempTouchState.reset();
1307
Jeff Brown53a415e2010-09-15 15:18:56 -07001308 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1309 updateDispatchStatisticsLocked(currentTime, entry,
1310 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001311#if DEBUG_FOCUS
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001312 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1313 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown53a415e2010-09-15 15:18:56 -07001314 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001315#endif
1316 return injectionResult;
1317}
1318
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001319void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1320 BitSet32 pointerIds) {
Jeff Browna665ca82010-09-08 11:49:43 -07001321 mCurrentInputTargets.push();
1322
1323 InputTarget& target = mCurrentInputTargets.editTop();
1324 target.inputChannel = window->inputChannel;
1325 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001326 target.xOffset = - window->frameLeft;
1327 target.yOffset = - window->frameTop;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001328 target.pointerIds = pointerIds;
Jeff Browna665ca82010-09-08 11:49:43 -07001329}
1330
1331void InputDispatcher::addMonitoringTargetsLocked() {
1332 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1333 mCurrentInputTargets.push();
1334
1335 InputTarget& target = mCurrentInputTargets.editTop();
1336 target.inputChannel = mMonitoringChannels[i];
1337 target.flags = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07001338 target.xOffset = 0;
1339 target.yOffset = 0;
1340 }
1341}
1342
1343bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001344 const InjectionState* injectionState) {
1345 if (injectionState
Jeff Brown90f0cee2010-10-08 22:31:17 -07001346 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1347 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1348 if (window) {
1349 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1350 "with input channel %s owned by uid %d",
1351 injectionState->injectorPid, injectionState->injectorUid,
1352 window->inputChannel->getName().string(),
1353 window->ownerUid);
1354 } else {
1355 LOGW("Permission denied: injecting event from pid %d uid %d",
1356 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-09-08 11:49:43 -07001357 }
Jeff Brown90f0cee2010-10-08 22:31:17 -07001358 return false;
Jeff Browna665ca82010-09-08 11:49:43 -07001359 }
1360 return true;
1361}
1362
Jeff Brown35cf0e92010-10-05 12:26:23 -07001363bool InputDispatcher::isWindowObscuredAtPointLocked(
1364 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Browna665ca82010-09-08 11:49:43 -07001365 size_t numWindows = mWindows.size();
1366 for (size_t i = 0; i < numWindows; i++) {
1367 const InputWindow* other = & mWindows.itemAt(i);
1368 if (other == window) {
1369 break;
1370 }
Jeff Brown35cf0e92010-10-05 12:26:23 -07001371 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001372 return true;
1373 }
1374 }
1375 return false;
1376}
1377
Jeff Brown53a415e2010-09-15 15:18:56 -07001378bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1379 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1380 if (connectionIndex >= 0) {
1381 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1382 return connection->outboundQueue.isEmpty();
1383 } else {
1384 return true;
1385 }
1386}
1387
1388String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1389 const InputWindow* window) {
1390 if (application) {
1391 if (window) {
1392 String8 label(application->name);
1393 label.append(" - ");
1394 label.append(window->name);
1395 return label;
1396 } else {
1397 return application->name;
1398 }
1399 } else if (window) {
1400 return window->name;
1401 } else {
1402 return String8("<unknown application or window>");
1403 }
1404}
1405
Jeff Brownef3a8232010-10-18 13:21:23 -07001406void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1407 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Browne7a0d2b2010-10-29 21:50:21 -07001408 switch (eventEntry->type) {
1409 case EventEntry::TYPE_MOTION: {
Jeff Brownef3a8232010-10-18 13:21:23 -07001410 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Browne7a0d2b2010-10-29 21:50:21 -07001411 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1412 return;
1413 }
1414
Jeff Brownef3a8232010-10-18 13:21:23 -07001415 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1416 switch (motionEntry->action) {
1417 case AMOTION_EVENT_ACTION_DOWN:
1418 eventType = POWER_MANAGER_TOUCH_EVENT;
1419 break;
1420 case AMOTION_EVENT_ACTION_UP:
1421 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
1422 break;
1423 default:
Jeff Brownf6149c32010-11-01 20:35:46 -07001424 if (motionEntry->eventTime - motionEntry->downTime < LONG_TOUCH_DELAY) {
Jeff Brownef3a8232010-10-18 13:21:23 -07001425 eventType = POWER_MANAGER_TOUCH_EVENT;
1426 } else {
1427 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
1428 }
1429 break;
1430 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001431 }
Jeff Browne7a0d2b2010-10-29 21:50:21 -07001432 break;
1433 }
1434 case EventEntry::TYPE_KEY: {
1435 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1436 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1437 return;
1438 }
1439 break;
1440 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001441 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001442
Jeff Browna665ca82010-09-08 11:49:43 -07001443 CommandEntry* commandEntry = postCommandLocked(
1444 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Brownef3a8232010-10-18 13:21:23 -07001445 commandEntry->eventTime = eventEntry->eventTime;
Jeff Browna665ca82010-09-08 11:49:43 -07001446 commandEntry->userActivityEventType = eventType;
1447}
1448
Jeff Brown51d45a72010-06-17 20:52:56 -07001449void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1450 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -07001451 bool resumeWithAppendedMotionSample) {
1452#if DEBUG_DISPATCH_CYCLE
Jeff Brown53a415e2010-09-15 15:18:56 -07001453 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001454 "xOffset=%f, yOffset=%f, "
1455 "windowType=%d, pointerIds=0x%x, "
1456 "resumeWithAppendedMotionSample=%s",
Jeff Brown53a415e2010-09-15 15:18:56 -07001457 connection->getInputChannelName(), inputTarget->flags,
Jeff Browne839a582010-04-22 18:58:52 -07001458 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001459 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Browna665ca82010-09-08 11:49:43 -07001460 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -07001461#endif
1462
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001463 // Make sure we are never called for streaming when splitting across multiple windows.
1464 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1465 assert(! (resumeWithAppendedMotionSample && isSplit));
1466
Jeff Browne839a582010-04-22 18:58:52 -07001467 // Skip this event if the connection status is not normal.
Jeff Brown53a415e2010-09-15 15:18:56 -07001468 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Browne839a582010-04-22 18:58:52 -07001469 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001470#if DEBUG_DISPATCH_CYCLE
1471 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Browna665ca82010-09-08 11:49:43 -07001472 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown90f0cee2010-10-08 22:31:17 -07001473#endif
Jeff Browne839a582010-04-22 18:58:52 -07001474 return;
1475 }
1476
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001477 // Split a motion event if needed.
1478 if (isSplit) {
1479 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1480
1481 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1482 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1483 MotionEntry* splitMotionEntry = splitMotionEvent(
1484 originalMotionEntry, inputTarget->pointerIds);
1485#if DEBUG_FOCUS
1486 LOGD("channel '%s' ~ Split motion event.",
1487 connection->getInputChannelName());
1488 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1489#endif
1490 eventEntry = splitMotionEntry;
1491 }
1492 }
1493
Jeff Browne839a582010-04-22 18:58:52 -07001494 // Resume the dispatch cycle with a freshly appended motion sample.
1495 // First we check that the last dispatch entry in the outbound queue is for the same
1496 // motion event to which we appended the motion sample. If we find such a dispatch
1497 // entry, and if it is currently in progress then we try to stream the new sample.
1498 bool wasEmpty = connection->outboundQueue.isEmpty();
1499
1500 if (! wasEmpty && resumeWithAppendedMotionSample) {
1501 DispatchEntry* motionEventDispatchEntry =
1502 connection->findQueuedDispatchEntryForEvent(eventEntry);
1503 if (motionEventDispatchEntry) {
1504 // If the dispatch entry is not in progress, then we must be busy dispatching an
1505 // earlier event. Not a problem, the motion event is on the outbound queue and will
1506 // be dispatched later.
1507 if (! motionEventDispatchEntry->inProgress) {
1508#if DEBUG_BATCHING
1509 LOGD("channel '%s' ~ Not streaming because the motion event has "
1510 "not yet been dispatched. "
1511 "(Waiting for earlier events to be consumed.)",
1512 connection->getInputChannelName());
1513#endif
1514 return;
1515 }
1516
1517 // If the dispatch entry is in progress but it already has a tail of pending
1518 // motion samples, then it must mean that the shared memory buffer filled up.
1519 // Not a problem, when this dispatch cycle is finished, we will eventually start
1520 // a new dispatch cycle to process the tail and that tail includes the newly
1521 // appended motion sample.
1522 if (motionEventDispatchEntry->tailMotionSample) {
1523#if DEBUG_BATCHING
1524 LOGD("channel '%s' ~ Not streaming because no new samples can "
1525 "be appended to the motion event in this dispatch cycle. "
1526 "(Waiting for next dispatch cycle to start.)",
1527 connection->getInputChannelName());
1528#endif
1529 return;
1530 }
1531
1532 // The dispatch entry is in progress and is still potentially open for streaming.
1533 // Try to stream the new motion sample. This might fail if the consumer has already
1534 // consumed the motion event (or if the channel is broken).
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001535 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1536 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Browne839a582010-04-22 18:58:52 -07001537 status_t status = connection->inputPublisher.appendMotionSample(
1538 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1539 if (status == OK) {
1540#if DEBUG_BATCHING
1541 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1542 connection->getInputChannelName());
1543#endif
1544 return;
1545 }
1546
1547#if DEBUG_BATCHING
1548 if (status == NO_MEMORY) {
1549 LOGD("channel '%s' ~ Could not append motion sample to currently "
1550 "dispatched move event because the shared memory buffer is full. "
1551 "(Waiting for next dispatch cycle to start.)",
1552 connection->getInputChannelName());
1553 } else if (status == status_t(FAILED_TRANSACTION)) {
1554 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown50de30a2010-06-22 01:27:15 -07001555 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-04-22 18:58:52 -07001556 "(Waiting for next dispatch cycle to start.)",
1557 connection->getInputChannelName());
1558 } else {
1559 LOGD("channel '%s' ~ Could not append motion sample to currently "
1560 "dispatched move event due to an error, status=%d. "
1561 "(Waiting for next dispatch cycle to start.)",
1562 connection->getInputChannelName(), status);
1563 }
1564#endif
1565 // Failed to stream. Start a new tail of pending motion samples to dispatch
1566 // in the next cycle.
1567 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1568 return;
1569 }
1570 }
1571
1572 // This is a new event.
1573 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Browna665ca82010-09-08 11:49:43 -07001574 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown53a415e2010-09-15 15:18:56 -07001575 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1576 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001577 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001578 }
1579
Jeff Browne839a582010-04-22 18:58:52 -07001580 // Handle the case where we could not stream a new motion sample because the consumer has
1581 // already consumed the motion event (otherwise the corresponding dispatch entry would
1582 // still be in the outbound queue for this connection). We set the head motion sample
1583 // to the list starting with the newly appended motion sample.
1584 if (resumeWithAppendedMotionSample) {
1585#if DEBUG_BATCHING
1586 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1587 "that cannot be streamed because the motion event has already been consumed.",
1588 connection->getInputChannelName());
1589#endif
1590 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1591 dispatchEntry->headMotionSample = appendedMotionSample;
1592 }
1593
1594 // Enqueue the dispatch entry.
1595 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1596
1597 // If the outbound queue was previously empty, start the dispatch cycle going.
1598 if (wasEmpty) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001599 activateConnectionLocked(connection.get());
Jeff Brown53a415e2010-09-15 15:18:56 -07001600 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001601 }
1602}
1603
Jeff Brown51d45a72010-06-17 20:52:56 -07001604void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown53a415e2010-09-15 15:18:56 -07001605 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001606#if DEBUG_DISPATCH_CYCLE
1607 LOGD("channel '%s' ~ startDispatchCycle",
1608 connection->getInputChannelName());
1609#endif
1610
1611 assert(connection->status == Connection::STATUS_NORMAL);
1612 assert(! connection->outboundQueue.isEmpty());
1613
Jeff Browna665ca82010-09-08 11:49:43 -07001614 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001615 assert(! dispatchEntry->inProgress);
1616
Jeff Browna665ca82010-09-08 11:49:43 -07001617 // Mark the dispatch entry as in progress.
1618 dispatchEntry->inProgress = true;
1619
1620 // Update the connection's input state.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001621 EventEntry* eventEntry = dispatchEntry->eventEntry;
1622 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001623
1624#if FILTER_INPUT_EVENTS
1625 // Filter out inconsistent sequences of input events.
1626 // The input system may drop or inject events in a way that could violate implicit
1627 // invariants on input state and potentially cause an application to crash
1628 // or think that a key or pointer is stuck down. Technically we make no guarantees
1629 // of consistency but it would be nice to improve on this where possible.
1630 // XXX: This code is a proof of concept only. Not ready for prime time.
1631 if (consistency == InputState::TOLERABLE) {
1632#if DEBUG_DISPATCH_CYCLE
1633 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1634 "current input state but that is likely to be tolerated by the application.",
1635 connection->getInputChannelName());
1636#endif
1637 } else if (consistency == InputState::BROKEN) {
1638 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1639 "current input state and that is likely to cause the application to crash.",
1640 connection->getInputChannelName());
1641 startNextDispatchCycleLocked(currentTime, connection);
1642 return;
1643 }
1644#endif
Jeff Browne839a582010-04-22 18:58:52 -07001645
1646 // Publish the event.
1647 status_t status;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001648 switch (eventEntry->type) {
Jeff Browne839a582010-04-22 18:58:52 -07001649 case EventEntry::TYPE_KEY: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001650 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001651
1652 // Apply target flags.
1653 int32_t action = keyEntry->action;
1654 int32_t flags = keyEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001655
1656 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001657 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-04-22 18:58:52 -07001658 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1659 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1660 keyEntry->eventTime);
1661
1662 if (status) {
1663 LOGE("channel '%s' ~ Could not publish key event, "
1664 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001665 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001666 return;
1667 }
1668 break;
1669 }
1670
1671 case EventEntry::TYPE_MOTION: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001672 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001673
1674 // Apply target flags.
1675 int32_t action = motionEntry->action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07001676 int32_t flags = motionEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001677 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001678 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -07001679 }
Jeff Brownaf30ff62010-09-01 17:01:00 -07001680 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1681 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1682 }
Jeff Browne839a582010-04-22 18:58:52 -07001683
1684 // If headMotionSample is non-NULL, then it points to the first new sample that we
1685 // were unable to dispatch during the previous cycle so we resume dispatching from
1686 // that point in the list of motion samples.
1687 // Otherwise, we just start from the first sample of the motion event.
1688 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1689 if (! firstMotionSample) {
1690 firstMotionSample = & motionEntry->firstSample;
1691 }
1692
Jeff Brownf26db0d2010-07-16 17:21:06 -07001693 // Set the X and Y offset depending on the input source.
1694 float xOffset, yOffset;
1695 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1696 xOffset = dispatchEntry->xOffset;
1697 yOffset = dispatchEntry->yOffset;
1698 } else {
1699 xOffset = 0.0f;
1700 yOffset = 0.0f;
1701 }
1702
Jeff Browne839a582010-04-22 18:58:52 -07001703 // Publish the motion event and the first motion sample.
1704 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001705 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -07001706 xOffset, yOffset,
Jeff Browne839a582010-04-22 18:58:52 -07001707 motionEntry->xPrecision, motionEntry->yPrecision,
1708 motionEntry->downTime, firstMotionSample->eventTime,
1709 motionEntry->pointerCount, motionEntry->pointerIds,
1710 firstMotionSample->pointerCoords);
1711
1712 if (status) {
1713 LOGE("channel '%s' ~ Could not publish motion event, "
1714 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001715 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001716 return;
1717 }
1718
1719 // Append additional motion samples.
1720 MotionSample* nextMotionSample = firstMotionSample->next;
1721 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1722 status = connection->inputPublisher.appendMotionSample(
1723 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1724 if (status == NO_MEMORY) {
1725#if DEBUG_DISPATCH_CYCLE
1726 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1727 "be sent in the next dispatch cycle.",
1728 connection->getInputChannelName());
1729#endif
1730 break;
1731 }
1732 if (status != OK) {
1733 LOGE("channel '%s' ~ Could not append motion sample "
1734 "for a reason other than out of memory, status=%d",
1735 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001736 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001737 return;
1738 }
1739 }
1740
1741 // Remember the next motion sample that we could not dispatch, in case we ran out
1742 // of space in the shared memory buffer.
1743 dispatchEntry->tailMotionSample = nextMotionSample;
1744 break;
1745 }
1746
1747 default: {
1748 assert(false);
1749 }
1750 }
1751
1752 // Send the dispatch signal.
1753 status = connection->inputPublisher.sendDispatchSignal();
1754 if (status) {
1755 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1756 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001757 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001758 return;
1759 }
1760
1761 // Record information about the newly started dispatch cycle.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001762 connection->lastEventTime = eventEntry->eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07001763 connection->lastDispatchTime = currentTime;
1764
Jeff Browne839a582010-04-22 18:58:52 -07001765 // Notify other system components.
1766 onDispatchCycleStartedLocked(currentTime, connection);
1767}
1768
Jeff Brown51d45a72010-06-17 20:52:56 -07001769void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1770 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001771#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001772 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -07001773 "%01.1fms since dispatch",
1774 connection->getInputChannelName(),
1775 connection->getEventLatencyMillis(currentTime),
1776 connection->getDispatchLatencyMillis(currentTime));
1777#endif
1778
Jeff Brown54bc2812010-06-15 01:31:58 -07001779 if (connection->status == Connection::STATUS_BROKEN
1780 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001781 return;
1782 }
1783
Jeff Brown53a415e2010-09-15 15:18:56 -07001784 // Notify other system components.
1785 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001786
1787 // Reset the publisher since the event has been consumed.
1788 // We do this now so that the publisher can release some of its internal resources
1789 // while waiting for the next dispatch cycle to begin.
1790 status_t status = connection->inputPublisher.reset();
1791 if (status) {
1792 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1793 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001794 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001795 return;
1796 }
1797
Jeff Browna665ca82010-09-08 11:49:43 -07001798 startNextDispatchCycleLocked(currentTime, connection);
1799}
1800
1801void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1802 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001803 // Start the next dispatch cycle for this connection.
1804 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001805 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001806 if (dispatchEntry->inProgress) {
1807 // Finish or resume current event in progress.
1808 if (dispatchEntry->tailMotionSample) {
1809 // We have a tail of undispatched motion samples.
1810 // Reuse the same DispatchEntry and start a new cycle.
1811 dispatchEntry->inProgress = false;
1812 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1813 dispatchEntry->tailMotionSample = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07001814 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001815 return;
1816 }
1817 // Finished.
1818 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001819 if (dispatchEntry->hasForegroundTarget()) {
1820 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001821 }
Jeff Browne839a582010-04-22 18:58:52 -07001822 mAllocator.releaseDispatchEntry(dispatchEntry);
1823 } else {
1824 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown53a415e2010-09-15 15:18:56 -07001825 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001826 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001827 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001828 return;
1829 }
1830 }
1831
1832 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001833 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001834}
1835
Jeff Brown90f0cee2010-10-08 22:31:17 -07001836void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1837 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001838#if DEBUG_DISPATCH_CYCLE
Jeff Brown90f0cee2010-10-08 22:31:17 -07001839 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001840 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001841#endif
1842
Jeff Browna665ca82010-09-08 11:49:43 -07001843 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001844 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001845
Jeff Brown90f0cee2010-10-08 22:31:17 -07001846 // The connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001847 // Ignore already broken or zombie connections.
Jeff Brown90f0cee2010-10-08 22:31:17 -07001848 if (connection->status == Connection::STATUS_NORMAL) {
1849 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001850
Jeff Brown90f0cee2010-10-08 22:31:17 -07001851 // Notify other system components.
1852 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001853 }
Jeff Browne839a582010-04-22 18:58:52 -07001854}
1855
Jeff Brown53a415e2010-09-15 15:18:56 -07001856void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1857 while (! connection->outboundQueue.isEmpty()) {
1858 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1859 if (dispatchEntry->hasForegroundTarget()) {
1860 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001861 }
1862 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001863 }
1864
Jeff Brown53a415e2010-09-15 15:18:56 -07001865 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001866}
1867
Jeff Brown59abe7e2010-09-13 23:17:30 -07001868int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-04-22 18:58:52 -07001869 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1870
1871 { // acquire lock
1872 AutoMutex _l(d->mLock);
1873
1874 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1875 if (connectionIndex < 0) {
1876 LOGE("Received spurious receive callback for unknown input channel. "
1877 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001878 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001879 }
1880
Jeff Brown51d45a72010-06-17 20:52:56 -07001881 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001882
1883 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001884 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-04-22 18:58:52 -07001885 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1886 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001887 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001888 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001889 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001890 }
1891
Jeff Brown59abe7e2010-09-13 23:17:30 -07001892 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001893 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1894 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001895 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001896 }
1897
1898 status_t status = connection->inputPublisher.receiveFinishedSignal();
1899 if (status) {
1900 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1901 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001902 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001903 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001904 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001905 }
1906
Jeff Brown51d45a72010-06-17 20:52:56 -07001907 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001908 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001909 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001910 } // release lock
1911}
1912
Jeff Brown90f0cee2010-10-08 22:31:17 -07001913void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1914 InputState::CancelationOptions options, const char* reason) {
1915 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1916 synthesizeCancelationEventsForConnectionLocked(
1917 mConnectionsByReceiveFd.valueAt(i), options, reason);
1918 }
1919}
1920
1921void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1922 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1923 const char* reason) {
1924 ssize_t index = getConnectionIndexLocked(channel);
1925 if (index >= 0) {
1926 synthesizeCancelationEventsForConnectionLocked(
1927 mConnectionsByReceiveFd.valueAt(index), options, reason);
1928 }
1929}
1930
1931void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1932 const sp<Connection>& connection, InputState::CancelationOptions options,
1933 const char* reason) {
1934 nsecs_t currentTime = now();
1935
1936 mTempCancelationEvents.clear();
1937 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1938 mTempCancelationEvents, options);
1939
1940 if (! mTempCancelationEvents.isEmpty()
1941 && connection->status != Connection::STATUS_BROKEN) {
1942#if DEBUG_OUTBOUND_EVENT_DETAILS
1943 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1944 "with reality: %s, options=%d.",
1945 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1946#endif
1947 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1948 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1949 switch (cancelationEventEntry->type) {
1950 case EventEntry::TYPE_KEY:
1951 logOutboundKeyDetailsLocked("cancel - ",
1952 static_cast<KeyEntry*>(cancelationEventEntry));
1953 break;
1954 case EventEntry::TYPE_MOTION:
1955 logOutboundMotionDetailsLocked("cancel - ",
1956 static_cast<MotionEntry*>(cancelationEventEntry));
1957 break;
1958 }
1959
1960 int32_t xOffset, yOffset;
1961 const InputWindow* window = getWindowLocked(connection->inputChannel);
1962 if (window) {
1963 xOffset = -window->frameLeft;
1964 yOffset = -window->frameTop;
1965 } else {
1966 xOffset = 0;
1967 yOffset = 0;
1968 }
1969
1970 DispatchEntry* cancelationDispatchEntry =
1971 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1972 0, xOffset, yOffset);
1973 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1974
1975 mAllocator.releaseEventEntry(cancelationEventEntry);
1976 }
1977
1978 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1979 startDispatchCycleLocked(currentTime, connection);
1980 }
1981 }
1982}
1983
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001984InputDispatcher::MotionEntry*
1985InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1986 assert(pointerIds.value != 0);
1987
1988 uint32_t splitPointerIndexMap[MAX_POINTERS];
1989 int32_t splitPointerIds[MAX_POINTERS];
1990 PointerCoords splitPointerCoords[MAX_POINTERS];
1991
1992 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1993 uint32_t splitPointerCount = 0;
1994
1995 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1996 originalPointerIndex++) {
1997 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1998 if (pointerIds.hasBit(pointerId)) {
1999 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2000 splitPointerIds[splitPointerCount] = pointerId;
2001 splitPointerCoords[splitPointerCount] =
2002 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
2003 splitPointerCount += 1;
2004 }
2005 }
2006 assert(splitPointerCount == pointerIds.count());
2007
2008 int32_t action = originalMotionEntry->action;
2009 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2010 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2011 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2012 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2013 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2014 if (pointerIds.hasBit(pointerId)) {
2015 if (pointerIds.count() == 1) {
2016 // The first/last pointer went down/up.
2017 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2018 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brownffb16d62010-09-27 16:35:11 -07002019 } else {
2020 // A secondary pointer went down/up.
2021 uint32_t splitPointerIndex = 0;
2022 while (pointerId != splitPointerIds[splitPointerIndex]) {
2023 splitPointerIndex += 1;
2024 }
2025 action = maskedAction | (splitPointerIndex
2026 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002027 }
2028 } else {
2029 // An unrelated pointer changed.
2030 action = AMOTION_EVENT_ACTION_MOVE;
2031 }
2032 }
2033
2034 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2035 originalMotionEntry->eventTime,
2036 originalMotionEntry->deviceId,
2037 originalMotionEntry->source,
2038 originalMotionEntry->policyFlags,
2039 action,
2040 originalMotionEntry->flags,
2041 originalMotionEntry->metaState,
2042 originalMotionEntry->edgeFlags,
2043 originalMotionEntry->xPrecision,
2044 originalMotionEntry->yPrecision,
2045 originalMotionEntry->downTime,
2046 splitPointerCount, splitPointerIds, splitPointerCoords);
2047
2048 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2049 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2050 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2051 splitPointerIndex++) {
2052 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2053 splitPointerCoords[splitPointerIndex] =
2054 originalMotionSample->pointerCoords[originalPointerIndex];
2055 }
2056
2057 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2058 splitPointerCoords);
2059 }
2060
2061 return splitMotionEntry;
2062}
2063
Jeff Brown54bc2812010-06-15 01:31:58 -07002064void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002065#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -07002066 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07002067#endif
2068
Jeff Browna665ca82010-09-08 11:49:43 -07002069 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002070 { // acquire lock
2071 AutoMutex _l(mLock);
2072
Jeff Brown51d45a72010-06-17 20:52:56 -07002073 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browna665ca82010-09-08 11:49:43 -07002074 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002075 } // release lock
2076
Jeff Browna665ca82010-09-08 11:49:43 -07002077 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002078 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002079 }
2080}
2081
Jeff Brown5c1ed842010-07-14 18:48:53 -07002082void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -07002083 uint32_t policyFlags, int32_t action, int32_t flags,
2084 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2085#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002086 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07002087 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07002088 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -07002089 keyCode, scanCode, metaState, downTime);
2090#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002091 if (! validateKeyEvent(action)) {
2092 return;
2093 }
Jeff Browne839a582010-04-22 18:58:52 -07002094
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002095 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002096 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2097 keyCode, scanCode, /*byref*/ policyFlags);
2098
Jeff Browna665ca82010-09-08 11:49:43 -07002099 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002100 { // acquire lock
2101 AutoMutex _l(mLock);
2102
Jeff Brown51d45a72010-06-17 20:52:56 -07002103 int32_t repeatCount = 0;
2104 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002105 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07002106 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07002107
Jeff Browna665ca82010-09-08 11:49:43 -07002108 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002109 } // release lock
2110
Jeff Browna665ca82010-09-08 11:49:43 -07002111 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002112 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002113 }
2114}
2115
Jeff Brown5c1ed842010-07-14 18:48:53 -07002116void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002117 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002118 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2119 float xPrecision, float yPrecision, nsecs_t downTime) {
2120#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002121 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002122 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2123 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2124 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002125 xPrecision, yPrecision, downTime);
2126 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07002127 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002128 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07002129 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07002130 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-08-30 03:02:23 -07002131 pointerCoords[i].pressure, pointerCoords[i].size,
2132 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2133 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2134 pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -07002135 }
2136#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002137 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2138 return;
2139 }
Jeff Browne839a582010-04-22 18:58:52 -07002140
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002141 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002142 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2143
Jeff Browna665ca82010-09-08 11:49:43 -07002144 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002145 { // acquire lock
2146 AutoMutex _l(mLock);
2147
2148 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07002149 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07002150 // BATCHING CASE
2151 //
2152 // Try to append a move sample to the tail of the inbound queue for this device.
2153 // Give up if we encounter a non-move motion event for this device since that
2154 // means we cannot append any new samples until a new motion event has started.
Jeff Browna665ca82010-09-08 11:49:43 -07002155 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2156 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07002157 if (entry->type != EventEntry::TYPE_MOTION) {
2158 // Keep looking for motion events.
2159 continue;
2160 }
2161
2162 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2163 if (motionEntry->deviceId != deviceId) {
2164 // Keep looking for this device.
2165 continue;
2166 }
2167
Jeff Brown5c1ed842010-07-14 18:48:53 -07002168 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07002169 || motionEntry->pointerCount != pointerCount
2170 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07002171 // Last motion event in the queue for this device is not compatible for
2172 // appending new samples. Stop here.
2173 goto NoBatchingOrStreaming;
2174 }
2175
2176 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07002177 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07002178 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002179#if DEBUG_BATCHING
2180 LOGD("Appended motion sample onto batch for most recent "
2181 "motion event for this device in the inbound queue.");
2182#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07002183 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002184 }
2185
2186 // STREAMING CASE
2187 //
2188 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07002189 // Search the outbound queue for the current foreground targets to find a dispatched
2190 // motion event that is still in progress. If found, then, appen the new sample to
2191 // that event and push it out to all current targets. The logic in
2192 // prepareDispatchCycleLocked takes care of the case where some targets may
2193 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown54bc2812010-06-15 01:31:58 -07002194 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002195 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2196 const InputTarget& inputTarget = mCurrentInputTargets[i];
2197 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2198 // Skip non-foreground targets. We only want to stream if there is at
2199 // least one foreground target whose dispatch is still in progress.
2200 continue;
Jeff Browne839a582010-04-22 18:58:52 -07002201 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002202
2203 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2204 if (connectionIndex < 0) {
2205 // Connection must no longer be valid.
2206 continue;
2207 }
2208
2209 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2210 if (connection->outboundQueue.isEmpty()) {
2211 // This foreground target has an empty outbound queue.
2212 continue;
2213 }
2214
2215 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2216 if (! dispatchEntry->inProgress
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002217 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2218 || dispatchEntry->isSplit()) {
2219 // No motion event is being dispatched, or it is being split across
2220 // windows in which case we cannot stream.
Jeff Brown53a415e2010-09-15 15:18:56 -07002221 continue;
2222 }
2223
2224 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2225 dispatchEntry->eventEntry);
2226 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2227 || motionEntry->deviceId != deviceId
2228 || motionEntry->pointerCount != pointerCount
2229 || motionEntry->isInjected()) {
2230 // The motion event is not compatible with this move.
2231 continue;
2232 }
2233
2234 // Hurray! This foreground target is currently dispatching a move event
2235 // that we can stream onto. Append the motion sample and resume dispatch.
2236 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2237#if DEBUG_BATCHING
2238 LOGD("Appended motion sample onto batch for most recently dispatched "
2239 "motion event for this device in the outbound queues. "
2240 "Attempting to stream the motion sample.");
2241#endif
2242 nsecs_t currentTime = now();
2243 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2244 true /*resumeWithAppendedMotionSample*/);
2245
2246 runCommandsLockedInterruptible();
2247 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002248 }
2249 }
2250
2251NoBatchingOrStreaming:;
2252 }
2253
2254 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07002255 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002256 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002257 xPrecision, yPrecision, downTime,
2258 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002259
Jeff Browna665ca82010-09-08 11:49:43 -07002260 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002261 } // release lock
2262
Jeff Browna665ca82010-09-08 11:49:43 -07002263 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002264 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002265 }
2266}
2267
Jeff Brown90f0cee2010-10-08 22:31:17 -07002268void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2269 uint32_t policyFlags) {
2270#if DEBUG_INBOUND_EVENT_DETAILS
2271 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2272 switchCode, switchValue, policyFlags);
2273#endif
2274
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002275 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002276 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2277}
2278
Jeff Brown51d45a72010-06-17 20:52:56 -07002279int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07002280 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002281#if DEBUG_INBOUND_EVENT_DETAILS
2282 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002283 "syncMode=%d, timeoutMillis=%d",
2284 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07002285#endif
2286
2287 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002288
2289 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2290 if (hasInjectionPermission(injectorPid, injectorUid)) {
2291 policyFlags |= POLICY_FLAG_TRUSTED;
2292 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002293
Jeff Brown90f0cee2010-10-08 22:31:17 -07002294 EventEntry* injectedEntry;
2295 switch (event->getType()) {
2296 case AINPUT_EVENT_TYPE_KEY: {
2297 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2298 int32_t action = keyEvent->getAction();
2299 if (! validateKeyEvent(action)) {
Jeff Browna665ca82010-09-08 11:49:43 -07002300 return INPUT_EVENT_INJECTION_FAILED;
2301 }
2302
Jeff Brown90f0cee2010-10-08 22:31:17 -07002303 nsecs_t eventTime = keyEvent->getEventTime();
2304 int32_t deviceId = keyEvent->getDeviceId();
2305 int32_t flags = keyEvent->getFlags();
2306 int32_t keyCode = keyEvent->getKeyCode();
2307 int32_t scanCode = keyEvent->getScanCode();
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002308 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2309 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002310
Jeff Brown90f0cee2010-10-08 22:31:17 -07002311 mLock.lock();
2312 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2313 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2314 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2315 break;
2316 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002317
Jeff Brown90f0cee2010-10-08 22:31:17 -07002318 case AINPUT_EVENT_TYPE_MOTION: {
2319 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2320 int32_t action = motionEvent->getAction();
2321 size_t pointerCount = motionEvent->getPointerCount();
2322 const int32_t* pointerIds = motionEvent->getPointerIds();
2323 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2324 return INPUT_EVENT_INJECTION_FAILED;
2325 }
2326
2327 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002328 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002329
2330 mLock.lock();
2331 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2332 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2333 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2334 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2335 action, motionEvent->getFlags(),
2336 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2337 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2338 motionEvent->getDownTime(), uint32_t(pointerCount),
2339 pointerIds, samplePointerCoords);
2340 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2341 sampleEventTimes += 1;
2342 samplePointerCoords += pointerCount;
2343 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2344 }
2345 injectedEntry = motionEntry;
2346 break;
2347 }
2348
2349 default:
2350 LOGW("Cannot inject event of type %d", event->getType());
2351 return INPUT_EVENT_INJECTION_FAILED;
2352 }
2353
2354 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2355 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2356 injectionState->injectionIsAsync = true;
2357 }
2358
2359 injectionState->refCount += 1;
2360 injectedEntry->injectionState = injectionState;
2361
2362 bool needWake = enqueueInboundEventLocked(injectedEntry);
2363 mLock.unlock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002364
Jeff Browna665ca82010-09-08 11:49:43 -07002365 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002366 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07002367 }
2368
2369 int32_t injectionResult;
2370 { // acquire lock
2371 AutoMutex _l(mLock);
2372
Jeff Brownf67c53e2010-07-28 15:48:59 -07002373 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2374 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2375 } else {
2376 for (;;) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002377 injectionResult = injectionState->injectionResult;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002378 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2379 break;
2380 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002381
Jeff Brown51d45a72010-06-17 20:52:56 -07002382 nsecs_t remainingTimeout = endTime - now();
2383 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002384#if DEBUG_INJECTION
2385 LOGD("injectInputEvent - Timed out waiting for injection result "
2386 "to become available.");
2387#endif
Jeff Brown51d45a72010-06-17 20:52:56 -07002388 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2389 break;
2390 }
2391
Jeff Brownf67c53e2010-07-28 15:48:59 -07002392 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2393 }
2394
2395 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2396 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002397 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002398#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002399 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002400 injectionState->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002401#endif
2402 nsecs_t remainingTimeout = endTime - now();
2403 if (remainingTimeout <= 0) {
2404#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002405 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002406 "dispatches to finish.");
2407#endif
2408 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2409 break;
2410 }
2411
2412 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2413 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002414 }
2415 }
2416
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002417 mAllocator.releaseInjectionState(injectionState);
Jeff Brown51d45a72010-06-17 20:52:56 -07002418 } // release lock
2419
Jeff Brownf67c53e2010-07-28 15:48:59 -07002420#if DEBUG_INJECTION
2421 LOGD("injectInputEvent - Finished with result %d. "
2422 "injectorPid=%d, injectorUid=%d",
2423 injectionResult, injectorPid, injectorUid);
2424#endif
2425
Jeff Brown51d45a72010-06-17 20:52:56 -07002426 return injectionResult;
2427}
2428
Jeff Brown90f0cee2010-10-08 22:31:17 -07002429bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2430 return injectorUid == 0
2431 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2432}
2433
Jeff Brown51d45a72010-06-17 20:52:56 -07002434void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002435 InjectionState* injectionState = entry->injectionState;
2436 if (injectionState) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002437#if DEBUG_INJECTION
2438 LOGD("Setting input event injection result to %d. "
2439 "injectorPid=%d, injectorUid=%d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002440 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002441#endif
2442
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002443 if (injectionState->injectionIsAsync) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002444 // Log the outcome since the injector did not wait for the injection result.
2445 switch (injectionResult) {
2446 case INPUT_EVENT_INJECTION_SUCCEEDED:
2447 LOGV("Asynchronous input event injection succeeded.");
2448 break;
2449 case INPUT_EVENT_INJECTION_FAILED:
2450 LOGW("Asynchronous input event injection failed.");
2451 break;
2452 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2453 LOGW("Asynchronous input event injection permission denied.");
2454 break;
2455 case INPUT_EVENT_INJECTION_TIMED_OUT:
2456 LOGW("Asynchronous input event injection timed out.");
2457 break;
2458 }
2459 }
2460
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002461 injectionState->injectionResult = injectionResult;
Jeff Brown51d45a72010-06-17 20:52:56 -07002462 mInjectionResultAvailableCondition.broadcast();
2463 }
2464}
2465
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002466void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2467 InjectionState* injectionState = entry->injectionState;
2468 if (injectionState) {
2469 injectionState->pendingForegroundDispatches += 1;
2470 }
2471}
2472
Jeff Brown53a415e2010-09-15 15:18:56 -07002473void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002474 InjectionState* injectionState = entry->injectionState;
2475 if (injectionState) {
2476 injectionState->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002477
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002478 if (injectionState->pendingForegroundDispatches == 0) {
2479 mInjectionSyncFinishedCondition.broadcast();
2480 }
Jeff Browna665ca82010-09-08 11:49:43 -07002481 }
2482}
2483
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002484const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2485 for (size_t i = 0; i < mWindows.size(); i++) {
2486 const InputWindow* window = & mWindows[i];
2487 if (window->inputChannel == inputChannel) {
2488 return window;
2489 }
2490 }
2491 return NULL;
2492}
2493
Jeff Browna665ca82010-09-08 11:49:43 -07002494void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2495#if DEBUG_FOCUS
2496 LOGD("setInputWindows");
2497#endif
2498 { // acquire lock
2499 AutoMutex _l(mLock);
2500
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002501 // Clear old window pointers.
Jeff Brown90f0cee2010-10-08 22:31:17 -07002502 sp<InputChannel> oldFocusedWindowChannel;
2503 if (mFocusedWindow) {
2504 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2505 mFocusedWindow = NULL;
2506 }
2507
Jeff Browna665ca82010-09-08 11:49:43 -07002508 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002509
2510 // Loop over new windows and rebuild the necessary window pointers for
2511 // tracking focus and touch.
Jeff Browna665ca82010-09-08 11:49:43 -07002512 mWindows.appendVector(inputWindows);
2513
2514 size_t numWindows = mWindows.size();
2515 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002516 const InputWindow* window = & mWindows.itemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07002517 if (window->hasFocus) {
2518 mFocusedWindow = window;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002519 break;
Jeff Browna665ca82010-09-08 11:49:43 -07002520 }
2521 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002522
Jeff Brown90f0cee2010-10-08 22:31:17 -07002523 if (oldFocusedWindowChannel != NULL) {
2524 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2525#if DEBUG_FOCUS
2526 LOGD("Focus left window: %s",
2527 oldFocusedWindowChannel->getName().string());
2528#endif
2529 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2530 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2531 oldFocusedWindowChannel.clear();
2532 }
2533 }
2534 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2535#if DEBUG_FOCUS
2536 LOGD("Focus entered window: %s",
2537 mFocusedWindow->inputChannel->getName().string());
2538#endif
2539 }
2540
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002541 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2542 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2543 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2544 if (window) {
2545 touchedWindow.window = window;
2546 i += 1;
2547 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -07002548#if DEBUG_FOCUS
2549 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2550#endif
Jeff Brown90f0cee2010-10-08 22:31:17 -07002551 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2552 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownb13d7b52010-10-15 16:20:51 -07002553 mTouchState.windows.removeAt(i);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002554 }
2555 }
Jeff Browna665ca82010-09-08 11:49:43 -07002556
Jeff Browna665ca82010-09-08 11:49:43 -07002557#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002558 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002559#endif
2560 } // release lock
2561
2562 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002563 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002564}
2565
2566void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2567#if DEBUG_FOCUS
2568 LOGD("setFocusedApplication");
2569#endif
2570 { // acquire lock
2571 AutoMutex _l(mLock);
2572
2573 releaseFocusedApplicationLocked();
2574
2575 if (inputApplication) {
2576 mFocusedApplicationStorage = *inputApplication;
2577 mFocusedApplication = & mFocusedApplicationStorage;
2578 }
2579
2580#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002581 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002582#endif
2583 } // release lock
2584
2585 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002586 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002587}
2588
2589void InputDispatcher::releaseFocusedApplicationLocked() {
2590 if (mFocusedApplication) {
2591 mFocusedApplication = NULL;
2592 mFocusedApplicationStorage.handle.clear();
2593 }
2594}
2595
2596void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2597#if DEBUG_FOCUS
2598 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2599#endif
2600
2601 bool changed;
2602 { // acquire lock
2603 AutoMutex _l(mLock);
2604
2605 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brownfef5b042010-10-27 18:43:51 -07002606 if (mDispatchFrozen && !frozen) {
Jeff Browna665ca82010-09-08 11:49:43 -07002607 resetANRTimeoutsLocked();
2608 }
2609
Jeff Brownfef5b042010-10-27 18:43:51 -07002610 if (mDispatchEnabled && !enabled) {
2611 resetAndDropEverythingLocked("dispatcher is being disabled");
2612 }
2613
Jeff Browna665ca82010-09-08 11:49:43 -07002614 mDispatchEnabled = enabled;
2615 mDispatchFrozen = frozen;
2616 changed = true;
2617 } else {
2618 changed = false;
2619 }
2620
2621#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002622 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002623#endif
2624 } // release lock
2625
2626 if (changed) {
2627 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002628 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002629 }
2630}
2631
Jeff Brownfef5b042010-10-27 18:43:51 -07002632void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2633#if DEBUG_FOCUS
2634 LOGD("Resetting and dropping all events (%s).", reason);
2635#endif
2636
2637 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2638
2639 resetKeyRepeatLocked();
2640 releasePendingEventLocked();
2641 drainInboundQueueLocked();
2642 resetTargetsLocked();
2643
2644 mTouchState.reset();
2645}
2646
Jeff Browna665ca82010-09-08 11:49:43 -07002647void InputDispatcher::logDispatchStateLocked() {
2648 String8 dump;
2649 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002650
2651 char* text = dump.lockBuffer(dump.size());
2652 char* start = text;
2653 while (*start != '\0') {
2654 char* end = strchr(start, '\n');
2655 if (*end == '\n') {
2656 *(end++) = '\0';
2657 }
2658 LOGD("%s", start);
2659 start = end;
2660 }
Jeff Browna665ca82010-09-08 11:49:43 -07002661}
2662
2663void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002664 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2665 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002666
2667 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002668 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002669 mFocusedApplication->name.string(),
2670 mFocusedApplication->dispatchingTimeout / 1000000.0);
2671 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002672 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002673 }
Jeff Brown2806e382010-10-01 17:46:21 -07002674 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002675 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-10-01 17:46:21 -07002676
2677 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2678 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2679 if (!mTouchState.windows.isEmpty()) {
2680 dump.append(INDENT "TouchedWindows:\n");
2681 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2682 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2683 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2684 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2685 touchedWindow.targetFlags);
2686 }
2687 } else {
2688 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002689 }
2690
Jeff Brown2806e382010-10-01 17:46:21 -07002691 if (!mWindows.isEmpty()) {
2692 dump.append(INDENT "Windows:\n");
2693 for (size_t i = 0; i < mWindows.size(); i++) {
2694 const InputWindow& window = mWindows[i];
2695 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2696 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2697 "frame=[%d,%d][%d,%d], "
2698 "visibleFrame=[%d,%d][%d,%d], "
2699 "touchableArea=[%d,%d][%d,%d], "
2700 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2701 i, window.name.string(),
2702 toString(window.paused),
2703 toString(window.hasFocus),
2704 toString(window.hasWallpaper),
2705 toString(window.visible),
2706 toString(window.canReceiveKeys),
2707 window.layoutParamsFlags, window.layoutParamsType,
2708 window.layer,
2709 window.frameLeft, window.frameTop,
2710 window.frameRight, window.frameBottom,
2711 window.visibleFrameLeft, window.visibleFrameTop,
2712 window.visibleFrameRight, window.visibleFrameBottom,
2713 window.touchableAreaLeft, window.touchableAreaTop,
2714 window.touchableAreaRight, window.touchableAreaBottom,
2715 window.ownerPid, window.ownerUid,
2716 window.dispatchingTimeout / 1000000.0);
2717 }
2718 } else {
2719 dump.append(INDENT "Windows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002720 }
2721
Jeff Brown2806e382010-10-01 17:46:21 -07002722 if (!mMonitoringChannels.isEmpty()) {
2723 dump.append(INDENT "MonitoringChannels:\n");
2724 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2725 const sp<InputChannel>& channel = mMonitoringChannels[i];
2726 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2727 }
2728 } else {
2729 dump.append(INDENT "MonitoringChannels: <none>\n");
2730 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002731
Jeff Brown2806e382010-10-01 17:46:21 -07002732 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2733
2734 if (!mActiveConnections.isEmpty()) {
2735 dump.append(INDENT "ActiveConnections:\n");
2736 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2737 const Connection* connection = mActiveConnections[i];
2738 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
Jeff Brown90f0cee2010-10-08 22:31:17 -07002739 "inputState.isNeutral=%s\n",
Jeff Brown2806e382010-10-01 17:46:21 -07002740 i, connection->getInputChannelName(), connection->getStatusLabel(),
2741 connection->outboundQueue.count(),
Jeff Brown90f0cee2010-10-08 22:31:17 -07002742 toString(connection->inputState.isNeutral()));
Jeff Brown2806e382010-10-01 17:46:21 -07002743 }
2744 } else {
2745 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002746 }
2747
2748 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002749 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002750 (mAppSwitchDueTime - now()) / 1000000.0);
2751 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002752 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002753 }
2754}
2755
2756status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002757#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002758 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2759 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002760#endif
2761
Jeff Browne839a582010-04-22 18:58:52 -07002762 { // acquire lock
2763 AutoMutex _l(mLock);
2764
Jeff Brown53a415e2010-09-15 15:18:56 -07002765 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002766 LOGW("Attempted to register already registered input channel '%s'",
2767 inputChannel->getName().string());
2768 return BAD_VALUE;
2769 }
2770
2771 sp<Connection> connection = new Connection(inputChannel);
2772 status_t status = connection->initialize();
2773 if (status) {
2774 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2775 inputChannel->getName().string(), status);
2776 return status;
2777 }
2778
Jeff Brown0cacb872010-08-17 15:59:26 -07002779 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002780 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002781
Jeff Browna665ca82010-09-08 11:49:43 -07002782 if (monitor) {
2783 mMonitoringChannels.push(inputChannel);
2784 }
2785
Jeff Brown59abe7e2010-09-13 23:17:30 -07002786 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002787
Jeff Brown54bc2812010-06-15 01:31:58 -07002788 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002789 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002790 return OK;
2791}
2792
2793status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002794#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002795 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002796#endif
2797
Jeff Browne839a582010-04-22 18:58:52 -07002798 { // acquire lock
2799 AutoMutex _l(mLock);
2800
Jeff Brown53a415e2010-09-15 15:18:56 -07002801 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002802 if (connectionIndex < 0) {
2803 LOGW("Attempted to unregister already unregistered input channel '%s'",
2804 inputChannel->getName().string());
2805 return BAD_VALUE;
2806 }
2807
2808 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2809 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2810
2811 connection->status = Connection::STATUS_ZOMBIE;
2812
Jeff Browna665ca82010-09-08 11:49:43 -07002813 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2814 if (mMonitoringChannels[i] == inputChannel) {
2815 mMonitoringChannels.removeAt(i);
2816 break;
2817 }
2818 }
2819
Jeff Brown59abe7e2010-09-13 23:17:30 -07002820 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002821
Jeff Brown51d45a72010-06-17 20:52:56 -07002822 nsecs_t currentTime = now();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002823 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002824
2825 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002826 } // release lock
2827
Jeff Browne839a582010-04-22 18:58:52 -07002828 // Wake the poll loop because removing the connection may have changed the current
2829 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002830 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002831 return OK;
2832}
2833
Jeff Brown53a415e2010-09-15 15:18:56 -07002834ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002835 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2836 if (connectionIndex >= 0) {
2837 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2838 if (connection->inputChannel.get() == inputChannel.get()) {
2839 return connectionIndex;
2840 }
2841 }
2842
2843 return -1;
2844}
2845
Jeff Browne839a582010-04-22 18:58:52 -07002846void InputDispatcher::activateConnectionLocked(Connection* connection) {
2847 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2848 if (mActiveConnections.itemAt(i) == connection) {
2849 return;
2850 }
2851 }
2852 mActiveConnections.add(connection);
2853}
2854
2855void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2856 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2857 if (mActiveConnections.itemAt(i) == connection) {
2858 mActiveConnections.removeAt(i);
2859 return;
2860 }
2861 }
2862}
2863
Jeff Brown54bc2812010-06-15 01:31:58 -07002864void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002865 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002866}
2867
Jeff Brown54bc2812010-06-15 01:31:58 -07002868void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002869 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002870}
2871
Jeff Brown54bc2812010-06-15 01:31:58 -07002872void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002873 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002874 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2875 connection->getInputChannelName());
2876
Jeff Brown54bc2812010-06-15 01:31:58 -07002877 CommandEntry* commandEntry = postCommandLocked(
2878 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002879 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002880}
2881
Jeff Brown53a415e2010-09-15 15:18:56 -07002882void InputDispatcher::onANRLocked(
2883 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2884 nsecs_t eventTime, nsecs_t waitStartTime) {
2885 LOGI("Application is not responding: %s. "
2886 "%01.1fms since event, %01.1fms since wait started",
2887 getApplicationWindowLabelLocked(application, window).string(),
2888 (currentTime - eventTime) / 1000000.0,
2889 (currentTime - waitStartTime) / 1000000.0);
2890
2891 CommandEntry* commandEntry = postCommandLocked(
2892 & InputDispatcher::doNotifyANRLockedInterruptible);
2893 if (application) {
2894 commandEntry->inputApplicationHandle = application->handle;
2895 }
2896 if (window) {
2897 commandEntry->inputChannel = window->inputChannel;
2898 }
2899}
2900
Jeff Browna665ca82010-09-08 11:49:43 -07002901void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2902 CommandEntry* commandEntry) {
2903 mLock.unlock();
2904
2905 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2906
2907 mLock.lock();
2908}
2909
Jeff Brown54bc2812010-06-15 01:31:58 -07002910void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2911 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002912 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002913
Jeff Brown51d45a72010-06-17 20:52:56 -07002914 if (connection->status != Connection::STATUS_ZOMBIE) {
2915 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002916
Jeff Brown51d45a72010-06-17 20:52:56 -07002917 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2918
2919 mLock.lock();
2920 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002921}
2922
Jeff Brown53a415e2010-09-15 15:18:56 -07002923void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002924 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002925 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002926
Jeff Brown53a415e2010-09-15 15:18:56 -07002927 nsecs_t newTimeout = mPolicy->notifyANR(
2928 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002929
Jeff Brown53a415e2010-09-15 15:18:56 -07002930 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002931
Jeff Brown53a415e2010-09-15 15:18:56 -07002932 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002933}
2934
Jeff Browna665ca82010-09-08 11:49:43 -07002935void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2936 CommandEntry* commandEntry) {
2937 KeyEntry* entry = commandEntry->keyEntry;
2938 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2939 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2940 entry->downTime, entry->eventTime);
2941
2942 mLock.unlock();
2943
2944 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2945 & mReusableKeyEvent, entry->policyFlags);
2946
2947 mLock.lock();
2948
2949 entry->interceptKeyResult = consumed
2950 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2951 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2952 mAllocator.releaseKeyEntry(entry);
2953}
2954
2955void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2956 mLock.unlock();
2957
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002958 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07002959
2960 mLock.lock();
2961}
2962
Jeff Brown53a415e2010-09-15 15:18:56 -07002963void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
2964 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
2965 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07002966}
2967
2968void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002969 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002970 dumpDispatchStateLocked(dump);
2971}
2972
Jeff Brown54bc2812010-06-15 01:31:58 -07002973
Jeff Brown53a415e2010-09-15 15:18:56 -07002974// --- InputDispatcher::Queue ---
2975
2976template <typename T>
2977uint32_t InputDispatcher::Queue<T>::count() const {
2978 uint32_t result = 0;
2979 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
2980 result += 1;
2981 }
2982 return result;
2983}
2984
2985
Jeff Browne839a582010-04-22 18:58:52 -07002986// --- InputDispatcher::Allocator ---
2987
2988InputDispatcher::Allocator::Allocator() {
2989}
2990
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002991InputDispatcher::InjectionState*
2992InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
2993 InjectionState* injectionState = mInjectionStatePool.alloc();
2994 injectionState->refCount = 1;
2995 injectionState->injectorPid = injectorPid;
2996 injectionState->injectorUid = injectorUid;
2997 injectionState->injectionIsAsync = false;
2998 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
2999 injectionState->pendingForegroundDispatches = 0;
3000 return injectionState;
3001}
3002
Jeff Brown51d45a72010-06-17 20:52:56 -07003003void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brown90f0cee2010-10-08 22:31:17 -07003004 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown51d45a72010-06-17 20:52:56 -07003005 entry->type = type;
3006 entry->refCount = 1;
3007 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07003008 entry->eventTime = eventTime;
Jeff Brown90f0cee2010-10-08 22:31:17 -07003009 entry->policyFlags = policyFlags;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003010 entry->injectionState = NULL;
3011}
3012
3013void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3014 if (entry->injectionState) {
3015 releaseInjectionState(entry->injectionState);
3016 entry->injectionState = NULL;
3017 }
Jeff Brown51d45a72010-06-17 20:52:56 -07003018}
3019
Jeff Browne839a582010-04-22 18:58:52 -07003020InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07003021InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003022 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003023 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Browne839a582010-04-22 18:58:52 -07003024 return entry;
3025}
3026
Jeff Brown51d45a72010-06-17 20:52:56 -07003027InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07003028 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07003029 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3030 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003031 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003032 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003033
3034 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003035 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003036 entry->action = action;
3037 entry->flags = flags;
3038 entry->keyCode = keyCode;
3039 entry->scanCode = scanCode;
3040 entry->metaState = metaState;
3041 entry->repeatCount = repeatCount;
3042 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07003043 entry->syntheticRepeat = false;
3044 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07003045 return entry;
3046}
3047
Jeff Brown51d45a72010-06-17 20:52:56 -07003048InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07003049 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07003050 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3051 nsecs_t downTime, uint32_t pointerCount,
3052 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003053 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003054 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003055
3056 entry->eventTime = eventTime;
3057 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003058 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003059 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07003060 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07003061 entry->metaState = metaState;
3062 entry->edgeFlags = edgeFlags;
3063 entry->xPrecision = xPrecision;
3064 entry->yPrecision = yPrecision;
3065 entry->downTime = downTime;
3066 entry->pointerCount = pointerCount;
3067 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07003068 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07003069 entry->lastSample = & entry->firstSample;
3070 for (uint32_t i = 0; i < pointerCount; i++) {
3071 entry->pointerIds[i] = pointerIds[i];
3072 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3073 }
Jeff Browne839a582010-04-22 18:58:52 -07003074 return entry;
3075}
3076
3077InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07003078 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07003079 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07003080 DispatchEntry* entry = mDispatchEntryPool.alloc();
3081 entry->eventEntry = eventEntry;
3082 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07003083 entry->targetFlags = targetFlags;
3084 entry->xOffset = xOffset;
3085 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07003086 entry->inProgress = false;
3087 entry->headMotionSample = NULL;
3088 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07003089 return entry;
3090}
3091
Jeff Brown54bc2812010-06-15 01:31:58 -07003092InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3093 CommandEntry* entry = mCommandEntryPool.alloc();
3094 entry->command = command;
3095 return entry;
3096}
3097
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003098void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3099 injectionState->refCount -= 1;
3100 if (injectionState->refCount == 0) {
3101 mInjectionStatePool.free(injectionState);
3102 } else {
3103 assert(injectionState->refCount > 0);
3104 }
3105}
3106
Jeff Browne839a582010-04-22 18:58:52 -07003107void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3108 switch (entry->type) {
3109 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3110 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3111 break;
3112 case EventEntry::TYPE_KEY:
3113 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3114 break;
3115 case EventEntry::TYPE_MOTION:
3116 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3117 break;
3118 default:
3119 assert(false);
3120 break;
3121 }
3122}
3123
3124void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3125 ConfigurationChangedEntry* entry) {
3126 entry->refCount -= 1;
3127 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003128 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003129 mConfigurationChangeEntryPool.free(entry);
3130 } else {
3131 assert(entry->refCount > 0);
3132 }
3133}
3134
3135void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3136 entry->refCount -= 1;
3137 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003138 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003139 mKeyEntryPool.free(entry);
3140 } else {
3141 assert(entry->refCount > 0);
3142 }
3143}
3144
3145void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3146 entry->refCount -= 1;
3147 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003148 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -07003149 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3150 MotionSample* next = sample->next;
3151 mMotionSamplePool.free(sample);
3152 sample = next;
3153 }
Jeff Browne839a582010-04-22 18:58:52 -07003154 mMotionEntryPool.free(entry);
3155 } else {
3156 assert(entry->refCount > 0);
3157 }
3158}
3159
3160void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3161 releaseEventEntry(entry->eventEntry);
3162 mDispatchEntryPool.free(entry);
3163}
3164
Jeff Brown54bc2812010-06-15 01:31:58 -07003165void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3166 mCommandEntryPool.free(entry);
3167}
3168
Jeff Browne839a582010-04-22 18:58:52 -07003169void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003170 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003171 MotionSample* sample = mMotionSamplePool.alloc();
3172 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003173 uint32_t pointerCount = motionEntry->pointerCount;
3174 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07003175 sample->pointerCoords[i] = pointerCoords[i];
3176 }
3177
3178 sample->next = NULL;
3179 motionEntry->lastSample->next = sample;
3180 motionEntry->lastSample = sample;
3181}
3182
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003183void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3184 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003185
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003186 keyEntry->dispatchInProgress = false;
3187 keyEntry->syntheticRepeat = false;
3188 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003189}
3190
3191
Jeff Brown542412c2010-08-18 15:51:08 -07003192// --- InputDispatcher::MotionEntry ---
3193
3194uint32_t InputDispatcher::MotionEntry::countSamples() const {
3195 uint32_t count = 1;
3196 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3197 count += 1;
3198 }
3199 return count;
3200}
3201
Jeff Browna665ca82010-09-08 11:49:43 -07003202
3203// --- InputDispatcher::InputState ---
3204
Jeff Brown90f0cee2010-10-08 22:31:17 -07003205InputDispatcher::InputState::InputState() {
Jeff Browna665ca82010-09-08 11:49:43 -07003206}
3207
3208InputDispatcher::InputState::~InputState() {
3209}
3210
3211bool InputDispatcher::InputState::isNeutral() const {
3212 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3213}
3214
Jeff Browna665ca82010-09-08 11:49:43 -07003215InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3216 const EventEntry* entry) {
3217 switch (entry->type) {
3218 case EventEntry::TYPE_KEY:
3219 return trackKey(static_cast<const KeyEntry*>(entry));
3220
3221 case EventEntry::TYPE_MOTION:
3222 return trackMotion(static_cast<const MotionEntry*>(entry));
3223
3224 default:
3225 return CONSISTENT;
3226 }
3227}
3228
3229InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3230 const KeyEntry* entry) {
3231 int32_t action = entry->action;
3232 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3233 KeyMemento& memento = mKeyMementos.editItemAt(i);
3234 if (memento.deviceId == entry->deviceId
3235 && memento.source == entry->source
3236 && memento.keyCode == entry->keyCode
3237 && memento.scanCode == entry->scanCode) {
3238 switch (action) {
3239 case AKEY_EVENT_ACTION_UP:
3240 mKeyMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003241 return CONSISTENT;
3242
3243 case AKEY_EVENT_ACTION_DOWN:
3244 return TOLERABLE;
3245
3246 default:
3247 return BROKEN;
3248 }
3249 }
3250 }
3251
3252 switch (action) {
3253 case AKEY_EVENT_ACTION_DOWN: {
3254 mKeyMementos.push();
3255 KeyMemento& memento = mKeyMementos.editTop();
3256 memento.deviceId = entry->deviceId;
3257 memento.source = entry->source;
3258 memento.keyCode = entry->keyCode;
3259 memento.scanCode = entry->scanCode;
3260 memento.downTime = entry->downTime;
3261 return CONSISTENT;
3262 }
3263
3264 default:
3265 return BROKEN;
3266 }
3267}
3268
3269InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3270 const MotionEntry* entry) {
3271 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3272 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3273 MotionMemento& memento = mMotionMementos.editItemAt(i);
3274 if (memento.deviceId == entry->deviceId
3275 && memento.source == entry->source) {
3276 switch (action) {
3277 case AMOTION_EVENT_ACTION_UP:
3278 case AMOTION_EVENT_ACTION_CANCEL:
3279 mMotionMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003280 return CONSISTENT;
3281
3282 case AMOTION_EVENT_ACTION_DOWN:
3283 return TOLERABLE;
3284
3285 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3286 if (entry->pointerCount == memento.pointerCount + 1) {
3287 memento.setPointers(entry);
3288 return CONSISTENT;
3289 }
3290 return BROKEN;
3291
3292 case AMOTION_EVENT_ACTION_POINTER_UP:
3293 if (entry->pointerCount == memento.pointerCount - 1) {
3294 memento.setPointers(entry);
3295 return CONSISTENT;
3296 }
3297 return BROKEN;
3298
3299 case AMOTION_EVENT_ACTION_MOVE:
3300 if (entry->pointerCount == memento.pointerCount) {
3301 return CONSISTENT;
3302 }
3303 return BROKEN;
3304
3305 default:
3306 return BROKEN;
3307 }
3308 }
3309 }
3310
3311 switch (action) {
3312 case AMOTION_EVENT_ACTION_DOWN: {
3313 mMotionMementos.push();
3314 MotionMemento& memento = mMotionMementos.editTop();
3315 memento.deviceId = entry->deviceId;
3316 memento.source = entry->source;
3317 memento.xPrecision = entry->xPrecision;
3318 memento.yPrecision = entry->yPrecision;
3319 memento.downTime = entry->downTime;
3320 memento.setPointers(entry);
3321 return CONSISTENT;
3322 }
3323
3324 default:
3325 return BROKEN;
3326 }
3327}
3328
3329void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3330 pointerCount = entry->pointerCount;
3331 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3332 pointerIds[i] = entry->pointerIds[i];
3333 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3334 }
3335}
3336
Jeff Brown90f0cee2010-10-08 22:31:17 -07003337void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3338 Allocator* allocator, Vector<EventEntry*>& outEvents,
3339 CancelationOptions options) {
3340 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003341 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003342 if (shouldCancelEvent(memento.source, options)) {
3343 outEvents.push(allocator->obtainKeyEntry(currentTime,
3344 memento.deviceId, memento.source, 0,
3345 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3346 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3347 mKeyMementos.removeAt(i);
3348 } else {
3349 i += 1;
3350 }
Jeff Browna665ca82010-09-08 11:49:43 -07003351 }
3352
Jeff Brown316237d2010-10-11 18:22:53 -07003353 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003354 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003355 if (shouldCancelEvent(memento.source, options)) {
3356 outEvents.push(allocator->obtainMotionEntry(currentTime,
3357 memento.deviceId, memento.source, 0,
3358 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3359 memento.xPrecision, memento.yPrecision, memento.downTime,
3360 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3361 mMotionMementos.removeAt(i);
3362 } else {
3363 i += 1;
3364 }
Jeff Browna665ca82010-09-08 11:49:43 -07003365 }
3366}
3367
3368void InputDispatcher::InputState::clear() {
3369 mKeyMementos.clear();
3370 mMotionMementos.clear();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003371}
3372
3373bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3374 CancelationOptions options) {
3375 switch (options) {
3376 case CANCEL_POINTER_EVENTS:
3377 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3378 case CANCEL_NON_POINTER_EVENTS:
3379 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3380 default:
3381 return true;
3382 }
Jeff Browna665ca82010-09-08 11:49:43 -07003383}
3384
3385
Jeff Browne839a582010-04-22 18:58:52 -07003386// --- InputDispatcher::Connection ---
3387
3388InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3389 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003390 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003391}
3392
3393InputDispatcher::Connection::~Connection() {
3394}
3395
3396status_t InputDispatcher::Connection::initialize() {
3397 return inputPublisher.initialize();
3398}
3399
Jeff Brown54bc2812010-06-15 01:31:58 -07003400const char* InputDispatcher::Connection::getStatusLabel() const {
3401 switch (status) {
3402 case STATUS_NORMAL:
3403 return "NORMAL";
3404
3405 case STATUS_BROKEN:
3406 return "BROKEN";
3407
Jeff Brown54bc2812010-06-15 01:31:58 -07003408 case STATUS_ZOMBIE:
3409 return "ZOMBIE";
3410
3411 default:
3412 return "UNKNOWN";
3413 }
3414}
3415
Jeff Browne839a582010-04-22 18:58:52 -07003416InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3417 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003418 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3419 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003420 if (dispatchEntry->eventEntry == eventEntry) {
3421 return dispatchEntry;
3422 }
3423 }
3424 return NULL;
3425}
3426
Jeff Browna665ca82010-09-08 11:49:43 -07003427
Jeff Brown54bc2812010-06-15 01:31:58 -07003428// --- InputDispatcher::CommandEntry ---
3429
Jeff Browna665ca82010-09-08 11:49:43 -07003430InputDispatcher::CommandEntry::CommandEntry() :
3431 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003432}
3433
3434InputDispatcher::CommandEntry::~CommandEntry() {
3435}
3436
Jeff Browne839a582010-04-22 18:58:52 -07003437
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003438// --- InputDispatcher::TouchState ---
3439
3440InputDispatcher::TouchState::TouchState() :
3441 down(false), split(false) {
3442}
3443
3444InputDispatcher::TouchState::~TouchState() {
3445}
3446
3447void InputDispatcher::TouchState::reset() {
3448 down = false;
3449 split = false;
3450 windows.clear();
3451}
3452
3453void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3454 down = other.down;
3455 split = other.split;
3456 windows.clear();
3457 windows.appendVector(other.windows);
3458}
3459
3460void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3461 int32_t targetFlags, BitSet32 pointerIds) {
3462 if (targetFlags & InputTarget::FLAG_SPLIT) {
3463 split = true;
3464 }
3465
3466 for (size_t i = 0; i < windows.size(); i++) {
3467 TouchedWindow& touchedWindow = windows.editItemAt(i);
3468 if (touchedWindow.window == window) {
3469 touchedWindow.targetFlags |= targetFlags;
3470 touchedWindow.pointerIds.value |= pointerIds.value;
3471 return;
3472 }
3473 }
3474
3475 windows.push();
3476
3477 TouchedWindow& touchedWindow = windows.editTop();
3478 touchedWindow.window = window;
3479 touchedWindow.targetFlags = targetFlags;
3480 touchedWindow.pointerIds = pointerIds;
3481 touchedWindow.channel = window->inputChannel;
3482}
3483
3484void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3485 for (size_t i = 0 ; i < windows.size(); ) {
3486 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3487 windows.removeAt(i);
3488 } else {
3489 i += 1;
3490 }
3491 }
3492}
3493
3494const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3495 for (size_t i = 0; i < windows.size(); i++) {
3496 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3497 return windows[i].window;
3498 }
3499 }
3500 return NULL;
3501}
3502
3503
Jeff Browne839a582010-04-22 18:58:52 -07003504// --- InputDispatcherThread ---
3505
3506InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3507 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3508}
3509
3510InputDispatcherThread::~InputDispatcherThread() {
3511}
3512
3513bool InputDispatcherThread::threadLoop() {
3514 mDispatcher->dispatchOnce();
3515 return true;
3516}
3517
3518} // namespace android