blob: 93bde13b9655f6a276c4fc27172d06c63de1bb25 [file] [log] [blame]
Jeff Browne839a582010-04-22 18:58:52 -07001//
2// Copyright 2010 The Android Open Source Project
3//
4// The input dispatcher.
5//
6#define LOG_TAG "InputDispatcher"
7
8//#define LOG_NDEBUG 0
9
10// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown50de30a2010-06-22 01:27:15 -070011#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Browne839a582010-04-22 18:58:52 -070012
13// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown50de30a2010-06-22 01:27:15 -070014#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Browne839a582010-04-22 18:58:52 -070015
16// Log debug messages about batching.
Jeff Brown50de30a2010-06-22 01:27:15 -070017#define DEBUG_BATCHING 0
Jeff Browne839a582010-04-22 18:58:52 -070018
19// Log debug messages about the dispatch cycle.
Jeff Brown50de30a2010-06-22 01:27:15 -070020#define DEBUG_DISPATCH_CYCLE 0
Jeff Browne839a582010-04-22 18:58:52 -070021
Jeff Brown54bc2812010-06-15 01:31:58 -070022// Log debug messages about registrations.
Jeff Brown50de30a2010-06-22 01:27:15 -070023#define DEBUG_REGISTRATION 0
Jeff Brown54bc2812010-06-15 01:31:58 -070024
Jeff Browne839a582010-04-22 18:58:52 -070025// Log debug messages about performance statistics.
Jeff Brown50de30a2010-06-22 01:27:15 -070026#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Browne839a582010-04-22 18:58:52 -070027
Jeff Brown51d45a72010-06-17 20:52:56 -070028// Log debug messages about input event injection.
Jeff Brown50de30a2010-06-22 01:27:15 -070029#define DEBUG_INJECTION 0
Jeff Brown51d45a72010-06-17 20:52:56 -070030
Jeff Brown542412c2010-08-18 15:51:08 -070031// Log debug messages about input event throttling.
32#define DEBUG_THROTTLING 0
33
Jeff Browna665ca82010-09-08 11:49:43 -070034// Log debug messages about input focus tracking.
35#define DEBUG_FOCUS 0
36
37// Log debug messages about the app switch latency optimization.
38#define DEBUG_APP_SWITCH 0
39
Jeff Browne839a582010-04-22 18:58:52 -070040#include <cutils/log.h>
41#include <ui/InputDispatcher.h>
Jeff Browna665ca82010-09-08 11:49:43 -070042#include <ui/PowerManager.h>
Jeff Browne839a582010-04-22 18:58:52 -070043
44#include <stddef.h>
45#include <unistd.h>
Jeff Browne839a582010-04-22 18:58:52 -070046#include <errno.h>
47#include <limits.h>
Jeff Browne839a582010-04-22 18:58:52 -070048
Jeff Brown2806e382010-10-01 17:46:21 -070049#define INDENT " "
50#define INDENT2 " "
51
Jeff Browne839a582010-04-22 18:58:52 -070052namespace android {
53
Jeff Browna665ca82010-09-08 11:49:43 -070054// Delay between reporting long touch events to the power manager.
55const nsecs_t EVENT_IGNORE_DURATION = 300 * 1000000LL; // 300 ms
56
57// Default input dispatching timeout if there is no focused application or paused window
58// from which to determine an appropriate dispatching timeout.
59const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
60
61// Amount of time to allow for all pending events to be processed when an app switch
62// key is on the way. This is used to preempt input dispatch and drop input events
63// when an application takes too long to respond and the user has pressed an app switch key.
64const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
65
Jeff Browne839a582010-04-22 18:58:52 -070066
Jeff Brown51d45a72010-06-17 20:52:56 -070067static inline nsecs_t now() {
68 return systemTime(SYSTEM_TIME_MONOTONIC);
69}
70
Jeff Browna665ca82010-09-08 11:49:43 -070071static inline const char* toString(bool value) {
72 return value ? "true" : "false";
73}
74
Jeff Brownd1b0a2b2010-09-26 22:20:12 -070075static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
76 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
77 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
78}
79
80static bool isValidKeyAction(int32_t action) {
81 switch (action) {
82 case AKEY_EVENT_ACTION_DOWN:
83 case AKEY_EVENT_ACTION_UP:
84 return true;
85 default:
86 return false;
87 }
88}
89
90static bool validateKeyEvent(int32_t action) {
91 if (! isValidKeyAction(action)) {
92 LOGE("Key event has invalid action code 0x%x", action);
93 return false;
94 }
95 return true;
96}
97
Jeff Brown90f0cee2010-10-08 22:31:17 -070098static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -070099 switch (action & AMOTION_EVENT_ACTION_MASK) {
100 case AMOTION_EVENT_ACTION_DOWN:
101 case AMOTION_EVENT_ACTION_UP:
102 case AMOTION_EVENT_ACTION_CANCEL:
103 case AMOTION_EVENT_ACTION_MOVE:
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700104 case AMOTION_EVENT_ACTION_OUTSIDE:
105 return true;
Jeff Brown90f0cee2010-10-08 22:31:17 -0700106 case AMOTION_EVENT_ACTION_POINTER_DOWN:
107 case AMOTION_EVENT_ACTION_POINTER_UP: {
108 int32_t index = getMotionEventActionPointerIndex(action);
109 return index >= 0 && size_t(index) < pointerCount;
110 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700111 default:
112 return false;
113 }
114}
115
116static bool validateMotionEvent(int32_t action, size_t pointerCount,
117 const int32_t* pointerIds) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700118 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700119 LOGE("Motion event has invalid action code 0x%x", action);
120 return false;
121 }
122 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
123 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
124 pointerCount, MAX_POINTERS);
125 return false;
126 }
127 for (size_t i = 0; i < pointerCount; i++) {
128 if (pointerIds[i] < 0 || pointerIds[i] > MAX_POINTER_ID) {
129 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
130 pointerIds[i], MAX_POINTER_ID);
131 return false;
132 }
133 }
134 return true;
135}
136
Jeff Browna665ca82010-09-08 11:49:43 -0700137
138// --- InputWindow ---
139
Jeff Browna665ca82010-09-08 11:49:43 -0700140bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
141 return x >= touchableAreaLeft && x <= touchableAreaRight
142 && y >= touchableAreaTop && y <= touchableAreaBottom;
143}
144
Jeff Brown35cf0e92010-10-05 12:26:23 -0700145bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
146 return x >= frameLeft && x <= frameRight
147 && y >= frameTop && y <= frameBottom;
148}
149
150bool InputWindow::isTrustedOverlay() const {
151 return layoutParamsType == TYPE_INPUT_METHOD
Jeff Browne68d9e02010-10-15 00:54:27 -0700152 || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
153 || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
Jeff Brown35cf0e92010-10-05 12:26:23 -0700154}
155
Jeff Browna665ca82010-09-08 11:49:43 -0700156
Jeff Browne839a582010-04-22 18:58:52 -0700157// --- InputDispatcher ---
158
Jeff Brown54bc2812010-06-15 01:31:58 -0700159InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Browna665ca82010-09-08 11:49:43 -0700160 mPolicy(policy),
161 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
162 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700163 mFocusedWindow(NULL),
Jeff Browna665ca82010-09-08 11:49:43 -0700164 mFocusedApplication(NULL),
165 mCurrentInputTargetsValid(false),
166 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown59abe7e2010-09-13 23:17:30 -0700167 mLooper = new Looper(false);
Jeff Browne839a582010-04-22 18:58:52 -0700168
Jeff Browna665ca82010-09-08 11:49:43 -0700169 mInboundQueue.headSentinel.refCount = -1;
170 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
171 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Browne839a582010-04-22 18:58:52 -0700172
Jeff Browna665ca82010-09-08 11:49:43 -0700173 mInboundQueue.tailSentinel.refCount = -1;
174 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
175 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Browne839a582010-04-22 18:58:52 -0700176
177 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown54bc2812010-06-15 01:31:58 -0700178
Jeff Brown542412c2010-08-18 15:51:08 -0700179 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
180 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
181 mThrottleState.lastDeviceId = -1;
182
183#if DEBUG_THROTTLING
184 mThrottleState.originalSampleCount = 0;
185 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
186#endif
Jeff Browne839a582010-04-22 18:58:52 -0700187}
188
189InputDispatcher::~InputDispatcher() {
Jeff Browna665ca82010-09-08 11:49:43 -0700190 { // acquire lock
191 AutoMutex _l(mLock);
192
193 resetKeyRepeatLocked();
Jeff Brownd8816c32010-09-16 14:07:33 -0700194 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700195 drainInboundQueueLocked();
196 }
Jeff Browne839a582010-04-22 18:58:52 -0700197
198 while (mConnectionsByReceiveFd.size() != 0) {
199 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
200 }
Jeff Browne839a582010-04-22 18:58:52 -0700201}
202
203void InputDispatcher::dispatchOnce() {
Jeff Brown54bc2812010-06-15 01:31:58 -0700204 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brown61ce3982010-09-07 10:44:57 -0700205 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Browne839a582010-04-22 18:58:52 -0700206
Jeff Browne839a582010-04-22 18:58:52 -0700207 nsecs_t nextWakeupTime = LONG_LONG_MAX;
208 { // acquire lock
209 AutoMutex _l(mLock);
Jeff Browna665ca82010-09-08 11:49:43 -0700210 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Browne839a582010-04-22 18:58:52 -0700211
Jeff Browna665ca82010-09-08 11:49:43 -0700212 if (runCommandsLockedInterruptible()) {
213 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Browne839a582010-04-22 18:58:52 -0700214 }
Jeff Browne839a582010-04-22 18:58:52 -0700215 } // release lock
216
Jeff Browna665ca82010-09-08 11:49:43 -0700217 // Wait for callback or timeout or wake. (make sure we round up, not down)
218 nsecs_t currentTime = now();
219 int32_t timeoutMillis;
220 if (nextWakeupTime > currentTime) {
221 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
222 timeout = (timeout + 999999LL) / 1000000LL;
223 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
224 } else {
225 timeoutMillis = 0;
226 }
227
Jeff Brown59abe7e2010-09-13 23:17:30 -0700228 mLooper->pollOnce(timeoutMillis);
Jeff Browna665ca82010-09-08 11:49:43 -0700229}
230
231void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
232 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
233 nsecs_t currentTime = now();
234
235 // Reset the key repeat timer whenever we disallow key events, even if the next event
236 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
237 // out of sleep.
238 if (keyRepeatTimeout < 0) {
239 resetKeyRepeatLocked();
240 }
241
Jeff Browna665ca82010-09-08 11:49:43 -0700242 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
243 if (mDispatchFrozen) {
244#if DEBUG_FOCUS
245 LOGD("Dispatch frozen. Waiting some more.");
246#endif
247 return;
248 }
249
250 // Optimize latency of app switches.
251 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
252 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
253 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
254 if (mAppSwitchDueTime < *nextWakeupTime) {
255 *nextWakeupTime = mAppSwitchDueTime;
256 }
257
Jeff Browna665ca82010-09-08 11:49:43 -0700258 // Ready to start a new event.
259 // If we don't already have a pending event, go grab one.
260 if (! mPendingEvent) {
261 if (mInboundQueue.isEmpty()) {
262 if (isAppSwitchDue) {
263 // The inbound queue is empty so the app switch key we were waiting
264 // for will never arrive. Stop waiting for it.
265 resetPendingAppSwitchLocked(false);
266 isAppSwitchDue = false;
267 }
268
269 // Synthesize a key repeat if appropriate.
270 if (mKeyRepeatState.lastKeyEntry) {
271 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
272 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
273 } else {
274 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
275 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
276 }
277 }
278 }
279 if (! mPendingEvent) {
280 return;
281 }
282 } else {
283 // Inbound queue has at least one entry.
284 EventEntry* entry = mInboundQueue.headSentinel.next;
285
286 // Throttle the entry if it is a move event and there are no
287 // other events behind it in the queue. Due to movement batching, additional
288 // samples may be appended to this event by the time the throttling timeout
289 // expires.
290 // TODO Make this smarter and consider throttling per device independently.
Jeff Brown90f0cee2010-10-08 22:31:17 -0700291 if (entry->type == EventEntry::TYPE_MOTION
292 && !isAppSwitchDue
293 && mDispatchEnabled
294 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
295 && !entry->isInjected()) {
Jeff Browna665ca82010-09-08 11:49:43 -0700296 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
297 int32_t deviceId = motionEntry->deviceId;
298 uint32_t source = motionEntry->source;
299 if (! isAppSwitchDue
300 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
301 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
302 && deviceId == mThrottleState.lastDeviceId
303 && source == mThrottleState.lastSource) {
304 nsecs_t nextTime = mThrottleState.lastEventTime
305 + mThrottleState.minTimeBetweenEvents;
306 if (currentTime < nextTime) {
307 // Throttle it!
308#if DEBUG_THROTTLING
309 LOGD("Throttling - Delaying motion event for "
310 "device 0x%x, source 0x%08x by up to %0.3fms.",
311 deviceId, source, (nextTime - currentTime) * 0.000001);
312#endif
313 if (nextTime < *nextWakeupTime) {
314 *nextWakeupTime = nextTime;
315 }
316 if (mThrottleState.originalSampleCount == 0) {
317 mThrottleState.originalSampleCount =
318 motionEntry->countSamples();
319 }
320 return;
321 }
322 }
323
324#if DEBUG_THROTTLING
325 if (mThrottleState.originalSampleCount != 0) {
326 uint32_t count = motionEntry->countSamples();
327 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
328 count - mThrottleState.originalSampleCount,
329 mThrottleState.originalSampleCount, count);
330 mThrottleState.originalSampleCount = 0;
331 }
332#endif
333
334 mThrottleState.lastEventTime = entry->eventTime < currentTime
335 ? entry->eventTime : currentTime;
336 mThrottleState.lastDeviceId = deviceId;
337 mThrottleState.lastSource = source;
338 }
339
340 mInboundQueue.dequeue(entry);
341 mPendingEvent = entry;
342 }
343 }
344
345 // Now we have an event to dispatch.
346 assert(mPendingEvent != NULL);
Jeff Brownd8816c32010-09-16 14:07:33 -0700347 bool done = false;
Jeff Brown90f0cee2010-10-08 22:31:17 -0700348 DropReason dropReason = DROP_REASON_NOT_DROPPED;
349 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
350 dropReason = DROP_REASON_POLICY;
351 } else if (!mDispatchEnabled) {
352 dropReason = DROP_REASON_DISABLED;
353 }
Jeff Browna665ca82010-09-08 11:49:43 -0700354 switch (mPendingEvent->type) {
355 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
356 ConfigurationChangedEntry* typedEntry =
357 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brownd8816c32010-09-16 14:07:33 -0700358 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700359 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Browna665ca82010-09-08 11:49:43 -0700360 break;
361 }
362
363 case EventEntry::TYPE_KEY: {
364 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700365 if (isAppSwitchDue) {
366 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700367 resetPendingAppSwitchLocked(true);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700368 isAppSwitchDue = false;
369 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
370 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700371 }
372 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700373 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Brown33d54ce2010-10-11 14:20:19 -0700374 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700375 break;
376 }
377
378 case EventEntry::TYPE_MOTION: {
379 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700380 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
381 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700382 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700383 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Brown33d54ce2010-10-11 14:20:19 -0700384 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700385 break;
386 }
387
388 default:
389 assert(false);
Jeff Browna665ca82010-09-08 11:49:43 -0700390 break;
391 }
392
Jeff Brownd8816c32010-09-16 14:07:33 -0700393 if (done) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700394 if (dropReason != DROP_REASON_NOT_DROPPED) {
395 dropInboundEventLocked(mPendingEvent, dropReason);
396 }
397
Jeff Brownd8816c32010-09-16 14:07:33 -0700398 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700399 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
400 }
401}
402
403bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
404 bool needWake = mInboundQueue.isEmpty();
405 mInboundQueue.enqueueAtTail(entry);
406
407 switch (entry->type) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700408 case EventEntry::TYPE_KEY: {
409 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
410 if (isAppSwitchKeyEventLocked(keyEntry)) {
411 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
412 mAppSwitchSawKeyDown = true;
413 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
414 if (mAppSwitchSawKeyDown) {
415#if DEBUG_APP_SWITCH
416 LOGD("App switch is pending!");
417#endif
418 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
419 mAppSwitchSawKeyDown = false;
420 needWake = true;
421 }
422 }
423 }
Jeff Browna665ca82010-09-08 11:49:43 -0700424 break;
425 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700426 }
Jeff Browna665ca82010-09-08 11:49:43 -0700427
428 return needWake;
429}
430
Jeff Brown90f0cee2010-10-08 22:31:17 -0700431void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
432 const char* reason;
433 switch (dropReason) {
434 case DROP_REASON_POLICY:
Jeff Brown33d54ce2010-10-11 14:20:19 -0700435#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Browna8ed8562010-10-11 23:32:49 -0700436 LOGD("Dropped event because policy consumed it.");
Jeff Brown33d54ce2010-10-11 14:20:19 -0700437#endif
Jeff Browna8ed8562010-10-11 23:32:49 -0700438 reason = "inbound event was dropped because the policy consumed it";
Jeff Brown90f0cee2010-10-08 22:31:17 -0700439 break;
440 case DROP_REASON_DISABLED:
441 LOGI("Dropped event because input dispatch is disabled.");
442 reason = "inbound event was dropped because input dispatch is disabled";
443 break;
444 case DROP_REASON_APP_SWITCH:
445 LOGI("Dropped event because of pending overdue app switch.");
446 reason = "inbound event was dropped because of pending overdue app switch";
447 break;
448 default:
449 assert(false);
450 return;
451 }
452
453 switch (entry->type) {
454 case EventEntry::TYPE_KEY:
455 synthesizeCancelationEventsForAllConnectionsLocked(
456 InputState::CANCEL_NON_POINTER_EVENTS, reason);
457 break;
458 case EventEntry::TYPE_MOTION: {
459 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
460 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
461 synthesizeCancelationEventsForAllConnectionsLocked(
462 InputState::CANCEL_POINTER_EVENTS, reason);
463 } else {
464 synthesizeCancelationEventsForAllConnectionsLocked(
465 InputState::CANCEL_NON_POINTER_EVENTS, reason);
466 }
467 break;
468 }
469 }
470}
471
472bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Browna665ca82010-09-08 11:49:43 -0700473 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
474}
475
Jeff Brown90f0cee2010-10-08 22:31:17 -0700476bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
477 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
478 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Brown33d54ce2010-10-11 14:20:19 -0700479 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brown90f0cee2010-10-08 22:31:17 -0700480 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
481}
482
Jeff Browna665ca82010-09-08 11:49:43 -0700483bool InputDispatcher::isAppSwitchPendingLocked() {
484 return mAppSwitchDueTime != LONG_LONG_MAX;
485}
486
Jeff Browna665ca82010-09-08 11:49:43 -0700487void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
488 mAppSwitchDueTime = LONG_LONG_MAX;
489
490#if DEBUG_APP_SWITCH
491 if (handled) {
492 LOGD("App switch has arrived.");
493 } else {
494 LOGD("App switch was abandoned.");
495 }
496#endif
Jeff Browne839a582010-04-22 18:58:52 -0700497}
498
Jeff Brown54bc2812010-06-15 01:31:58 -0700499bool InputDispatcher::runCommandsLockedInterruptible() {
500 if (mCommandQueue.isEmpty()) {
501 return false;
502 }
Jeff Browne839a582010-04-22 18:58:52 -0700503
Jeff Brown54bc2812010-06-15 01:31:58 -0700504 do {
505 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
506
507 Command command = commandEntry->command;
508 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
509
Jeff Brown51d45a72010-06-17 20:52:56 -0700510 commandEntry->connection.clear();
Jeff Brown54bc2812010-06-15 01:31:58 -0700511 mAllocator.releaseCommandEntry(commandEntry);
512 } while (! mCommandQueue.isEmpty());
513 return true;
Jeff Browne839a582010-04-22 18:58:52 -0700514}
515
Jeff Brown54bc2812010-06-15 01:31:58 -0700516InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
517 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
518 mCommandQueue.enqueueAtTail(commandEntry);
519 return commandEntry;
520}
521
Jeff Browna665ca82010-09-08 11:49:43 -0700522void InputDispatcher::drainInboundQueueLocked() {
523 while (! mInboundQueue.isEmpty()) {
524 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brownd8816c32010-09-16 14:07:33 -0700525 releaseInboundEventLocked(entry);
Jeff Browne839a582010-04-22 18:58:52 -0700526 }
Jeff Browne839a582010-04-22 18:58:52 -0700527}
528
Jeff Brownd8816c32010-09-16 14:07:33 -0700529void InputDispatcher::releasePendingEventLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700530 if (mPendingEvent) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700531 releaseInboundEventLocked(mPendingEvent);
Jeff Browna665ca82010-09-08 11:49:43 -0700532 mPendingEvent = NULL;
533 }
534}
535
Jeff Brownd8816c32010-09-16 14:07:33 -0700536void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700537 InjectionState* injectionState = entry->injectionState;
538 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Browna665ca82010-09-08 11:49:43 -0700539#if DEBUG_DISPATCH_CYCLE
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700540 LOGD("Injected inbound event was dropped.");
Jeff Browna665ca82010-09-08 11:49:43 -0700541#endif
542 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
543 }
544 mAllocator.releaseEventEntry(entry);
545}
546
Jeff Browna665ca82010-09-08 11:49:43 -0700547void InputDispatcher::resetKeyRepeatLocked() {
548 if (mKeyRepeatState.lastKeyEntry) {
549 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
550 mKeyRepeatState.lastKeyEntry = NULL;
551 }
552}
553
554InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brown61ce3982010-09-07 10:44:57 -0700555 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown50de30a2010-06-22 01:27:15 -0700556 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
557
Jeff Brown50de30a2010-06-22 01:27:15 -0700558 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown33d54ce2010-10-11 14:20:19 -0700559 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
560 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Browne839a582010-04-22 18:58:52 -0700561 if (entry->refCount == 1) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700562 mAllocator.recycleKeyEntry(entry);
Jeff Brown51d45a72010-06-17 20:52:56 -0700563 entry->eventTime = currentTime;
Jeff Brown51d45a72010-06-17 20:52:56 -0700564 entry->policyFlags = policyFlags;
Jeff Browne839a582010-04-22 18:58:52 -0700565 entry->repeatCount += 1;
566 } else {
Jeff Brown51d45a72010-06-17 20:52:56 -0700567 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700568 entry->deviceId, entry->source, policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700569 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brownf16c26d2010-07-02 15:37:36 -0700570 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Browne839a582010-04-22 18:58:52 -0700571
572 mKeyRepeatState.lastKeyEntry = newEntry;
573 mAllocator.releaseKeyEntry(entry);
574
575 entry = newEntry;
576 }
Jeff Browna665ca82010-09-08 11:49:43 -0700577 entry->syntheticRepeat = true;
578
579 // Increment reference count since we keep a reference to the event in
580 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
581 entry->refCount += 1;
Jeff Browne839a582010-04-22 18:58:52 -0700582
Jeff Brownf16c26d2010-07-02 15:37:36 -0700583 if (entry->repeatCount == 1) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700584 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brownf16c26d2010-07-02 15:37:36 -0700585 }
586
Jeff Brown61ce3982010-09-07 10:44:57 -0700587 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Browna665ca82010-09-08 11:49:43 -0700588 return entry;
Jeff Browne839a582010-04-22 18:58:52 -0700589}
590
Jeff Browna665ca82010-09-08 11:49:43 -0700591bool InputDispatcher::dispatchConfigurationChangedLocked(
592 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Browne839a582010-04-22 18:58:52 -0700593#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Browna665ca82010-09-08 11:49:43 -0700594 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
595#endif
596
597 // Reset key repeating in case a keyboard device was added or removed or something.
598 resetKeyRepeatLocked();
599
600 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
601 CommandEntry* commandEntry = postCommandLocked(
602 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
603 commandEntry->eventTime = entry->eventTime;
604 return true;
605}
606
607bool InputDispatcher::dispatchKeyLocked(
608 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brown33d54ce2010-10-11 14:20:19 -0700609 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700610 // Give the policy a chance to intercept the key.
611 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Brown33d54ce2010-10-11 14:20:19 -0700612 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700613 CommandEntry* commandEntry = postCommandLocked(
614 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Brown33d54ce2010-10-11 14:20:19 -0700615 if (mFocusedWindow) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700616 commandEntry->inputChannel = mFocusedWindow->inputChannel;
617 }
618 commandEntry->keyEntry = entry;
619 entry->refCount += 1;
620 return false; // wait for the command to run
621 } else {
622 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
623 }
624 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Brown33d54ce2010-10-11 14:20:19 -0700625 if (*dropReason == DROP_REASON_NOT_DROPPED) {
626 *dropReason = DROP_REASON_POLICY;
627 }
Jeff Brownd8816c32010-09-16 14:07:33 -0700628 }
629
630 // Clean up if dropping the event.
Jeff Brown33d54ce2010-10-11 14:20:19 -0700631 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700632 resetTargetsLocked();
Jeff Browna8ed8562010-10-11 23:32:49 -0700633 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
634 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brownd8816c32010-09-16 14:07:33 -0700635 return true;
636 }
637
Jeff Browna665ca82010-09-08 11:49:43 -0700638 // Preprocessing.
639 if (! entry->dispatchInProgress) {
640 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
641
642 if (entry->repeatCount == 0
643 && entry->action == AKEY_EVENT_ACTION_DOWN
Jeff Brown33d54ce2010-10-11 14:20:19 -0700644 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
645 && !entry->isInjected()) {
Jeff Browna665ca82010-09-08 11:49:43 -0700646 if (mKeyRepeatState.lastKeyEntry
647 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
648 // We have seen two identical key downs in a row which indicates that the device
649 // driver is automatically generating key repeats itself. We take note of the
650 // repeat here, but we disable our own next key repeat timer since it is clear that
651 // we will not need to synthesize key repeats ourselves.
652 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
653 resetKeyRepeatLocked();
654 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
655 } else {
656 // Not a repeat. Save key down state in case we do see a repeat later.
657 resetKeyRepeatLocked();
658 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
659 }
660 mKeyRepeatState.lastKeyEntry = entry;
661 entry->refCount += 1;
662 } else if (! entry->syntheticRepeat) {
663 resetKeyRepeatLocked();
664 }
665
666 entry->dispatchInProgress = true;
Jeff Brownd8816c32010-09-16 14:07:33 -0700667 resetTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700668 }
669
670 // Identify targets.
671 if (! mCurrentInputTargetsValid) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700672 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
673 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700674 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
675 return false;
676 }
677
678 setInjectionResultLocked(entry, injectionResult);
679 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
680 return true;
681 }
682
683 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700684 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700685 }
686
687 // Dispatch the key.
688 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
689
690 // Poke user activity.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700691 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
692 pokeUserActivityLocked(entry->eventTime, POWER_MANAGER_BUTTON_EVENT);
693 }
Jeff Browna665ca82010-09-08 11:49:43 -0700694 return true;
695}
696
697void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
698#if DEBUG_OUTBOUND_EVENT_DETAILS
699 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
700 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
701 "downTime=%lld",
702 prefix,
703 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
704 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
705 entry->downTime);
706#endif
707}
708
709bool InputDispatcher::dispatchMotionLocked(
Jeff Brown33d54ce2010-10-11 14:20:19 -0700710 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700711 // Clean up if dropping the event.
Jeff Brown33d54ce2010-10-11 14:20:19 -0700712 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700713 resetTargetsLocked();
Jeff Browna8ed8562010-10-11 23:32:49 -0700714 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
715 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brownd8816c32010-09-16 14:07:33 -0700716 return true;
717 }
718
Jeff Browna665ca82010-09-08 11:49:43 -0700719 // Preprocessing.
720 if (! entry->dispatchInProgress) {
721 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
722
723 entry->dispatchInProgress = true;
Jeff Brownd8816c32010-09-16 14:07:33 -0700724 resetTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700725 }
726
727 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
728
729 // Identify targets.
730 if (! mCurrentInputTargetsValid) {
Jeff Browna665ca82010-09-08 11:49:43 -0700731 int32_t injectionResult;
732 if (isPointerEvent) {
733 // Pointer event. (eg. touchscreen)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700734 injectionResult = findTouchedWindowTargetsLocked(currentTime,
735 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700736 } else {
737 // Non touch event. (eg. trackball)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700738 injectionResult = findFocusedWindowTargetsLocked(currentTime,
739 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700740 }
741 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
742 return false;
743 }
744
745 setInjectionResultLocked(entry, injectionResult);
746 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
747 return true;
748 }
749
750 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700751 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700752 }
753
754 // Dispatch the motion.
755 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
756
757 // Poke user activity.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700758 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
759 int32_t eventType;
760 if (isPointerEvent) {
761 switch (entry->action) {
762 case AMOTION_EVENT_ACTION_DOWN:
Jeff Browna665ca82010-09-08 11:49:43 -0700763 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700764 break;
765 case AMOTION_EVENT_ACTION_UP:
766 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
767 break;
768 default:
769 if (entry->eventTime - entry->downTime >= EVENT_IGNORE_DURATION) {
770 eventType = POWER_MANAGER_TOUCH_EVENT;
771 } else {
772 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
773 }
774 break;
Jeff Browna665ca82010-09-08 11:49:43 -0700775 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700776 } else {
777 eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Browna665ca82010-09-08 11:49:43 -0700778 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700779 pokeUserActivityLocked(entry->eventTime, eventType);
Jeff Browna665ca82010-09-08 11:49:43 -0700780 }
Jeff Browna665ca82010-09-08 11:49:43 -0700781 return true;
782}
783
784
785void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
786#if DEBUG_OUTBOUND_EVENT_DETAILS
787 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700788 "action=0x%x, flags=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700789 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700790 prefix,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700791 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
792 entry->action, entry->flags,
Jeff Browne839a582010-04-22 18:58:52 -0700793 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
794 entry->downTime);
795
796 // Print the most recent sample that we have available, this may change due to batching.
797 size_t sampleCount = 1;
Jeff Browna665ca82010-09-08 11:49:43 -0700798 const MotionSample* sample = & entry->firstSample;
Jeff Browne839a582010-04-22 18:58:52 -0700799 for (; sample->next != NULL; sample = sample->next) {
800 sampleCount += 1;
801 }
802 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -0700803 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700804 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -0700805 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -0700806 i, entry->pointerIds[i],
Jeff Brown38a7fab2010-08-30 03:02:23 -0700807 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
808 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
809 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
810 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
811 sample->pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -0700812 }
813
814 // Keep in mind that due to batching, it is possible for the number of samples actually
815 // dispatched to change before the application finally consumed them.
Jeff Brown5c1ed842010-07-14 18:48:53 -0700816 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -0700817 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
818 }
819#endif
Jeff Browne839a582010-04-22 18:58:52 -0700820}
821
822void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
823 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
824#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700825 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700826 "resumeWithAppendedMotionSample=%s",
Jeff Browna665ca82010-09-08 11:49:43 -0700827 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -0700828#endif
829
Jeff Brown54bc2812010-06-15 01:31:58 -0700830 assert(eventEntry->dispatchInProgress); // should already have been set to true
831
Jeff Browne839a582010-04-22 18:58:52 -0700832 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
833 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
834
Jeff Brown53a415e2010-09-15 15:18:56 -0700835 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -0700836 if (connectionIndex >= 0) {
837 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown51d45a72010-06-17 20:52:56 -0700838 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -0700839 resumeWithAppendedMotionSample);
840 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700841#if DEBUG_FOCUS
842 LOGD("Dropping event delivery to target with channel '%s' because it "
843 "is no longer registered with the input dispatcher.",
Jeff Browne839a582010-04-22 18:58:52 -0700844 inputTarget.inputChannel->getName().string());
Jeff Brown90f0cee2010-10-08 22:31:17 -0700845#endif
Jeff Browne839a582010-04-22 18:58:52 -0700846 }
847 }
848}
849
Jeff Brownd8816c32010-09-16 14:07:33 -0700850void InputDispatcher::resetTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700851 mCurrentInputTargetsValid = false;
852 mCurrentInputTargets.clear();
Jeff Browna665ca82010-09-08 11:49:43 -0700853 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
854}
855
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700856void InputDispatcher::commitTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700857 mCurrentInputTargetsValid = true;
858}
859
860int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
861 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
862 nsecs_t* nextWakeupTime) {
863 if (application == NULL && window == NULL) {
864 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
865#if DEBUG_FOCUS
866 LOGD("Waiting for system to become ready for input.");
867#endif
868 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
869 mInputTargetWaitStartTime = currentTime;
870 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
871 mInputTargetWaitTimeoutExpired = false;
872 }
873 } else {
874 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
875#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700876 LOGD("Waiting for application to become ready for input: %s",
877 getApplicationWindowLabelLocked(application, window).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700878#endif
879 nsecs_t timeout = window ? window->dispatchingTimeout :
880 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
881
882 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
883 mInputTargetWaitStartTime = currentTime;
884 mInputTargetWaitTimeoutTime = currentTime + timeout;
885 mInputTargetWaitTimeoutExpired = false;
886 }
887 }
888
889 if (mInputTargetWaitTimeoutExpired) {
890 return INPUT_EVENT_INJECTION_TIMED_OUT;
891 }
892
893 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown53a415e2010-09-15 15:18:56 -0700894 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700895
896 // Force poll loop to wake up immediately on next iteration once we get the
897 // ANR response back from the policy.
898 *nextWakeupTime = LONG_LONG_MIN;
899 return INPUT_EVENT_INJECTION_PENDING;
900 } else {
901 // Force poll loop to wake up when timeout is due.
902 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
903 *nextWakeupTime = mInputTargetWaitTimeoutTime;
904 }
905 return INPUT_EVENT_INJECTION_PENDING;
906 }
907}
908
Jeff Brown53a415e2010-09-15 15:18:56 -0700909void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
910 const sp<InputChannel>& inputChannel) {
Jeff Browna665ca82010-09-08 11:49:43 -0700911 if (newTimeout > 0) {
912 // Extend the timeout.
913 mInputTargetWaitTimeoutTime = now() + newTimeout;
914 } else {
915 // Give up.
916 mInputTargetWaitTimeoutExpired = true;
Jeff Brown53a415e2010-09-15 15:18:56 -0700917
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700918 // Release the touch targets.
919 mTouchState.reset();
Jeff Brown405a1d32010-09-16 12:31:46 -0700920
Jeff Brown53a415e2010-09-15 15:18:56 -0700921 // Input state will not be realistic. Mark it out of sync.
Jeff Brown40ad4702010-09-16 11:02:16 -0700922 if (inputChannel.get()) {
923 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
924 if (connectionIndex >= 0) {
925 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700926 synthesizeCancelationEventsForConnectionLocked(
927 connection, InputState::CANCEL_ALL_EVENTS,
928 "application not responding");
Jeff Brown40ad4702010-09-16 11:02:16 -0700929 }
Jeff Brown53a415e2010-09-15 15:18:56 -0700930 }
Jeff Browna665ca82010-09-08 11:49:43 -0700931 }
932}
933
Jeff Brown53a415e2010-09-15 15:18:56 -0700934nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Browna665ca82010-09-08 11:49:43 -0700935 nsecs_t currentTime) {
936 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
937 return currentTime - mInputTargetWaitStartTime;
938 }
939 return 0;
940}
941
942void InputDispatcher::resetANRTimeoutsLocked() {
943#if DEBUG_FOCUS
944 LOGD("Resetting ANR timeouts.");
945#endif
946
Jeff Browna665ca82010-09-08 11:49:43 -0700947 // Reset input target wait timeout.
948 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
949}
950
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700951int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
952 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -0700953 mCurrentInputTargets.clear();
954
955 int32_t injectionResult;
956
957 // If there is no currently focused window and no focused application
958 // then drop the event.
959 if (! mFocusedWindow) {
960 if (mFocusedApplication) {
961#if DEBUG_FOCUS
962 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -0700963 "focused application that may eventually add a window: %s.",
964 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700965#endif
966 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
967 mFocusedApplication, NULL, nextWakeupTime);
968 goto Unresponsive;
969 }
970
971 LOGI("Dropping event because there is no focused window or focused application.");
972 injectionResult = INPUT_EVENT_INJECTION_FAILED;
973 goto Failed;
974 }
975
976 // Check permissions.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700977 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700978 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
979 goto Failed;
980 }
981
982 // If the currently focused window is paused then keep waiting.
983 if (mFocusedWindow->paused) {
984#if DEBUG_FOCUS
985 LOGD("Waiting because focused window is paused.");
986#endif
987 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
988 mFocusedApplication, mFocusedWindow, nextWakeupTime);
989 goto Unresponsive;
990 }
991
Jeff Brown53a415e2010-09-15 15:18:56 -0700992 // If the currently focused window is still working on previous events then keep waiting.
993 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
994#if DEBUG_FOCUS
995 LOGD("Waiting because focused window still processing previous input.");
996#endif
997 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
998 mFocusedApplication, mFocusedWindow, nextWakeupTime);
999 goto Unresponsive;
1000 }
1001
Jeff Browna665ca82010-09-08 11:49:43 -07001002 // Success! Output targets.
1003 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001004 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -07001005
1006 // Done.
1007Failed:
1008Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -07001009 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1010 updateDispatchStatisticsLocked(currentTime, entry,
1011 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001012#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -07001013 LOGD("findFocusedWindow finished: injectionResult=%d, "
1014 "timeSpendWaitingForApplication=%0.1fms",
1015 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001016#endif
1017 return injectionResult;
1018}
1019
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001020int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1021 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -07001022 enum InjectionPermission {
1023 INJECTION_PERMISSION_UNKNOWN,
1024 INJECTION_PERMISSION_GRANTED,
1025 INJECTION_PERMISSION_DENIED
1026 };
1027
Jeff Browna665ca82010-09-08 11:49:43 -07001028 mCurrentInputTargets.clear();
1029
1030 nsecs_t startTime = now();
1031
1032 // For security reasons, we defer updating the touch state until we are sure that
1033 // event injection will be allowed.
1034 //
1035 // FIXME In the original code, screenWasOff could never be set to true.
1036 // The reason is that the POLICY_FLAG_WOKE_HERE
1037 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1038 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1039 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1040 // events upon which no preprocessing took place. So policyFlags was always 0.
1041 // In the new native input dispatcher we're a bit more careful about event
1042 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1043 // Unfortunately we obtain undesirable behavior.
1044 //
1045 // Here's what happens:
1046 //
1047 // When the device dims in anticipation of going to sleep, touches
1048 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1049 // the device to brighten and reset the user activity timer.
1050 // Touches on other windows (such as the launcher window)
1051 // are dropped. Then after a moment, the device goes to sleep. Oops.
1052 //
1053 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1054 // instead of POLICY_FLAG_WOKE_HERE...
1055 //
1056 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1057
1058 int32_t action = entry->action;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001059 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Browna665ca82010-09-08 11:49:43 -07001060
1061 // Update the touch state as needed based on the properties of the touch event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001062 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1063 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1064 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1065 mTempTouchState.reset();
1066 mTempTouchState.down = true;
1067 } else {
1068 mTempTouchState.copyFrom(mTouchState);
1069 }
Jeff Browna665ca82010-09-08 11:49:43 -07001070
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001071 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1072 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1073 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1074 /* Case 1: New splittable pointer going down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001075
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001076 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1077 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1078 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1079 const InputWindow* newTouchedWindow = NULL;
1080 const InputWindow* topErrorWindow = NULL;
Jeff Browna665ca82010-09-08 11:49:43 -07001081
1082 // Traverse windows from front to back to find touched window and outside targets.
1083 size_t numWindows = mWindows.size();
1084 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001085 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07001086 int32_t flags = window->layoutParamsFlags;
1087
1088 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1089 if (! topErrorWindow) {
1090 topErrorWindow = window;
1091 }
1092 }
1093
1094 if (window->visible) {
1095 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1096 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1097 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1098 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1099 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1100 newTouchedWindow = window;
Jeff Browna665ca82010-09-08 11:49:43 -07001101 }
1102 break; // found touched window, exit window loop
1103 }
1104 }
1105
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001106 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1107 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001108 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1109 if (isWindowObscuredAtPointLocked(window, x, y)) {
1110 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1111 }
1112
1113 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -07001114 }
1115 }
1116 }
1117
1118 // If there is an error window but it is not taking focus (typically because
1119 // it is invisible) then wait for it. Any other focused window may in
1120 // fact be in ANR state.
1121 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1122#if DEBUG_FOCUS
1123 LOGD("Waiting because system error window is pending.");
1124#endif
1125 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1126 NULL, NULL, nextWakeupTime);
1127 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1128 goto Unresponsive;
1129 }
1130
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001131 // Figure out whether splitting will be allowed for this window.
Jeff Brown3c2450f2010-09-28 13:24:41 -07001132 if (newTouchedWindow
1133 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001134 // New window supports splitting.
1135 isSplit = true;
1136 } else if (isSplit) {
1137 // New window does not support splitting but we have already split events.
1138 // Assign the pointer to the first foreground window we find.
1139 // (May be NULL which is why we put this code block before the next check.)
1140 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1141 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001142
Jeff Browna665ca82010-09-08 11:49:43 -07001143 // If we did not find a touched window then fail.
1144 if (! newTouchedWindow) {
1145 if (mFocusedApplication) {
1146#if DEBUG_FOCUS
1147 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -07001148 "focused application that may eventually add a new window: %s.",
1149 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -07001150#endif
1151 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1152 mFocusedApplication, NULL, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -07001153 goto Unresponsive;
1154 }
1155
1156 LOGI("Dropping event because there is no touched window or focused application.");
1157 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001158 goto Failed;
1159 }
1160
Jeff Brown35cf0e92010-10-05 12:26:23 -07001161 // Set target flags.
1162 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1163 if (isSplit) {
1164 targetFlags |= InputTarget::FLAG_SPLIT;
1165 }
1166 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1167 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1168 }
1169
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001170 // Update the temporary touch state.
1171 BitSet32 pointerIds;
1172 if (isSplit) {
1173 uint32_t pointerId = entry->pointerIds[pointerIndex];
1174 pointerIds.markBit(pointerId);
Jeff Browna665ca82010-09-08 11:49:43 -07001175 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001176 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001177 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001178 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001179
1180 // If the pointer is not currently down, then ignore the event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001181 if (! mTempTouchState.down) {
Jeff Browna665ca82010-09-08 11:49:43 -07001182 LOGI("Dropping event because the pointer is not down.");
1183 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001184 goto Failed;
1185 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001186 }
Jeff Browna665ca82010-09-08 11:49:43 -07001187
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001188 // Check permission to inject into all touched foreground windows and ensure there
1189 // is at least one touched foreground window.
1190 {
1191 bool haveForegroundWindow = false;
1192 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1193 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1194 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1195 haveForegroundWindow = true;
1196 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1197 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1198 injectionPermission = INJECTION_PERMISSION_DENIED;
1199 goto Failed;
1200 }
1201 }
1202 }
1203 if (! haveForegroundWindow) {
Jeff Browna665ca82010-09-08 11:49:43 -07001204#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001205 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Browna665ca82010-09-08 11:49:43 -07001206#endif
1207 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001208 goto Failed;
1209 }
1210
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001211 // Permission granted to injection into all touched foreground windows.
1212 injectionPermission = INJECTION_PERMISSION_GRANTED;
1213 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001214
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001215 // Ensure all touched foreground windows are ready for new input.
1216 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1217 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1218 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1219 // If the touched window is paused then keep waiting.
1220 if (touchedWindow.window->paused) {
1221#if DEBUG_INPUT_DISPATCHER_POLICY
1222 LOGD("Waiting because touched window is paused.");
Jeff Brown53a415e2010-09-15 15:18:56 -07001223#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001224 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1225 NULL, touchedWindow.window, nextWakeupTime);
1226 goto Unresponsive;
1227 }
1228
1229 // If the touched window is still working on previous events then keep waiting.
1230 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1231#if DEBUG_FOCUS
1232 LOGD("Waiting because touched window still processing previous input.");
1233#endif
1234 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1235 NULL, touchedWindow.window, nextWakeupTime);
1236 goto Unresponsive;
1237 }
1238 }
1239 }
1240
1241 // If this is the first pointer going down and the touched window has a wallpaper
1242 // then also add the touched wallpaper windows so they are locked in for the duration
1243 // of the touch gesture.
1244 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1245 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1246 if (foregroundWindow->hasWallpaper) {
1247 for (size_t i = 0; i < mWindows.size(); i++) {
1248 const InputWindow* window = & mWindows[i];
1249 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001250 mTempTouchState.addOrUpdateWindow(window,
1251 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001252 }
1253 }
1254 }
1255 }
1256
Jeff Browna665ca82010-09-08 11:49:43 -07001257 // Success! Output targets.
1258 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Browna665ca82010-09-08 11:49:43 -07001259
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001260 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1261 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1262 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1263 touchedWindow.pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001264 }
1265
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001266 // Drop the outside touch window since we will not care about them in the next iteration.
1267 mTempTouchState.removeOutsideTouchWindows();
1268
Jeff Browna665ca82010-09-08 11:49:43 -07001269Failed:
1270 // Check injection permission once and for all.
1271 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001272 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001273 injectionPermission = INJECTION_PERMISSION_GRANTED;
1274 } else {
1275 injectionPermission = INJECTION_PERMISSION_DENIED;
1276 }
1277 }
1278
1279 // Update final pieces of touch state if the injector had permission.
1280 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001281 if (maskedAction == AMOTION_EVENT_ACTION_UP
1282 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1283 // All pointers up or canceled.
1284 mTempTouchState.reset();
1285 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1286 // First pointer went down.
1287 if (mTouchState.down) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001288#if DEBUG_FOCUS
1289 LOGD("Pointer down received while already down.");
1290#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001291 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001292 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1293 // One pointer went up.
1294 if (isSplit) {
1295 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1296 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Browna665ca82010-09-08 11:49:43 -07001297
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001298 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1299 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1300 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1301 touchedWindow.pointerIds.clearBit(pointerId);
1302 if (touchedWindow.pointerIds.isEmpty()) {
1303 mTempTouchState.windows.removeAt(i);
1304 continue;
1305 }
1306 }
1307 i += 1;
1308 }
Jeff Browna665ca82010-09-08 11:49:43 -07001309 }
Jeff Browna665ca82010-09-08 11:49:43 -07001310 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001311
1312 // Save changes to touch state.
1313 mTouchState.copyFrom(mTempTouchState);
Jeff Browna665ca82010-09-08 11:49:43 -07001314 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001315#if DEBUG_FOCUS
1316 LOGD("Not updating touch focus because injection was denied.");
1317#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001318 }
1319
1320Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -07001321 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1322 updateDispatchStatisticsLocked(currentTime, entry,
1323 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001324#if DEBUG_FOCUS
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001325 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1326 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown53a415e2010-09-15 15:18:56 -07001327 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001328#endif
1329 return injectionResult;
1330}
1331
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001332void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1333 BitSet32 pointerIds) {
Jeff Browna665ca82010-09-08 11:49:43 -07001334 mCurrentInputTargets.push();
1335
1336 InputTarget& target = mCurrentInputTargets.editTop();
1337 target.inputChannel = window->inputChannel;
1338 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001339 target.xOffset = - window->frameLeft;
1340 target.yOffset = - window->frameTop;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001341 target.windowType = window->layoutParamsType;
1342 target.pointerIds = pointerIds;
Jeff Browna665ca82010-09-08 11:49:43 -07001343}
1344
1345void InputDispatcher::addMonitoringTargetsLocked() {
1346 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1347 mCurrentInputTargets.push();
1348
1349 InputTarget& target = mCurrentInputTargets.editTop();
1350 target.inputChannel = mMonitoringChannels[i];
1351 target.flags = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07001352 target.xOffset = 0;
1353 target.yOffset = 0;
Jeff Browne68d9e02010-10-15 00:54:27 -07001354 target.windowType = -1;
Jeff Browna665ca82010-09-08 11:49:43 -07001355 }
1356}
1357
1358bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001359 const InjectionState* injectionState) {
1360 if (injectionState
Jeff Brown90f0cee2010-10-08 22:31:17 -07001361 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1362 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1363 if (window) {
1364 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1365 "with input channel %s owned by uid %d",
1366 injectionState->injectorPid, injectionState->injectorUid,
1367 window->inputChannel->getName().string(),
1368 window->ownerUid);
1369 } else {
1370 LOGW("Permission denied: injecting event from pid %d uid %d",
1371 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-09-08 11:49:43 -07001372 }
Jeff Brown90f0cee2010-10-08 22:31:17 -07001373 return false;
Jeff Browna665ca82010-09-08 11:49:43 -07001374 }
1375 return true;
1376}
1377
Jeff Brown35cf0e92010-10-05 12:26:23 -07001378bool InputDispatcher::isWindowObscuredAtPointLocked(
1379 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Browna665ca82010-09-08 11:49:43 -07001380 size_t numWindows = mWindows.size();
1381 for (size_t i = 0; i < numWindows; i++) {
1382 const InputWindow* other = & mWindows.itemAt(i);
1383 if (other == window) {
1384 break;
1385 }
Jeff Brown35cf0e92010-10-05 12:26:23 -07001386 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001387 return true;
1388 }
1389 }
1390 return false;
1391}
1392
Jeff Brown53a415e2010-09-15 15:18:56 -07001393bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1394 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1395 if (connectionIndex >= 0) {
1396 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1397 return connection->outboundQueue.isEmpty();
1398 } else {
1399 return true;
1400 }
1401}
1402
1403String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1404 const InputWindow* window) {
1405 if (application) {
1406 if (window) {
1407 String8 label(application->name);
1408 label.append(" - ");
1409 label.append(window->name);
1410 return label;
1411 } else {
1412 return application->name;
1413 }
1414 } else if (window) {
1415 return window->name;
1416 } else {
1417 return String8("<unknown application or window>");
1418 }
1419}
1420
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001421bool InputDispatcher::shouldPokeUserActivityForCurrentInputTargetsLocked() {
1422 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
1423 if (mCurrentInputTargets[i].windowType == InputWindow::TYPE_KEYGUARD) {
1424 return false;
1425 }
1426 }
1427 return true;
1428}
1429
1430void InputDispatcher::pokeUserActivityLocked(nsecs_t eventTime, int32_t eventType) {
Jeff Browna665ca82010-09-08 11:49:43 -07001431 CommandEntry* commandEntry = postCommandLocked(
1432 & InputDispatcher::doPokeUserActivityLockedInterruptible);
1433 commandEntry->eventTime = eventTime;
Jeff Browna665ca82010-09-08 11:49:43 -07001434 commandEntry->userActivityEventType = eventType;
1435}
1436
Jeff Brown51d45a72010-06-17 20:52:56 -07001437void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1438 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -07001439 bool resumeWithAppendedMotionSample) {
1440#if DEBUG_DISPATCH_CYCLE
Jeff Brown53a415e2010-09-15 15:18:56 -07001441 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001442 "xOffset=%f, yOffset=%f, "
1443 "windowType=%d, pointerIds=0x%x, "
1444 "resumeWithAppendedMotionSample=%s",
Jeff Brown53a415e2010-09-15 15:18:56 -07001445 connection->getInputChannelName(), inputTarget->flags,
Jeff Browne839a582010-04-22 18:58:52 -07001446 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001447 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Browna665ca82010-09-08 11:49:43 -07001448 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -07001449#endif
1450
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001451 // Make sure we are never called for streaming when splitting across multiple windows.
1452 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1453 assert(! (resumeWithAppendedMotionSample && isSplit));
1454
Jeff Browne839a582010-04-22 18:58:52 -07001455 // Skip this event if the connection status is not normal.
Jeff Brown53a415e2010-09-15 15:18:56 -07001456 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Browne839a582010-04-22 18:58:52 -07001457 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001458#if DEBUG_DISPATCH_CYCLE
1459 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Browna665ca82010-09-08 11:49:43 -07001460 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown90f0cee2010-10-08 22:31:17 -07001461#endif
Jeff Browne839a582010-04-22 18:58:52 -07001462 return;
1463 }
1464
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001465 // Split a motion event if needed.
1466 if (isSplit) {
1467 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1468
1469 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1470 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1471 MotionEntry* splitMotionEntry = splitMotionEvent(
1472 originalMotionEntry, inputTarget->pointerIds);
1473#if DEBUG_FOCUS
1474 LOGD("channel '%s' ~ Split motion event.",
1475 connection->getInputChannelName());
1476 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1477#endif
1478 eventEntry = splitMotionEntry;
1479 }
1480 }
1481
Jeff Browne839a582010-04-22 18:58:52 -07001482 // Resume the dispatch cycle with a freshly appended motion sample.
1483 // First we check that the last dispatch entry in the outbound queue is for the same
1484 // motion event to which we appended the motion sample. If we find such a dispatch
1485 // entry, and if it is currently in progress then we try to stream the new sample.
1486 bool wasEmpty = connection->outboundQueue.isEmpty();
1487
1488 if (! wasEmpty && resumeWithAppendedMotionSample) {
1489 DispatchEntry* motionEventDispatchEntry =
1490 connection->findQueuedDispatchEntryForEvent(eventEntry);
1491 if (motionEventDispatchEntry) {
1492 // If the dispatch entry is not in progress, then we must be busy dispatching an
1493 // earlier event. Not a problem, the motion event is on the outbound queue and will
1494 // be dispatched later.
1495 if (! motionEventDispatchEntry->inProgress) {
1496#if DEBUG_BATCHING
1497 LOGD("channel '%s' ~ Not streaming because the motion event has "
1498 "not yet been dispatched. "
1499 "(Waiting for earlier events to be consumed.)",
1500 connection->getInputChannelName());
1501#endif
1502 return;
1503 }
1504
1505 // If the dispatch entry is in progress but it already has a tail of pending
1506 // motion samples, then it must mean that the shared memory buffer filled up.
1507 // Not a problem, when this dispatch cycle is finished, we will eventually start
1508 // a new dispatch cycle to process the tail and that tail includes the newly
1509 // appended motion sample.
1510 if (motionEventDispatchEntry->tailMotionSample) {
1511#if DEBUG_BATCHING
1512 LOGD("channel '%s' ~ Not streaming because no new samples can "
1513 "be appended to the motion event in this dispatch cycle. "
1514 "(Waiting for next dispatch cycle to start.)",
1515 connection->getInputChannelName());
1516#endif
1517 return;
1518 }
1519
1520 // The dispatch entry is in progress and is still potentially open for streaming.
1521 // Try to stream the new motion sample. This might fail if the consumer has already
1522 // consumed the motion event (or if the channel is broken).
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001523 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1524 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Browne839a582010-04-22 18:58:52 -07001525 status_t status = connection->inputPublisher.appendMotionSample(
1526 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1527 if (status == OK) {
1528#if DEBUG_BATCHING
1529 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1530 connection->getInputChannelName());
1531#endif
1532 return;
1533 }
1534
1535#if DEBUG_BATCHING
1536 if (status == NO_MEMORY) {
1537 LOGD("channel '%s' ~ Could not append motion sample to currently "
1538 "dispatched move event because the shared memory buffer is full. "
1539 "(Waiting for next dispatch cycle to start.)",
1540 connection->getInputChannelName());
1541 } else if (status == status_t(FAILED_TRANSACTION)) {
1542 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown50de30a2010-06-22 01:27:15 -07001543 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-04-22 18:58:52 -07001544 "(Waiting for next dispatch cycle to start.)",
1545 connection->getInputChannelName());
1546 } else {
1547 LOGD("channel '%s' ~ Could not append motion sample to currently "
1548 "dispatched move event due to an error, status=%d. "
1549 "(Waiting for next dispatch cycle to start.)",
1550 connection->getInputChannelName(), status);
1551 }
1552#endif
1553 // Failed to stream. Start a new tail of pending motion samples to dispatch
1554 // in the next cycle.
1555 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1556 return;
1557 }
1558 }
1559
1560 // This is a new event.
1561 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Browna665ca82010-09-08 11:49:43 -07001562 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown53a415e2010-09-15 15:18:56 -07001563 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1564 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001565 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001566 }
1567
Jeff Browne839a582010-04-22 18:58:52 -07001568 // Handle the case where we could not stream a new motion sample because the consumer has
1569 // already consumed the motion event (otherwise the corresponding dispatch entry would
1570 // still be in the outbound queue for this connection). We set the head motion sample
1571 // to the list starting with the newly appended motion sample.
1572 if (resumeWithAppendedMotionSample) {
1573#if DEBUG_BATCHING
1574 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1575 "that cannot be streamed because the motion event has already been consumed.",
1576 connection->getInputChannelName());
1577#endif
1578 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1579 dispatchEntry->headMotionSample = appendedMotionSample;
1580 }
1581
1582 // Enqueue the dispatch entry.
1583 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1584
1585 // If the outbound queue was previously empty, start the dispatch cycle going.
1586 if (wasEmpty) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001587 activateConnectionLocked(connection.get());
Jeff Brown53a415e2010-09-15 15:18:56 -07001588 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001589 }
1590}
1591
Jeff Brown51d45a72010-06-17 20:52:56 -07001592void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown53a415e2010-09-15 15:18:56 -07001593 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001594#if DEBUG_DISPATCH_CYCLE
1595 LOGD("channel '%s' ~ startDispatchCycle",
1596 connection->getInputChannelName());
1597#endif
1598
1599 assert(connection->status == Connection::STATUS_NORMAL);
1600 assert(! connection->outboundQueue.isEmpty());
1601
Jeff Browna665ca82010-09-08 11:49:43 -07001602 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001603 assert(! dispatchEntry->inProgress);
1604
Jeff Browna665ca82010-09-08 11:49:43 -07001605 // Mark the dispatch entry as in progress.
1606 dispatchEntry->inProgress = true;
1607
1608 // Update the connection's input state.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001609 EventEntry* eventEntry = dispatchEntry->eventEntry;
1610 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001611
1612#if FILTER_INPUT_EVENTS
1613 // Filter out inconsistent sequences of input events.
1614 // The input system may drop or inject events in a way that could violate implicit
1615 // invariants on input state and potentially cause an application to crash
1616 // or think that a key or pointer is stuck down. Technically we make no guarantees
1617 // of consistency but it would be nice to improve on this where possible.
1618 // XXX: This code is a proof of concept only. Not ready for prime time.
1619 if (consistency == InputState::TOLERABLE) {
1620#if DEBUG_DISPATCH_CYCLE
1621 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1622 "current input state but that is likely to be tolerated by the application.",
1623 connection->getInputChannelName());
1624#endif
1625 } else if (consistency == InputState::BROKEN) {
1626 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1627 "current input state and that is likely to cause the application to crash.",
1628 connection->getInputChannelName());
1629 startNextDispatchCycleLocked(currentTime, connection);
1630 return;
1631 }
1632#endif
Jeff Browne839a582010-04-22 18:58:52 -07001633
1634 // Publish the event.
1635 status_t status;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001636 switch (eventEntry->type) {
Jeff Browne839a582010-04-22 18:58:52 -07001637 case EventEntry::TYPE_KEY: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001638 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001639
1640 // Apply target flags.
1641 int32_t action = keyEntry->action;
1642 int32_t flags = keyEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001643
1644 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001645 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-04-22 18:58:52 -07001646 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1647 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1648 keyEntry->eventTime);
1649
1650 if (status) {
1651 LOGE("channel '%s' ~ Could not publish key event, "
1652 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001653 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001654 return;
1655 }
1656 break;
1657 }
1658
1659 case EventEntry::TYPE_MOTION: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001660 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001661
1662 // Apply target flags.
1663 int32_t action = motionEntry->action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07001664 int32_t flags = motionEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001665 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001666 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -07001667 }
Jeff Brownaf30ff62010-09-01 17:01:00 -07001668 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1669 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1670 }
Jeff Browne839a582010-04-22 18:58:52 -07001671
1672 // If headMotionSample is non-NULL, then it points to the first new sample that we
1673 // were unable to dispatch during the previous cycle so we resume dispatching from
1674 // that point in the list of motion samples.
1675 // Otherwise, we just start from the first sample of the motion event.
1676 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1677 if (! firstMotionSample) {
1678 firstMotionSample = & motionEntry->firstSample;
1679 }
1680
Jeff Brownf26db0d2010-07-16 17:21:06 -07001681 // Set the X and Y offset depending on the input source.
1682 float xOffset, yOffset;
1683 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1684 xOffset = dispatchEntry->xOffset;
1685 yOffset = dispatchEntry->yOffset;
1686 } else {
1687 xOffset = 0.0f;
1688 yOffset = 0.0f;
1689 }
1690
Jeff Browne839a582010-04-22 18:58:52 -07001691 // Publish the motion event and the first motion sample.
1692 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001693 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -07001694 xOffset, yOffset,
Jeff Browne839a582010-04-22 18:58:52 -07001695 motionEntry->xPrecision, motionEntry->yPrecision,
1696 motionEntry->downTime, firstMotionSample->eventTime,
1697 motionEntry->pointerCount, motionEntry->pointerIds,
1698 firstMotionSample->pointerCoords);
1699
1700 if (status) {
1701 LOGE("channel '%s' ~ Could not publish motion event, "
1702 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001703 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001704 return;
1705 }
1706
1707 // Append additional motion samples.
1708 MotionSample* nextMotionSample = firstMotionSample->next;
1709 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1710 status = connection->inputPublisher.appendMotionSample(
1711 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1712 if (status == NO_MEMORY) {
1713#if DEBUG_DISPATCH_CYCLE
1714 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1715 "be sent in the next dispatch cycle.",
1716 connection->getInputChannelName());
1717#endif
1718 break;
1719 }
1720 if (status != OK) {
1721 LOGE("channel '%s' ~ Could not append motion sample "
1722 "for a reason other than out of memory, status=%d",
1723 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001724 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001725 return;
1726 }
1727 }
1728
1729 // Remember the next motion sample that we could not dispatch, in case we ran out
1730 // of space in the shared memory buffer.
1731 dispatchEntry->tailMotionSample = nextMotionSample;
1732 break;
1733 }
1734
1735 default: {
1736 assert(false);
1737 }
1738 }
1739
1740 // Send the dispatch signal.
1741 status = connection->inputPublisher.sendDispatchSignal();
1742 if (status) {
1743 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1744 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001745 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001746 return;
1747 }
1748
1749 // Record information about the newly started dispatch cycle.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001750 connection->lastEventTime = eventEntry->eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07001751 connection->lastDispatchTime = currentTime;
1752
Jeff Browne839a582010-04-22 18:58:52 -07001753 // Notify other system components.
1754 onDispatchCycleStartedLocked(currentTime, connection);
1755}
1756
Jeff Brown51d45a72010-06-17 20:52:56 -07001757void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1758 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001759#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001760 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -07001761 "%01.1fms since dispatch",
1762 connection->getInputChannelName(),
1763 connection->getEventLatencyMillis(currentTime),
1764 connection->getDispatchLatencyMillis(currentTime));
1765#endif
1766
Jeff Brown54bc2812010-06-15 01:31:58 -07001767 if (connection->status == Connection::STATUS_BROKEN
1768 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001769 return;
1770 }
1771
Jeff Brown53a415e2010-09-15 15:18:56 -07001772 // Notify other system components.
1773 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001774
1775 // Reset the publisher since the event has been consumed.
1776 // We do this now so that the publisher can release some of its internal resources
1777 // while waiting for the next dispatch cycle to begin.
1778 status_t status = connection->inputPublisher.reset();
1779 if (status) {
1780 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1781 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001782 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001783 return;
1784 }
1785
Jeff Browna665ca82010-09-08 11:49:43 -07001786 startNextDispatchCycleLocked(currentTime, connection);
1787}
1788
1789void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1790 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001791 // Start the next dispatch cycle for this connection.
1792 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001793 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001794 if (dispatchEntry->inProgress) {
1795 // Finish or resume current event in progress.
1796 if (dispatchEntry->tailMotionSample) {
1797 // We have a tail of undispatched motion samples.
1798 // Reuse the same DispatchEntry and start a new cycle.
1799 dispatchEntry->inProgress = false;
1800 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1801 dispatchEntry->tailMotionSample = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07001802 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001803 return;
1804 }
1805 // Finished.
1806 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001807 if (dispatchEntry->hasForegroundTarget()) {
1808 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001809 }
Jeff Browne839a582010-04-22 18:58:52 -07001810 mAllocator.releaseDispatchEntry(dispatchEntry);
1811 } else {
1812 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown53a415e2010-09-15 15:18:56 -07001813 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001814 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001815 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001816 return;
1817 }
1818 }
1819
1820 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001821 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001822}
1823
Jeff Brown90f0cee2010-10-08 22:31:17 -07001824void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1825 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001826#if DEBUG_DISPATCH_CYCLE
Jeff Brown90f0cee2010-10-08 22:31:17 -07001827 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001828 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001829#endif
1830
Jeff Browna665ca82010-09-08 11:49:43 -07001831 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001832 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001833
Jeff Brown90f0cee2010-10-08 22:31:17 -07001834 // The connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001835 // Ignore already broken or zombie connections.
Jeff Brown90f0cee2010-10-08 22:31:17 -07001836 if (connection->status == Connection::STATUS_NORMAL) {
1837 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001838
Jeff Brown90f0cee2010-10-08 22:31:17 -07001839 // Notify other system components.
1840 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001841 }
Jeff Browne839a582010-04-22 18:58:52 -07001842}
1843
Jeff Brown53a415e2010-09-15 15:18:56 -07001844void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1845 while (! connection->outboundQueue.isEmpty()) {
1846 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1847 if (dispatchEntry->hasForegroundTarget()) {
1848 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001849 }
1850 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001851 }
1852
Jeff Brown53a415e2010-09-15 15:18:56 -07001853 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001854}
1855
Jeff Brown59abe7e2010-09-13 23:17:30 -07001856int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-04-22 18:58:52 -07001857 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1858
1859 { // acquire lock
1860 AutoMutex _l(d->mLock);
1861
1862 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1863 if (connectionIndex < 0) {
1864 LOGE("Received spurious receive callback for unknown input channel. "
1865 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001866 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001867 }
1868
Jeff Brown51d45a72010-06-17 20:52:56 -07001869 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001870
1871 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001872 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-04-22 18:58:52 -07001873 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1874 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001875 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001876 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001877 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001878 }
1879
Jeff Brown59abe7e2010-09-13 23:17:30 -07001880 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001881 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1882 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001883 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001884 }
1885
1886 status_t status = connection->inputPublisher.receiveFinishedSignal();
1887 if (status) {
1888 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1889 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001890 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001891 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001892 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001893 }
1894
Jeff Brown51d45a72010-06-17 20:52:56 -07001895 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001896 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001897 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001898 } // release lock
1899}
1900
Jeff Brown90f0cee2010-10-08 22:31:17 -07001901void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1902 InputState::CancelationOptions options, const char* reason) {
1903 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1904 synthesizeCancelationEventsForConnectionLocked(
1905 mConnectionsByReceiveFd.valueAt(i), options, reason);
1906 }
1907}
1908
1909void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1910 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1911 const char* reason) {
1912 ssize_t index = getConnectionIndexLocked(channel);
1913 if (index >= 0) {
1914 synthesizeCancelationEventsForConnectionLocked(
1915 mConnectionsByReceiveFd.valueAt(index), options, reason);
1916 }
1917}
1918
1919void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1920 const sp<Connection>& connection, InputState::CancelationOptions options,
1921 const char* reason) {
1922 nsecs_t currentTime = now();
1923
1924 mTempCancelationEvents.clear();
1925 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1926 mTempCancelationEvents, options);
1927
1928 if (! mTempCancelationEvents.isEmpty()
1929 && connection->status != Connection::STATUS_BROKEN) {
1930#if DEBUG_OUTBOUND_EVENT_DETAILS
1931 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1932 "with reality: %s, options=%d.",
1933 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1934#endif
1935 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1936 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1937 switch (cancelationEventEntry->type) {
1938 case EventEntry::TYPE_KEY:
1939 logOutboundKeyDetailsLocked("cancel - ",
1940 static_cast<KeyEntry*>(cancelationEventEntry));
1941 break;
1942 case EventEntry::TYPE_MOTION:
1943 logOutboundMotionDetailsLocked("cancel - ",
1944 static_cast<MotionEntry*>(cancelationEventEntry));
1945 break;
1946 }
1947
1948 int32_t xOffset, yOffset;
1949 const InputWindow* window = getWindowLocked(connection->inputChannel);
1950 if (window) {
1951 xOffset = -window->frameLeft;
1952 yOffset = -window->frameTop;
1953 } else {
1954 xOffset = 0;
1955 yOffset = 0;
1956 }
1957
1958 DispatchEntry* cancelationDispatchEntry =
1959 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1960 0, xOffset, yOffset);
1961 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1962
1963 mAllocator.releaseEventEntry(cancelationEventEntry);
1964 }
1965
1966 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1967 startDispatchCycleLocked(currentTime, connection);
1968 }
1969 }
1970}
1971
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001972InputDispatcher::MotionEntry*
1973InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1974 assert(pointerIds.value != 0);
1975
1976 uint32_t splitPointerIndexMap[MAX_POINTERS];
1977 int32_t splitPointerIds[MAX_POINTERS];
1978 PointerCoords splitPointerCoords[MAX_POINTERS];
1979
1980 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1981 uint32_t splitPointerCount = 0;
1982
1983 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1984 originalPointerIndex++) {
1985 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1986 if (pointerIds.hasBit(pointerId)) {
1987 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1988 splitPointerIds[splitPointerCount] = pointerId;
1989 splitPointerCoords[splitPointerCount] =
1990 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1991 splitPointerCount += 1;
1992 }
1993 }
1994 assert(splitPointerCount == pointerIds.count());
1995
1996 int32_t action = originalMotionEntry->action;
1997 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1998 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
1999 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2000 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2001 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2002 if (pointerIds.hasBit(pointerId)) {
2003 if (pointerIds.count() == 1) {
2004 // The first/last pointer went down/up.
2005 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2006 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brownffb16d62010-09-27 16:35:11 -07002007 } else {
2008 // A secondary pointer went down/up.
2009 uint32_t splitPointerIndex = 0;
2010 while (pointerId != splitPointerIds[splitPointerIndex]) {
2011 splitPointerIndex += 1;
2012 }
2013 action = maskedAction | (splitPointerIndex
2014 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002015 }
2016 } else {
2017 // An unrelated pointer changed.
2018 action = AMOTION_EVENT_ACTION_MOVE;
2019 }
2020 }
2021
2022 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2023 originalMotionEntry->eventTime,
2024 originalMotionEntry->deviceId,
2025 originalMotionEntry->source,
2026 originalMotionEntry->policyFlags,
2027 action,
2028 originalMotionEntry->flags,
2029 originalMotionEntry->metaState,
2030 originalMotionEntry->edgeFlags,
2031 originalMotionEntry->xPrecision,
2032 originalMotionEntry->yPrecision,
2033 originalMotionEntry->downTime,
2034 splitPointerCount, splitPointerIds, splitPointerCoords);
2035
2036 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2037 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2038 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2039 splitPointerIndex++) {
2040 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2041 splitPointerCoords[splitPointerIndex] =
2042 originalMotionSample->pointerCoords[originalPointerIndex];
2043 }
2044
2045 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2046 splitPointerCoords);
2047 }
2048
2049 return splitMotionEntry;
2050}
2051
Jeff Brown54bc2812010-06-15 01:31:58 -07002052void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002053#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -07002054 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07002055#endif
2056
Jeff Browna665ca82010-09-08 11:49:43 -07002057 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002058 { // acquire lock
2059 AutoMutex _l(mLock);
2060
Jeff Brown51d45a72010-06-17 20:52:56 -07002061 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browna665ca82010-09-08 11:49:43 -07002062 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002063 } // release lock
2064
Jeff Browna665ca82010-09-08 11:49:43 -07002065 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002066 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002067 }
2068}
2069
Jeff Brown5c1ed842010-07-14 18:48:53 -07002070void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -07002071 uint32_t policyFlags, int32_t action, int32_t flags,
2072 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2073#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002074 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07002075 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07002076 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -07002077 keyCode, scanCode, metaState, downTime);
2078#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002079 if (! validateKeyEvent(action)) {
2080 return;
2081 }
Jeff Browne839a582010-04-22 18:58:52 -07002082
Jeff Brown33d54ce2010-10-11 14:20:19 -07002083 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002084 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2085 keyCode, scanCode, /*byref*/ policyFlags);
2086
Jeff Browna665ca82010-09-08 11:49:43 -07002087 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002088 { // acquire lock
2089 AutoMutex _l(mLock);
2090
Jeff Brown51d45a72010-06-17 20:52:56 -07002091 int32_t repeatCount = 0;
2092 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002093 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07002094 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07002095
Jeff Browna665ca82010-09-08 11:49:43 -07002096 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002097 } // release lock
2098
Jeff Browna665ca82010-09-08 11:49:43 -07002099 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002100 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002101 }
2102}
2103
Jeff Brown5c1ed842010-07-14 18:48:53 -07002104void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002105 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002106 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2107 float xPrecision, float yPrecision, nsecs_t downTime) {
2108#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002109 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002110 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2111 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2112 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002113 xPrecision, yPrecision, downTime);
2114 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07002115 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002116 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07002117 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07002118 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-08-30 03:02:23 -07002119 pointerCoords[i].pressure, pointerCoords[i].size,
2120 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2121 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2122 pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -07002123 }
2124#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002125 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2126 return;
2127 }
Jeff Browne839a582010-04-22 18:58:52 -07002128
Jeff Brown33d54ce2010-10-11 14:20:19 -07002129 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002130 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2131
Jeff Browna665ca82010-09-08 11:49:43 -07002132 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002133 { // acquire lock
2134 AutoMutex _l(mLock);
2135
2136 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07002137 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07002138 // BATCHING CASE
2139 //
2140 // Try to append a move sample to the tail of the inbound queue for this device.
2141 // Give up if we encounter a non-move motion event for this device since that
2142 // means we cannot append any new samples until a new motion event has started.
Jeff Browna665ca82010-09-08 11:49:43 -07002143 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2144 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07002145 if (entry->type != EventEntry::TYPE_MOTION) {
2146 // Keep looking for motion events.
2147 continue;
2148 }
2149
2150 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2151 if (motionEntry->deviceId != deviceId) {
2152 // Keep looking for this device.
2153 continue;
2154 }
2155
Jeff Brown5c1ed842010-07-14 18:48:53 -07002156 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07002157 || motionEntry->pointerCount != pointerCount
2158 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07002159 // Last motion event in the queue for this device is not compatible for
2160 // appending new samples. Stop here.
2161 goto NoBatchingOrStreaming;
2162 }
2163
2164 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07002165 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07002166 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002167#if DEBUG_BATCHING
2168 LOGD("Appended motion sample onto batch for most recent "
2169 "motion event for this device in the inbound queue.");
2170#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07002171 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002172 }
2173
2174 // STREAMING CASE
2175 //
2176 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07002177 // Search the outbound queue for the current foreground targets to find a dispatched
2178 // motion event that is still in progress. If found, then, appen the new sample to
2179 // that event and push it out to all current targets. The logic in
2180 // prepareDispatchCycleLocked takes care of the case where some targets may
2181 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown54bc2812010-06-15 01:31:58 -07002182 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002183 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2184 const InputTarget& inputTarget = mCurrentInputTargets[i];
2185 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2186 // Skip non-foreground targets. We only want to stream if there is at
2187 // least one foreground target whose dispatch is still in progress.
2188 continue;
Jeff Browne839a582010-04-22 18:58:52 -07002189 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002190
2191 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2192 if (connectionIndex < 0) {
2193 // Connection must no longer be valid.
2194 continue;
2195 }
2196
2197 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2198 if (connection->outboundQueue.isEmpty()) {
2199 // This foreground target has an empty outbound queue.
2200 continue;
2201 }
2202
2203 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2204 if (! dispatchEntry->inProgress
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002205 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2206 || dispatchEntry->isSplit()) {
2207 // No motion event is being dispatched, or it is being split across
2208 // windows in which case we cannot stream.
Jeff Brown53a415e2010-09-15 15:18:56 -07002209 continue;
2210 }
2211
2212 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2213 dispatchEntry->eventEntry);
2214 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2215 || motionEntry->deviceId != deviceId
2216 || motionEntry->pointerCount != pointerCount
2217 || motionEntry->isInjected()) {
2218 // The motion event is not compatible with this move.
2219 continue;
2220 }
2221
2222 // Hurray! This foreground target is currently dispatching a move event
2223 // that we can stream onto. Append the motion sample and resume dispatch.
2224 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2225#if DEBUG_BATCHING
2226 LOGD("Appended motion sample onto batch for most recently dispatched "
2227 "motion event for this device in the outbound queues. "
2228 "Attempting to stream the motion sample.");
2229#endif
2230 nsecs_t currentTime = now();
2231 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2232 true /*resumeWithAppendedMotionSample*/);
2233
2234 runCommandsLockedInterruptible();
2235 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002236 }
2237 }
2238
2239NoBatchingOrStreaming:;
2240 }
2241
2242 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07002243 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002244 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002245 xPrecision, yPrecision, downTime,
2246 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002247
Jeff Browna665ca82010-09-08 11:49:43 -07002248 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002249 } // release lock
2250
Jeff Browna665ca82010-09-08 11:49:43 -07002251 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002252 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002253 }
2254}
2255
Jeff Brown90f0cee2010-10-08 22:31:17 -07002256void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2257 uint32_t policyFlags) {
2258#if DEBUG_INBOUND_EVENT_DETAILS
2259 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2260 switchCode, switchValue, policyFlags);
2261#endif
2262
Jeff Brown33d54ce2010-10-11 14:20:19 -07002263 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002264 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2265}
2266
Jeff Brown51d45a72010-06-17 20:52:56 -07002267int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07002268 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002269#if DEBUG_INBOUND_EVENT_DETAILS
2270 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002271 "syncMode=%d, timeoutMillis=%d",
2272 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07002273#endif
2274
2275 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brown33d54ce2010-10-11 14:20:19 -07002276
2277 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2278 if (hasInjectionPermission(injectorPid, injectorUid)) {
2279 policyFlags |= POLICY_FLAG_TRUSTED;
2280 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002281
Jeff Brown90f0cee2010-10-08 22:31:17 -07002282 EventEntry* injectedEntry;
2283 switch (event->getType()) {
2284 case AINPUT_EVENT_TYPE_KEY: {
2285 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2286 int32_t action = keyEvent->getAction();
2287 if (! validateKeyEvent(action)) {
Jeff Browna665ca82010-09-08 11:49:43 -07002288 return INPUT_EVENT_INJECTION_FAILED;
2289 }
2290
Jeff Brown90f0cee2010-10-08 22:31:17 -07002291 nsecs_t eventTime = keyEvent->getEventTime();
2292 int32_t deviceId = keyEvent->getDeviceId();
2293 int32_t flags = keyEvent->getFlags();
2294 int32_t keyCode = keyEvent->getKeyCode();
2295 int32_t scanCode = keyEvent->getScanCode();
Jeff Brown33d54ce2010-10-11 14:20:19 -07002296 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2297 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002298
Jeff Brown90f0cee2010-10-08 22:31:17 -07002299 mLock.lock();
2300 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2301 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2302 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2303 break;
2304 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002305
Jeff Brown90f0cee2010-10-08 22:31:17 -07002306 case AINPUT_EVENT_TYPE_MOTION: {
2307 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2308 int32_t action = motionEvent->getAction();
2309 size_t pointerCount = motionEvent->getPointerCount();
2310 const int32_t* pointerIds = motionEvent->getPointerIds();
2311 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2312 return INPUT_EVENT_INJECTION_FAILED;
2313 }
2314
2315 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown33d54ce2010-10-11 14:20:19 -07002316 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002317
2318 mLock.lock();
2319 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2320 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2321 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2322 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2323 action, motionEvent->getFlags(),
2324 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2325 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2326 motionEvent->getDownTime(), uint32_t(pointerCount),
2327 pointerIds, samplePointerCoords);
2328 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2329 sampleEventTimes += 1;
2330 samplePointerCoords += pointerCount;
2331 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2332 }
2333 injectedEntry = motionEntry;
2334 break;
2335 }
2336
2337 default:
2338 LOGW("Cannot inject event of type %d", event->getType());
2339 return INPUT_EVENT_INJECTION_FAILED;
2340 }
2341
2342 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2343 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2344 injectionState->injectionIsAsync = true;
2345 }
2346
2347 injectionState->refCount += 1;
2348 injectedEntry->injectionState = injectionState;
2349
2350 bool needWake = enqueueInboundEventLocked(injectedEntry);
2351 mLock.unlock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002352
Jeff Browna665ca82010-09-08 11:49:43 -07002353 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002354 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07002355 }
2356
2357 int32_t injectionResult;
2358 { // acquire lock
2359 AutoMutex _l(mLock);
2360
Jeff Brownf67c53e2010-07-28 15:48:59 -07002361 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2362 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2363 } else {
2364 for (;;) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002365 injectionResult = injectionState->injectionResult;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002366 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2367 break;
2368 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002369
Jeff Brown51d45a72010-06-17 20:52:56 -07002370 nsecs_t remainingTimeout = endTime - now();
2371 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002372#if DEBUG_INJECTION
2373 LOGD("injectInputEvent - Timed out waiting for injection result "
2374 "to become available.");
2375#endif
Jeff Brown51d45a72010-06-17 20:52:56 -07002376 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2377 break;
2378 }
2379
Jeff Brownf67c53e2010-07-28 15:48:59 -07002380 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2381 }
2382
2383 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2384 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002385 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002386#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002387 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002388 injectionState->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002389#endif
2390 nsecs_t remainingTimeout = endTime - now();
2391 if (remainingTimeout <= 0) {
2392#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002393 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002394 "dispatches to finish.");
2395#endif
2396 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2397 break;
2398 }
2399
2400 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2401 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002402 }
2403 }
2404
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002405 mAllocator.releaseInjectionState(injectionState);
Jeff Brown51d45a72010-06-17 20:52:56 -07002406 } // release lock
2407
Jeff Brownf67c53e2010-07-28 15:48:59 -07002408#if DEBUG_INJECTION
2409 LOGD("injectInputEvent - Finished with result %d. "
2410 "injectorPid=%d, injectorUid=%d",
2411 injectionResult, injectorPid, injectorUid);
2412#endif
2413
Jeff Brown51d45a72010-06-17 20:52:56 -07002414 return injectionResult;
2415}
2416
Jeff Brown90f0cee2010-10-08 22:31:17 -07002417bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2418 return injectorUid == 0
2419 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2420}
2421
Jeff Brown51d45a72010-06-17 20:52:56 -07002422void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002423 InjectionState* injectionState = entry->injectionState;
2424 if (injectionState) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002425#if DEBUG_INJECTION
2426 LOGD("Setting input event injection result to %d. "
2427 "injectorPid=%d, injectorUid=%d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002428 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002429#endif
2430
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002431 if (injectionState->injectionIsAsync) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002432 // Log the outcome since the injector did not wait for the injection result.
2433 switch (injectionResult) {
2434 case INPUT_EVENT_INJECTION_SUCCEEDED:
2435 LOGV("Asynchronous input event injection succeeded.");
2436 break;
2437 case INPUT_EVENT_INJECTION_FAILED:
2438 LOGW("Asynchronous input event injection failed.");
2439 break;
2440 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2441 LOGW("Asynchronous input event injection permission denied.");
2442 break;
2443 case INPUT_EVENT_INJECTION_TIMED_OUT:
2444 LOGW("Asynchronous input event injection timed out.");
2445 break;
2446 }
2447 }
2448
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002449 injectionState->injectionResult = injectionResult;
Jeff Brown51d45a72010-06-17 20:52:56 -07002450 mInjectionResultAvailableCondition.broadcast();
2451 }
2452}
2453
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002454void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2455 InjectionState* injectionState = entry->injectionState;
2456 if (injectionState) {
2457 injectionState->pendingForegroundDispatches += 1;
2458 }
2459}
2460
Jeff Brown53a415e2010-09-15 15:18:56 -07002461void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002462 InjectionState* injectionState = entry->injectionState;
2463 if (injectionState) {
2464 injectionState->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002465
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002466 if (injectionState->pendingForegroundDispatches == 0) {
2467 mInjectionSyncFinishedCondition.broadcast();
2468 }
Jeff Browna665ca82010-09-08 11:49:43 -07002469 }
2470}
2471
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002472const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2473 for (size_t i = 0; i < mWindows.size(); i++) {
2474 const InputWindow* window = & mWindows[i];
2475 if (window->inputChannel == inputChannel) {
2476 return window;
2477 }
2478 }
2479 return NULL;
2480}
2481
Jeff Browna665ca82010-09-08 11:49:43 -07002482void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2483#if DEBUG_FOCUS
2484 LOGD("setInputWindows");
2485#endif
2486 { // acquire lock
2487 AutoMutex _l(mLock);
2488
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002489 // Clear old window pointers.
Jeff Brown90f0cee2010-10-08 22:31:17 -07002490 sp<InputChannel> oldFocusedWindowChannel;
2491 if (mFocusedWindow) {
2492 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2493 mFocusedWindow = NULL;
2494 }
2495
Jeff Browna665ca82010-09-08 11:49:43 -07002496 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002497
2498 // Loop over new windows and rebuild the necessary window pointers for
2499 // tracking focus and touch.
Jeff Browna665ca82010-09-08 11:49:43 -07002500 mWindows.appendVector(inputWindows);
2501
2502 size_t numWindows = mWindows.size();
2503 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002504 const InputWindow* window = & mWindows.itemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07002505 if (window->hasFocus) {
2506 mFocusedWindow = window;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002507 break;
Jeff Browna665ca82010-09-08 11:49:43 -07002508 }
2509 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002510
Jeff Brown90f0cee2010-10-08 22:31:17 -07002511 if (oldFocusedWindowChannel != NULL) {
2512 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2513#if DEBUG_FOCUS
2514 LOGD("Focus left window: %s",
2515 oldFocusedWindowChannel->getName().string());
2516#endif
2517 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2518 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2519 oldFocusedWindowChannel.clear();
2520 }
2521 }
2522 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2523#if DEBUG_FOCUS
2524 LOGD("Focus entered window: %s",
2525 mFocusedWindow->inputChannel->getName().string());
2526#endif
2527 }
2528
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002529 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2530 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2531 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2532 if (window) {
2533 touchedWindow.window = window;
2534 i += 1;
2535 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -07002536#if DEBUG_FOCUS
2537 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2538#endif
Jeff Brown90f0cee2010-10-08 22:31:17 -07002539 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2540 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownb13d7b52010-10-15 16:20:51 -07002541 mTouchState.windows.removeAt(i);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002542 }
2543 }
Jeff Browna665ca82010-09-08 11:49:43 -07002544
Jeff Browna665ca82010-09-08 11:49:43 -07002545#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002546 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002547#endif
2548 } // release lock
2549
2550 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002551 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002552}
2553
2554void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2555#if DEBUG_FOCUS
2556 LOGD("setFocusedApplication");
2557#endif
2558 { // acquire lock
2559 AutoMutex _l(mLock);
2560
2561 releaseFocusedApplicationLocked();
2562
2563 if (inputApplication) {
2564 mFocusedApplicationStorage = *inputApplication;
2565 mFocusedApplication = & mFocusedApplicationStorage;
2566 }
2567
2568#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002569 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002570#endif
2571 } // release lock
2572
2573 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002574 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002575}
2576
2577void InputDispatcher::releaseFocusedApplicationLocked() {
2578 if (mFocusedApplication) {
2579 mFocusedApplication = NULL;
2580 mFocusedApplicationStorage.handle.clear();
2581 }
2582}
2583
2584void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2585#if DEBUG_FOCUS
2586 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2587#endif
2588
2589 bool changed;
2590 { // acquire lock
2591 AutoMutex _l(mLock);
2592
2593 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2594 if (mDispatchFrozen && ! frozen) {
2595 resetANRTimeoutsLocked();
2596 }
2597
2598 mDispatchEnabled = enabled;
2599 mDispatchFrozen = frozen;
2600 changed = true;
2601 } else {
2602 changed = false;
2603 }
2604
2605#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002606 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002607#endif
2608 } // release lock
2609
2610 if (changed) {
2611 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002612 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002613 }
2614}
2615
Jeff Brown744c5592010-09-27 14:52:15 -07002616bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2617 const sp<InputChannel>& toChannel) {
2618#if DEBUG_FOCUS
2619 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2620 fromChannel->getName().string(), toChannel->getName().string());
2621#endif
2622 { // acquire lock
2623 AutoMutex _l(mLock);
2624
2625 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2626 const InputWindow* toWindow = getWindowLocked(toChannel);
2627 if (! fromWindow || ! toWindow) {
2628#if DEBUG_FOCUS
2629 LOGD("Cannot transfer focus because from or to window not found.");
2630#endif
2631 return false;
2632 }
2633 if (fromWindow == toWindow) {
2634#if DEBUG_FOCUS
2635 LOGD("Trivial transfer to same window.");
2636#endif
2637 return true;
2638 }
2639
2640 bool found = false;
2641 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2642 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2643 if (touchedWindow.window == fromWindow) {
2644 int32_t oldTargetFlags = touchedWindow.targetFlags;
2645 BitSet32 pointerIds = touchedWindow.pointerIds;
2646
2647 mTouchState.windows.removeAt(i);
2648
2649 int32_t newTargetFlags = 0;
2650 if (oldTargetFlags & InputTarget::FLAG_FOREGROUND) {
2651 newTargetFlags |= InputTarget::FLAG_FOREGROUND;
2652 if (toWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) {
2653 newTargetFlags |= InputTarget::FLAG_SPLIT;
2654 }
2655 }
2656 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2657
2658 found = true;
2659 break;
2660 }
2661 }
2662
2663 if (! found) {
2664#if DEBUG_FOCUS
2665 LOGD("Focus transfer failed because from window did not have focus.");
2666#endif
2667 return false;
2668 }
2669
Jeff Brownb6702e52010-10-11 18:32:20 -07002670 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2671 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2672 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2673 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2674 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2675
2676 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2677 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2678 InputState::CANCEL_POINTER_EVENTS,
2679 "transferring touch focus from this window to another window");
2680 }
2681
Jeff Brown744c5592010-09-27 14:52:15 -07002682#if DEBUG_FOCUS
2683 logDispatchStateLocked();
2684#endif
2685 } // release lock
2686
2687 // Wake up poll loop since it may need to make new input dispatching choices.
2688 mLooper->wake();
2689 return true;
2690}
2691
Jeff Browna665ca82010-09-08 11:49:43 -07002692void InputDispatcher::logDispatchStateLocked() {
2693 String8 dump;
2694 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002695
2696 char* text = dump.lockBuffer(dump.size());
2697 char* start = text;
2698 while (*start != '\0') {
2699 char* end = strchr(start, '\n');
2700 if (*end == '\n') {
2701 *(end++) = '\0';
2702 }
2703 LOGD("%s", start);
2704 start = end;
2705 }
Jeff Browna665ca82010-09-08 11:49:43 -07002706}
2707
2708void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002709 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2710 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002711
2712 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002713 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002714 mFocusedApplication->name.string(),
2715 mFocusedApplication->dispatchingTimeout / 1000000.0);
2716 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002717 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002718 }
Jeff Brown2806e382010-10-01 17:46:21 -07002719 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002720 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-10-01 17:46:21 -07002721
2722 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2723 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2724 if (!mTouchState.windows.isEmpty()) {
2725 dump.append(INDENT "TouchedWindows:\n");
2726 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2727 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2728 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2729 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2730 touchedWindow.targetFlags);
2731 }
2732 } else {
2733 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002734 }
2735
Jeff Brown2806e382010-10-01 17:46:21 -07002736 if (!mWindows.isEmpty()) {
2737 dump.append(INDENT "Windows:\n");
2738 for (size_t i = 0; i < mWindows.size(); i++) {
2739 const InputWindow& window = mWindows[i];
2740 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2741 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2742 "frame=[%d,%d][%d,%d], "
2743 "visibleFrame=[%d,%d][%d,%d], "
2744 "touchableArea=[%d,%d][%d,%d], "
2745 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2746 i, window.name.string(),
2747 toString(window.paused),
2748 toString(window.hasFocus),
2749 toString(window.hasWallpaper),
2750 toString(window.visible),
2751 toString(window.canReceiveKeys),
2752 window.layoutParamsFlags, window.layoutParamsType,
2753 window.layer,
2754 window.frameLeft, window.frameTop,
2755 window.frameRight, window.frameBottom,
2756 window.visibleFrameLeft, window.visibleFrameTop,
2757 window.visibleFrameRight, window.visibleFrameBottom,
2758 window.touchableAreaLeft, window.touchableAreaTop,
2759 window.touchableAreaRight, window.touchableAreaBottom,
2760 window.ownerPid, window.ownerUid,
2761 window.dispatchingTimeout / 1000000.0);
2762 }
2763 } else {
2764 dump.append(INDENT "Windows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002765 }
2766
Jeff Brown2806e382010-10-01 17:46:21 -07002767 if (!mMonitoringChannels.isEmpty()) {
2768 dump.append(INDENT "MonitoringChannels:\n");
2769 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2770 const sp<InputChannel>& channel = mMonitoringChannels[i];
2771 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2772 }
2773 } else {
2774 dump.append(INDENT "MonitoringChannels: <none>\n");
2775 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002776
Jeff Brown2806e382010-10-01 17:46:21 -07002777 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2778
2779 if (!mActiveConnections.isEmpty()) {
2780 dump.append(INDENT "ActiveConnections:\n");
2781 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2782 const Connection* connection = mActiveConnections[i];
2783 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
Jeff Brown90f0cee2010-10-08 22:31:17 -07002784 "inputState.isNeutral=%s\n",
Jeff Brown2806e382010-10-01 17:46:21 -07002785 i, connection->getInputChannelName(), connection->getStatusLabel(),
2786 connection->outboundQueue.count(),
Jeff Brown90f0cee2010-10-08 22:31:17 -07002787 toString(connection->inputState.isNeutral()));
Jeff Brown2806e382010-10-01 17:46:21 -07002788 }
2789 } else {
2790 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002791 }
2792
2793 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002794 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002795 (mAppSwitchDueTime - now()) / 1000000.0);
2796 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002797 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002798 }
2799}
2800
2801status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002802#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002803 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2804 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002805#endif
2806
Jeff Browne839a582010-04-22 18:58:52 -07002807 { // acquire lock
2808 AutoMutex _l(mLock);
2809
Jeff Brown53a415e2010-09-15 15:18:56 -07002810 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002811 LOGW("Attempted to register already registered input channel '%s'",
2812 inputChannel->getName().string());
2813 return BAD_VALUE;
2814 }
2815
2816 sp<Connection> connection = new Connection(inputChannel);
2817 status_t status = connection->initialize();
2818 if (status) {
2819 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2820 inputChannel->getName().string(), status);
2821 return status;
2822 }
2823
Jeff Brown0cacb872010-08-17 15:59:26 -07002824 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002825 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002826
Jeff Browna665ca82010-09-08 11:49:43 -07002827 if (monitor) {
2828 mMonitoringChannels.push(inputChannel);
2829 }
2830
Jeff Brown59abe7e2010-09-13 23:17:30 -07002831 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002832
Jeff Brown54bc2812010-06-15 01:31:58 -07002833 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002834 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002835 return OK;
2836}
2837
2838status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002839#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002840 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002841#endif
2842
Jeff Browne839a582010-04-22 18:58:52 -07002843 { // acquire lock
2844 AutoMutex _l(mLock);
2845
Jeff Brown53a415e2010-09-15 15:18:56 -07002846 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002847 if (connectionIndex < 0) {
2848 LOGW("Attempted to unregister already unregistered input channel '%s'",
2849 inputChannel->getName().string());
2850 return BAD_VALUE;
2851 }
2852
2853 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2854 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2855
2856 connection->status = Connection::STATUS_ZOMBIE;
2857
Jeff Browna665ca82010-09-08 11:49:43 -07002858 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2859 if (mMonitoringChannels[i] == inputChannel) {
2860 mMonitoringChannels.removeAt(i);
2861 break;
2862 }
2863 }
2864
Jeff Brown59abe7e2010-09-13 23:17:30 -07002865 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002866
Jeff Brown51d45a72010-06-17 20:52:56 -07002867 nsecs_t currentTime = now();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002868 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002869
2870 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002871 } // release lock
2872
Jeff Browne839a582010-04-22 18:58:52 -07002873 // Wake the poll loop because removing the connection may have changed the current
2874 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002875 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002876 return OK;
2877}
2878
Jeff Brown53a415e2010-09-15 15:18:56 -07002879ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002880 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2881 if (connectionIndex >= 0) {
2882 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2883 if (connection->inputChannel.get() == inputChannel.get()) {
2884 return connectionIndex;
2885 }
2886 }
2887
2888 return -1;
2889}
2890
Jeff Browne839a582010-04-22 18:58:52 -07002891void InputDispatcher::activateConnectionLocked(Connection* connection) {
2892 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2893 if (mActiveConnections.itemAt(i) == connection) {
2894 return;
2895 }
2896 }
2897 mActiveConnections.add(connection);
2898}
2899
2900void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2901 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2902 if (mActiveConnections.itemAt(i) == connection) {
2903 mActiveConnections.removeAt(i);
2904 return;
2905 }
2906 }
2907}
2908
Jeff Brown54bc2812010-06-15 01:31:58 -07002909void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002910 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002911}
2912
Jeff Brown54bc2812010-06-15 01:31:58 -07002913void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002914 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002915}
2916
Jeff Brown54bc2812010-06-15 01:31:58 -07002917void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002918 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002919 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2920 connection->getInputChannelName());
2921
Jeff Brown54bc2812010-06-15 01:31:58 -07002922 CommandEntry* commandEntry = postCommandLocked(
2923 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002924 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002925}
2926
Jeff Brown53a415e2010-09-15 15:18:56 -07002927void InputDispatcher::onANRLocked(
2928 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2929 nsecs_t eventTime, nsecs_t waitStartTime) {
2930 LOGI("Application is not responding: %s. "
2931 "%01.1fms since event, %01.1fms since wait started",
2932 getApplicationWindowLabelLocked(application, window).string(),
2933 (currentTime - eventTime) / 1000000.0,
2934 (currentTime - waitStartTime) / 1000000.0);
2935
2936 CommandEntry* commandEntry = postCommandLocked(
2937 & InputDispatcher::doNotifyANRLockedInterruptible);
2938 if (application) {
2939 commandEntry->inputApplicationHandle = application->handle;
2940 }
2941 if (window) {
2942 commandEntry->inputChannel = window->inputChannel;
2943 }
2944}
2945
Jeff Browna665ca82010-09-08 11:49:43 -07002946void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2947 CommandEntry* commandEntry) {
2948 mLock.unlock();
2949
2950 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2951
2952 mLock.lock();
2953}
2954
Jeff Brown54bc2812010-06-15 01:31:58 -07002955void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2956 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002957 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002958
Jeff Brown51d45a72010-06-17 20:52:56 -07002959 if (connection->status != Connection::STATUS_ZOMBIE) {
2960 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002961
Jeff Brown51d45a72010-06-17 20:52:56 -07002962 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2963
2964 mLock.lock();
2965 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002966}
2967
Jeff Brown53a415e2010-09-15 15:18:56 -07002968void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002969 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002970 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002971
Jeff Brown53a415e2010-09-15 15:18:56 -07002972 nsecs_t newTimeout = mPolicy->notifyANR(
2973 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002974
Jeff Brown53a415e2010-09-15 15:18:56 -07002975 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002976
Jeff Brown53a415e2010-09-15 15:18:56 -07002977 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002978}
2979
Jeff Browna665ca82010-09-08 11:49:43 -07002980void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2981 CommandEntry* commandEntry) {
2982 KeyEntry* entry = commandEntry->keyEntry;
2983 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2984 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2985 entry->downTime, entry->eventTime);
2986
2987 mLock.unlock();
2988
2989 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2990 & mReusableKeyEvent, entry->policyFlags);
2991
2992 mLock.lock();
2993
2994 entry->interceptKeyResult = consumed
2995 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2996 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2997 mAllocator.releaseKeyEntry(entry);
2998}
2999
3000void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3001 mLock.unlock();
3002
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003003 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07003004
3005 mLock.lock();
3006}
3007
Jeff Brown53a415e2010-09-15 15:18:56 -07003008void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3009 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3010 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07003011}
3012
3013void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07003014 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07003015 dumpDispatchStateLocked(dump);
3016}
3017
Jeff Brown54bc2812010-06-15 01:31:58 -07003018
Jeff Brown53a415e2010-09-15 15:18:56 -07003019// --- InputDispatcher::Queue ---
3020
3021template <typename T>
3022uint32_t InputDispatcher::Queue<T>::count() const {
3023 uint32_t result = 0;
3024 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3025 result += 1;
3026 }
3027 return result;
3028}
3029
3030
Jeff Browne839a582010-04-22 18:58:52 -07003031// --- InputDispatcher::Allocator ---
3032
3033InputDispatcher::Allocator::Allocator() {
3034}
3035
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003036InputDispatcher::InjectionState*
3037InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3038 InjectionState* injectionState = mInjectionStatePool.alloc();
3039 injectionState->refCount = 1;
3040 injectionState->injectorPid = injectorPid;
3041 injectionState->injectorUid = injectorUid;
3042 injectionState->injectionIsAsync = false;
3043 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3044 injectionState->pendingForegroundDispatches = 0;
3045 return injectionState;
3046}
3047
Jeff Brown51d45a72010-06-17 20:52:56 -07003048void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brown90f0cee2010-10-08 22:31:17 -07003049 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown51d45a72010-06-17 20:52:56 -07003050 entry->type = type;
3051 entry->refCount = 1;
3052 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07003053 entry->eventTime = eventTime;
Jeff Brown90f0cee2010-10-08 22:31:17 -07003054 entry->policyFlags = policyFlags;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003055 entry->injectionState = NULL;
3056}
3057
3058void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3059 if (entry->injectionState) {
3060 releaseInjectionState(entry->injectionState);
3061 entry->injectionState = NULL;
3062 }
Jeff Brown51d45a72010-06-17 20:52:56 -07003063}
3064
Jeff Browne839a582010-04-22 18:58:52 -07003065InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07003066InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003067 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003068 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Browne839a582010-04-22 18:58:52 -07003069 return entry;
3070}
3071
Jeff Brown51d45a72010-06-17 20:52:56 -07003072InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07003073 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07003074 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3075 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003076 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003077 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003078
3079 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003080 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003081 entry->action = action;
3082 entry->flags = flags;
3083 entry->keyCode = keyCode;
3084 entry->scanCode = scanCode;
3085 entry->metaState = metaState;
3086 entry->repeatCount = repeatCount;
3087 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07003088 entry->syntheticRepeat = false;
3089 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07003090 return entry;
3091}
3092
Jeff Brown51d45a72010-06-17 20:52:56 -07003093InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07003094 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07003095 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3096 nsecs_t downTime, uint32_t pointerCount,
3097 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003098 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003099 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003100
3101 entry->eventTime = eventTime;
3102 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003103 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003104 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07003105 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07003106 entry->metaState = metaState;
3107 entry->edgeFlags = edgeFlags;
3108 entry->xPrecision = xPrecision;
3109 entry->yPrecision = yPrecision;
3110 entry->downTime = downTime;
3111 entry->pointerCount = pointerCount;
3112 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07003113 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07003114 entry->lastSample = & entry->firstSample;
3115 for (uint32_t i = 0; i < pointerCount; i++) {
3116 entry->pointerIds[i] = pointerIds[i];
3117 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3118 }
Jeff Browne839a582010-04-22 18:58:52 -07003119 return entry;
3120}
3121
3122InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07003123 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07003124 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07003125 DispatchEntry* entry = mDispatchEntryPool.alloc();
3126 entry->eventEntry = eventEntry;
3127 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07003128 entry->targetFlags = targetFlags;
3129 entry->xOffset = xOffset;
3130 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07003131 entry->inProgress = false;
3132 entry->headMotionSample = NULL;
3133 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07003134 return entry;
3135}
3136
Jeff Brown54bc2812010-06-15 01:31:58 -07003137InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3138 CommandEntry* entry = mCommandEntryPool.alloc();
3139 entry->command = command;
3140 return entry;
3141}
3142
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003143void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3144 injectionState->refCount -= 1;
3145 if (injectionState->refCount == 0) {
3146 mInjectionStatePool.free(injectionState);
3147 } else {
3148 assert(injectionState->refCount > 0);
3149 }
3150}
3151
Jeff Browne839a582010-04-22 18:58:52 -07003152void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3153 switch (entry->type) {
3154 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3155 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3156 break;
3157 case EventEntry::TYPE_KEY:
3158 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3159 break;
3160 case EventEntry::TYPE_MOTION:
3161 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3162 break;
3163 default:
3164 assert(false);
3165 break;
3166 }
3167}
3168
3169void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3170 ConfigurationChangedEntry* entry) {
3171 entry->refCount -= 1;
3172 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003173 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003174 mConfigurationChangeEntryPool.free(entry);
3175 } else {
3176 assert(entry->refCount > 0);
3177 }
3178}
3179
3180void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3181 entry->refCount -= 1;
3182 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003183 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003184 mKeyEntryPool.free(entry);
3185 } else {
3186 assert(entry->refCount > 0);
3187 }
3188}
3189
3190void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3191 entry->refCount -= 1;
3192 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003193 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -07003194 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3195 MotionSample* next = sample->next;
3196 mMotionSamplePool.free(sample);
3197 sample = next;
3198 }
Jeff Browne839a582010-04-22 18:58:52 -07003199 mMotionEntryPool.free(entry);
3200 } else {
3201 assert(entry->refCount > 0);
3202 }
3203}
3204
3205void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3206 releaseEventEntry(entry->eventEntry);
3207 mDispatchEntryPool.free(entry);
3208}
3209
Jeff Brown54bc2812010-06-15 01:31:58 -07003210void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3211 mCommandEntryPool.free(entry);
3212}
3213
Jeff Browne839a582010-04-22 18:58:52 -07003214void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003215 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003216 MotionSample* sample = mMotionSamplePool.alloc();
3217 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003218 uint32_t pointerCount = motionEntry->pointerCount;
3219 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07003220 sample->pointerCoords[i] = pointerCoords[i];
3221 }
3222
3223 sample->next = NULL;
3224 motionEntry->lastSample->next = sample;
3225 motionEntry->lastSample = sample;
3226}
3227
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003228void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3229 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003230
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003231 keyEntry->dispatchInProgress = false;
3232 keyEntry->syntheticRepeat = false;
3233 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003234}
3235
3236
Jeff Brown542412c2010-08-18 15:51:08 -07003237// --- InputDispatcher::MotionEntry ---
3238
3239uint32_t InputDispatcher::MotionEntry::countSamples() const {
3240 uint32_t count = 1;
3241 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3242 count += 1;
3243 }
3244 return count;
3245}
3246
Jeff Browna665ca82010-09-08 11:49:43 -07003247
3248// --- InputDispatcher::InputState ---
3249
Jeff Brown90f0cee2010-10-08 22:31:17 -07003250InputDispatcher::InputState::InputState() {
Jeff Browna665ca82010-09-08 11:49:43 -07003251}
3252
3253InputDispatcher::InputState::~InputState() {
3254}
3255
3256bool InputDispatcher::InputState::isNeutral() const {
3257 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3258}
3259
Jeff Browna665ca82010-09-08 11:49:43 -07003260InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3261 const EventEntry* entry) {
3262 switch (entry->type) {
3263 case EventEntry::TYPE_KEY:
3264 return trackKey(static_cast<const KeyEntry*>(entry));
3265
3266 case EventEntry::TYPE_MOTION:
3267 return trackMotion(static_cast<const MotionEntry*>(entry));
3268
3269 default:
3270 return CONSISTENT;
3271 }
3272}
3273
3274InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3275 const KeyEntry* entry) {
3276 int32_t action = entry->action;
3277 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3278 KeyMemento& memento = mKeyMementos.editItemAt(i);
3279 if (memento.deviceId == entry->deviceId
3280 && memento.source == entry->source
3281 && memento.keyCode == entry->keyCode
3282 && memento.scanCode == entry->scanCode) {
3283 switch (action) {
3284 case AKEY_EVENT_ACTION_UP:
3285 mKeyMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003286 return CONSISTENT;
3287
3288 case AKEY_EVENT_ACTION_DOWN:
3289 return TOLERABLE;
3290
3291 default:
3292 return BROKEN;
3293 }
3294 }
3295 }
3296
3297 switch (action) {
3298 case AKEY_EVENT_ACTION_DOWN: {
3299 mKeyMementos.push();
3300 KeyMemento& memento = mKeyMementos.editTop();
3301 memento.deviceId = entry->deviceId;
3302 memento.source = entry->source;
3303 memento.keyCode = entry->keyCode;
3304 memento.scanCode = entry->scanCode;
3305 memento.downTime = entry->downTime;
3306 return CONSISTENT;
3307 }
3308
3309 default:
3310 return BROKEN;
3311 }
3312}
3313
3314InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3315 const MotionEntry* entry) {
3316 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3317 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3318 MotionMemento& memento = mMotionMementos.editItemAt(i);
3319 if (memento.deviceId == entry->deviceId
3320 && memento.source == entry->source) {
3321 switch (action) {
3322 case AMOTION_EVENT_ACTION_UP:
3323 case AMOTION_EVENT_ACTION_CANCEL:
3324 mMotionMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003325 return CONSISTENT;
3326
3327 case AMOTION_EVENT_ACTION_DOWN:
3328 return TOLERABLE;
3329
3330 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3331 if (entry->pointerCount == memento.pointerCount + 1) {
3332 memento.setPointers(entry);
3333 return CONSISTENT;
3334 }
3335 return BROKEN;
3336
3337 case AMOTION_EVENT_ACTION_POINTER_UP:
3338 if (entry->pointerCount == memento.pointerCount - 1) {
3339 memento.setPointers(entry);
3340 return CONSISTENT;
3341 }
3342 return BROKEN;
3343
3344 case AMOTION_EVENT_ACTION_MOVE:
3345 if (entry->pointerCount == memento.pointerCount) {
3346 return CONSISTENT;
3347 }
3348 return BROKEN;
3349
3350 default:
3351 return BROKEN;
3352 }
3353 }
3354 }
3355
3356 switch (action) {
3357 case AMOTION_EVENT_ACTION_DOWN: {
3358 mMotionMementos.push();
3359 MotionMemento& memento = mMotionMementos.editTop();
3360 memento.deviceId = entry->deviceId;
3361 memento.source = entry->source;
3362 memento.xPrecision = entry->xPrecision;
3363 memento.yPrecision = entry->yPrecision;
3364 memento.downTime = entry->downTime;
3365 memento.setPointers(entry);
3366 return CONSISTENT;
3367 }
3368
3369 default:
3370 return BROKEN;
3371 }
3372}
3373
3374void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3375 pointerCount = entry->pointerCount;
3376 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3377 pointerIds[i] = entry->pointerIds[i];
3378 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3379 }
3380}
3381
Jeff Brown90f0cee2010-10-08 22:31:17 -07003382void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3383 Allocator* allocator, Vector<EventEntry*>& outEvents,
3384 CancelationOptions options) {
3385 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003386 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003387 if (shouldCancelEvent(memento.source, options)) {
3388 outEvents.push(allocator->obtainKeyEntry(currentTime,
3389 memento.deviceId, memento.source, 0,
3390 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3391 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3392 mKeyMementos.removeAt(i);
3393 } else {
3394 i += 1;
3395 }
Jeff Browna665ca82010-09-08 11:49:43 -07003396 }
3397
Jeff Brown316237d2010-10-11 18:22:53 -07003398 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003399 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003400 if (shouldCancelEvent(memento.source, options)) {
3401 outEvents.push(allocator->obtainMotionEntry(currentTime,
3402 memento.deviceId, memento.source, 0,
3403 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3404 memento.xPrecision, memento.yPrecision, memento.downTime,
3405 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3406 mMotionMementos.removeAt(i);
3407 } else {
3408 i += 1;
3409 }
Jeff Browna665ca82010-09-08 11:49:43 -07003410 }
3411}
3412
3413void InputDispatcher::InputState::clear() {
3414 mKeyMementos.clear();
3415 mMotionMementos.clear();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003416}
3417
Jeff Brownb6702e52010-10-11 18:32:20 -07003418void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3419 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3420 const MotionMemento& memento = mMotionMementos.itemAt(i);
3421 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3422 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3423 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3424 if (memento.deviceId == otherMemento.deviceId
3425 && memento.source == otherMemento.source) {
3426 other.mMotionMementos.removeAt(j);
3427 } else {
3428 j += 1;
3429 }
3430 }
3431 other.mMotionMementos.push(memento);
3432 }
3433 }
3434}
3435
Jeff Brown90f0cee2010-10-08 22:31:17 -07003436bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3437 CancelationOptions options) {
3438 switch (options) {
3439 case CANCEL_POINTER_EVENTS:
3440 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3441 case CANCEL_NON_POINTER_EVENTS:
3442 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3443 default:
3444 return true;
3445 }
Jeff Browna665ca82010-09-08 11:49:43 -07003446}
3447
3448
Jeff Browne839a582010-04-22 18:58:52 -07003449// --- InputDispatcher::Connection ---
3450
3451InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3452 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003453 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003454}
3455
3456InputDispatcher::Connection::~Connection() {
3457}
3458
3459status_t InputDispatcher::Connection::initialize() {
3460 return inputPublisher.initialize();
3461}
3462
Jeff Brown54bc2812010-06-15 01:31:58 -07003463const char* InputDispatcher::Connection::getStatusLabel() const {
3464 switch (status) {
3465 case STATUS_NORMAL:
3466 return "NORMAL";
3467
3468 case STATUS_BROKEN:
3469 return "BROKEN";
3470
Jeff Brown54bc2812010-06-15 01:31:58 -07003471 case STATUS_ZOMBIE:
3472 return "ZOMBIE";
3473
3474 default:
3475 return "UNKNOWN";
3476 }
3477}
3478
Jeff Browne839a582010-04-22 18:58:52 -07003479InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3480 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003481 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3482 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003483 if (dispatchEntry->eventEntry == eventEntry) {
3484 return dispatchEntry;
3485 }
3486 }
3487 return NULL;
3488}
3489
Jeff Browna665ca82010-09-08 11:49:43 -07003490
Jeff Brown54bc2812010-06-15 01:31:58 -07003491// --- InputDispatcher::CommandEntry ---
3492
Jeff Browna665ca82010-09-08 11:49:43 -07003493InputDispatcher::CommandEntry::CommandEntry() :
3494 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003495}
3496
3497InputDispatcher::CommandEntry::~CommandEntry() {
3498}
3499
Jeff Browne839a582010-04-22 18:58:52 -07003500
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003501// --- InputDispatcher::TouchState ---
3502
3503InputDispatcher::TouchState::TouchState() :
3504 down(false), split(false) {
3505}
3506
3507InputDispatcher::TouchState::~TouchState() {
3508}
3509
3510void InputDispatcher::TouchState::reset() {
3511 down = false;
3512 split = false;
3513 windows.clear();
3514}
3515
3516void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3517 down = other.down;
3518 split = other.split;
3519 windows.clear();
3520 windows.appendVector(other.windows);
3521}
3522
3523void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3524 int32_t targetFlags, BitSet32 pointerIds) {
3525 if (targetFlags & InputTarget::FLAG_SPLIT) {
3526 split = true;
3527 }
3528
3529 for (size_t i = 0; i < windows.size(); i++) {
3530 TouchedWindow& touchedWindow = windows.editItemAt(i);
3531 if (touchedWindow.window == window) {
3532 touchedWindow.targetFlags |= targetFlags;
3533 touchedWindow.pointerIds.value |= pointerIds.value;
3534 return;
3535 }
3536 }
3537
3538 windows.push();
3539
3540 TouchedWindow& touchedWindow = windows.editTop();
3541 touchedWindow.window = window;
3542 touchedWindow.targetFlags = targetFlags;
3543 touchedWindow.pointerIds = pointerIds;
3544 touchedWindow.channel = window->inputChannel;
3545}
3546
3547void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3548 for (size_t i = 0 ; i < windows.size(); ) {
3549 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3550 windows.removeAt(i);
3551 } else {
3552 i += 1;
3553 }
3554 }
3555}
3556
3557const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3558 for (size_t i = 0; i < windows.size(); i++) {
3559 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3560 return windows[i].window;
3561 }
3562 }
3563 return NULL;
3564}
3565
3566
Jeff Browne839a582010-04-22 18:58:52 -07003567// --- InputDispatcherThread ---
3568
3569InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3570 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3571}
3572
3573InputDispatcherThread::~InputDispatcherThread() {
3574}
3575
3576bool InputDispatcherThread::threadLoop() {
3577 mDispatcher->dispatchOnce();
3578 return true;
3579}
3580
3581} // namespace android