blob: 303075f1bc7c6ec445519194d511aa643082ce40 [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 Brownd9dd44d2010-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 }
Jeff Brownef3a8232010-10-18 13:21:23 -0700343
344 // Poke user activity for this event.
345 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
346 pokeUserActivityLocked(mPendingEvent);
347 }
Jeff Browna665ca82010-09-08 11:49:43 -0700348 }
349
350 // Now we have an event to dispatch.
351 assert(mPendingEvent != NULL);
Jeff Brownd8816c32010-09-16 14:07:33 -0700352 bool done = false;
Jeff Brown90f0cee2010-10-08 22:31:17 -0700353 DropReason dropReason = DROP_REASON_NOT_DROPPED;
354 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
355 dropReason = DROP_REASON_POLICY;
356 } else if (!mDispatchEnabled) {
357 dropReason = DROP_REASON_DISABLED;
358 }
Jeff Browna665ca82010-09-08 11:49:43 -0700359 switch (mPendingEvent->type) {
360 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
361 ConfigurationChangedEntry* typedEntry =
362 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brownd8816c32010-09-16 14:07:33 -0700363 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700364 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Browna665ca82010-09-08 11:49:43 -0700365 break;
366 }
367
368 case EventEntry::TYPE_KEY: {
369 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700370 if (isAppSwitchDue) {
371 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700372 resetPendingAppSwitchLocked(true);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700373 isAppSwitchDue = false;
374 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
375 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700376 }
377 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700378 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700379 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700380 break;
381 }
382
383 case EventEntry::TYPE_MOTION: {
384 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700385 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
386 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700387 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700388 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700389 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700390 break;
391 }
392
393 default:
394 assert(false);
Jeff Browna665ca82010-09-08 11:49:43 -0700395 break;
396 }
397
Jeff Brownd8816c32010-09-16 14:07:33 -0700398 if (done) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700399 if (dropReason != DROP_REASON_NOT_DROPPED) {
400 dropInboundEventLocked(mPendingEvent, dropReason);
401 }
402
Jeff Brownd8816c32010-09-16 14:07:33 -0700403 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700404 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
405 }
406}
407
408bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
409 bool needWake = mInboundQueue.isEmpty();
410 mInboundQueue.enqueueAtTail(entry);
411
412 switch (entry->type) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700413 case EventEntry::TYPE_KEY: {
414 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
415 if (isAppSwitchKeyEventLocked(keyEntry)) {
416 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
417 mAppSwitchSawKeyDown = true;
418 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
419 if (mAppSwitchSawKeyDown) {
420#if DEBUG_APP_SWITCH
421 LOGD("App switch is pending!");
422#endif
423 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
424 mAppSwitchSawKeyDown = false;
425 needWake = true;
426 }
427 }
428 }
Jeff Browna665ca82010-09-08 11:49:43 -0700429 break;
430 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700431 }
Jeff Browna665ca82010-09-08 11:49:43 -0700432
433 return needWake;
434}
435
Jeff Brown90f0cee2010-10-08 22:31:17 -0700436void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
437 const char* reason;
438 switch (dropReason) {
439 case DROP_REASON_POLICY:
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700440#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Browna8ed8562010-10-11 23:32:49 -0700441 LOGD("Dropped event because policy consumed it.");
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700442#endif
Jeff Browna8ed8562010-10-11 23:32:49 -0700443 reason = "inbound event was dropped because the policy consumed it";
Jeff Brown90f0cee2010-10-08 22:31:17 -0700444 break;
445 case DROP_REASON_DISABLED:
446 LOGI("Dropped event because input dispatch is disabled.");
447 reason = "inbound event was dropped because input dispatch is disabled";
448 break;
449 case DROP_REASON_APP_SWITCH:
450 LOGI("Dropped event because of pending overdue app switch.");
451 reason = "inbound event was dropped because of pending overdue app switch";
452 break;
453 default:
454 assert(false);
455 return;
456 }
457
458 switch (entry->type) {
459 case EventEntry::TYPE_KEY:
460 synthesizeCancelationEventsForAllConnectionsLocked(
461 InputState::CANCEL_NON_POINTER_EVENTS, reason);
462 break;
463 case EventEntry::TYPE_MOTION: {
464 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
465 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
466 synthesizeCancelationEventsForAllConnectionsLocked(
467 InputState::CANCEL_POINTER_EVENTS, reason);
468 } else {
469 synthesizeCancelationEventsForAllConnectionsLocked(
470 InputState::CANCEL_NON_POINTER_EVENTS, reason);
471 }
472 break;
473 }
474 }
475}
476
477bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Browna665ca82010-09-08 11:49:43 -0700478 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
479}
480
Jeff Brown90f0cee2010-10-08 22:31:17 -0700481bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
482 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
483 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700484 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brown90f0cee2010-10-08 22:31:17 -0700485 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
486}
487
Jeff Browna665ca82010-09-08 11:49:43 -0700488bool InputDispatcher::isAppSwitchPendingLocked() {
489 return mAppSwitchDueTime != LONG_LONG_MAX;
490}
491
Jeff Browna665ca82010-09-08 11:49:43 -0700492void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
493 mAppSwitchDueTime = LONG_LONG_MAX;
494
495#if DEBUG_APP_SWITCH
496 if (handled) {
497 LOGD("App switch has arrived.");
498 } else {
499 LOGD("App switch was abandoned.");
500 }
501#endif
Jeff Browne839a582010-04-22 18:58:52 -0700502}
503
Jeff Brown54bc2812010-06-15 01:31:58 -0700504bool InputDispatcher::runCommandsLockedInterruptible() {
505 if (mCommandQueue.isEmpty()) {
506 return false;
507 }
Jeff Browne839a582010-04-22 18:58:52 -0700508
Jeff Brown54bc2812010-06-15 01:31:58 -0700509 do {
510 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
511
512 Command command = commandEntry->command;
513 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
514
Jeff Brown51d45a72010-06-17 20:52:56 -0700515 commandEntry->connection.clear();
Jeff Brown54bc2812010-06-15 01:31:58 -0700516 mAllocator.releaseCommandEntry(commandEntry);
517 } while (! mCommandQueue.isEmpty());
518 return true;
Jeff Browne839a582010-04-22 18:58:52 -0700519}
520
Jeff Brown54bc2812010-06-15 01:31:58 -0700521InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
522 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
523 mCommandQueue.enqueueAtTail(commandEntry);
524 return commandEntry;
525}
526
Jeff Browna665ca82010-09-08 11:49:43 -0700527void InputDispatcher::drainInboundQueueLocked() {
528 while (! mInboundQueue.isEmpty()) {
529 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brownd8816c32010-09-16 14:07:33 -0700530 releaseInboundEventLocked(entry);
Jeff Browne839a582010-04-22 18:58:52 -0700531 }
Jeff Browne839a582010-04-22 18:58:52 -0700532}
533
Jeff Brownd8816c32010-09-16 14:07:33 -0700534void InputDispatcher::releasePendingEventLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700535 if (mPendingEvent) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700536 releaseInboundEventLocked(mPendingEvent);
Jeff Browna665ca82010-09-08 11:49:43 -0700537 mPendingEvent = NULL;
538 }
539}
540
Jeff Brownd8816c32010-09-16 14:07:33 -0700541void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700542 InjectionState* injectionState = entry->injectionState;
543 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Browna665ca82010-09-08 11:49:43 -0700544#if DEBUG_DISPATCH_CYCLE
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700545 LOGD("Injected inbound event was dropped.");
Jeff Browna665ca82010-09-08 11:49:43 -0700546#endif
547 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
548 }
549 mAllocator.releaseEventEntry(entry);
550}
551
Jeff Browna665ca82010-09-08 11:49:43 -0700552void InputDispatcher::resetKeyRepeatLocked() {
553 if (mKeyRepeatState.lastKeyEntry) {
554 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
555 mKeyRepeatState.lastKeyEntry = NULL;
556 }
557}
558
559InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brown61ce3982010-09-07 10:44:57 -0700560 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown50de30a2010-06-22 01:27:15 -0700561 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
562
Jeff Brown50de30a2010-06-22 01:27:15 -0700563 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700564 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
565 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Browne839a582010-04-22 18:58:52 -0700566 if (entry->refCount == 1) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700567 mAllocator.recycleKeyEntry(entry);
Jeff Brown51d45a72010-06-17 20:52:56 -0700568 entry->eventTime = currentTime;
Jeff Brown51d45a72010-06-17 20:52:56 -0700569 entry->policyFlags = policyFlags;
Jeff Browne839a582010-04-22 18:58:52 -0700570 entry->repeatCount += 1;
571 } else {
Jeff Brown51d45a72010-06-17 20:52:56 -0700572 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700573 entry->deviceId, entry->source, policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700574 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brownf16c26d2010-07-02 15:37:36 -0700575 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Browne839a582010-04-22 18:58:52 -0700576
577 mKeyRepeatState.lastKeyEntry = newEntry;
578 mAllocator.releaseKeyEntry(entry);
579
580 entry = newEntry;
581 }
Jeff Browna665ca82010-09-08 11:49:43 -0700582 entry->syntheticRepeat = true;
583
584 // Increment reference count since we keep a reference to the event in
585 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
586 entry->refCount += 1;
Jeff Browne839a582010-04-22 18:58:52 -0700587
Jeff Brownf16c26d2010-07-02 15:37:36 -0700588 if (entry->repeatCount == 1) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700589 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brownf16c26d2010-07-02 15:37:36 -0700590 }
591
Jeff Brown61ce3982010-09-07 10:44:57 -0700592 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Browna665ca82010-09-08 11:49:43 -0700593 return entry;
Jeff Browne839a582010-04-22 18:58:52 -0700594}
595
Jeff Browna665ca82010-09-08 11:49:43 -0700596bool InputDispatcher::dispatchConfigurationChangedLocked(
597 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Browne839a582010-04-22 18:58:52 -0700598#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Browna665ca82010-09-08 11:49:43 -0700599 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
600#endif
601
602 // Reset key repeating in case a keyboard device was added or removed or something.
603 resetKeyRepeatLocked();
604
605 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
606 CommandEntry* commandEntry = postCommandLocked(
607 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
608 commandEntry->eventTime = entry->eventTime;
609 return true;
610}
611
612bool InputDispatcher::dispatchKeyLocked(
613 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700614 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700615 // Give the policy a chance to intercept the key.
616 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700617 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700618 CommandEntry* commandEntry = postCommandLocked(
619 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700620 if (mFocusedWindow) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700621 commandEntry->inputChannel = mFocusedWindow->inputChannel;
622 }
623 commandEntry->keyEntry = entry;
624 entry->refCount += 1;
625 return false; // wait for the command to run
626 } else {
627 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
628 }
629 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700630 if (*dropReason == DROP_REASON_NOT_DROPPED) {
631 *dropReason = DROP_REASON_POLICY;
632 }
Jeff Brownd8816c32010-09-16 14:07:33 -0700633 }
634
635 // Clean up if dropping the event.
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700636 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700637 resetTargetsLocked();
Jeff Browna8ed8562010-10-11 23:32:49 -0700638 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
639 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brownd8816c32010-09-16 14:07:33 -0700640 return true;
641 }
642
Jeff Browna665ca82010-09-08 11:49:43 -0700643 // Preprocessing.
644 if (! entry->dispatchInProgress) {
645 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
646
647 if (entry->repeatCount == 0
648 && entry->action == AKEY_EVENT_ACTION_DOWN
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700649 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
650 && !entry->isInjected()) {
Jeff Browna665ca82010-09-08 11:49:43 -0700651 if (mKeyRepeatState.lastKeyEntry
652 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
653 // We have seen two identical key downs in a row which indicates that the device
654 // driver is automatically generating key repeats itself. We take note of the
655 // repeat here, but we disable our own next key repeat timer since it is clear that
656 // we will not need to synthesize key repeats ourselves.
657 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
658 resetKeyRepeatLocked();
659 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
660 } else {
661 // Not a repeat. Save key down state in case we do see a repeat later.
662 resetKeyRepeatLocked();
663 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
664 }
665 mKeyRepeatState.lastKeyEntry = entry;
666 entry->refCount += 1;
667 } else if (! entry->syntheticRepeat) {
668 resetKeyRepeatLocked();
669 }
670
671 entry->dispatchInProgress = true;
Jeff Brownd8816c32010-09-16 14:07:33 -0700672 resetTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700673 }
674
675 // Identify targets.
676 if (! mCurrentInputTargetsValid) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700677 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
678 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700679 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
680 return false;
681 }
682
683 setInjectionResultLocked(entry, injectionResult);
684 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
685 return true;
686 }
687
688 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700689 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700690 }
691
692 // Dispatch the key.
693 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
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 Brown1fe6dec2010-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 Brown1fe6dec2010-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);
Jeff Browna665ca82010-09-08 11:49:43 -0700756 return true;
757}
758
759
760void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
761#if DEBUG_OUTBOUND_EVENT_DETAILS
762 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700763 "action=0x%x, flags=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700764 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700765 prefix,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700766 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
767 entry->action, entry->flags,
Jeff Browne839a582010-04-22 18:58:52 -0700768 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
769 entry->downTime);
770
771 // Print the most recent sample that we have available, this may change due to batching.
772 size_t sampleCount = 1;
Jeff Browna665ca82010-09-08 11:49:43 -0700773 const MotionSample* sample = & entry->firstSample;
Jeff Browne839a582010-04-22 18:58:52 -0700774 for (; sample->next != NULL; sample = sample->next) {
775 sampleCount += 1;
776 }
777 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -0700778 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700779 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -0700780 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -0700781 i, entry->pointerIds[i],
Jeff Brown38a7fab2010-08-30 03:02:23 -0700782 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
783 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
784 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
785 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
786 sample->pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -0700787 }
788
789 // Keep in mind that due to batching, it is possible for the number of samples actually
790 // dispatched to change before the application finally consumed them.
Jeff Brown5c1ed842010-07-14 18:48:53 -0700791 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -0700792 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
793 }
794#endif
Jeff Browne839a582010-04-22 18:58:52 -0700795}
796
797void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
798 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
799#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700800 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700801 "resumeWithAppendedMotionSample=%s",
Jeff Browna665ca82010-09-08 11:49:43 -0700802 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -0700803#endif
804
Jeff Brown54bc2812010-06-15 01:31:58 -0700805 assert(eventEntry->dispatchInProgress); // should already have been set to true
806
Jeff Brownef3a8232010-10-18 13:21:23 -0700807 pokeUserActivityLocked(eventEntry);
808
Jeff Browne839a582010-04-22 18:58:52 -0700809 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
810 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
811
Jeff Brown53a415e2010-09-15 15:18:56 -0700812 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -0700813 if (connectionIndex >= 0) {
814 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown51d45a72010-06-17 20:52:56 -0700815 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -0700816 resumeWithAppendedMotionSample);
817 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700818#if DEBUG_FOCUS
819 LOGD("Dropping event delivery to target with channel '%s' because it "
820 "is no longer registered with the input dispatcher.",
Jeff Browne839a582010-04-22 18:58:52 -0700821 inputTarget.inputChannel->getName().string());
Jeff Brown90f0cee2010-10-08 22:31:17 -0700822#endif
Jeff Browne839a582010-04-22 18:58:52 -0700823 }
824 }
825}
826
Jeff Brownd8816c32010-09-16 14:07:33 -0700827void InputDispatcher::resetTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700828 mCurrentInputTargetsValid = false;
829 mCurrentInputTargets.clear();
Jeff Browna665ca82010-09-08 11:49:43 -0700830 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
831}
832
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700833void InputDispatcher::commitTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700834 mCurrentInputTargetsValid = true;
835}
836
837int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
838 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
839 nsecs_t* nextWakeupTime) {
840 if (application == NULL && window == NULL) {
841 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
842#if DEBUG_FOCUS
843 LOGD("Waiting for system to become ready for input.");
844#endif
845 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
846 mInputTargetWaitStartTime = currentTime;
847 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
848 mInputTargetWaitTimeoutExpired = false;
849 }
850 } else {
851 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
852#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700853 LOGD("Waiting for application to become ready for input: %s",
854 getApplicationWindowLabelLocked(application, window).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700855#endif
856 nsecs_t timeout = window ? window->dispatchingTimeout :
857 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
858
859 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
860 mInputTargetWaitStartTime = currentTime;
861 mInputTargetWaitTimeoutTime = currentTime + timeout;
862 mInputTargetWaitTimeoutExpired = false;
863 }
864 }
865
866 if (mInputTargetWaitTimeoutExpired) {
867 return INPUT_EVENT_INJECTION_TIMED_OUT;
868 }
869
870 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown53a415e2010-09-15 15:18:56 -0700871 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700872
873 // Force poll loop to wake up immediately on next iteration once we get the
874 // ANR response back from the policy.
875 *nextWakeupTime = LONG_LONG_MIN;
876 return INPUT_EVENT_INJECTION_PENDING;
877 } else {
878 // Force poll loop to wake up when timeout is due.
879 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
880 *nextWakeupTime = mInputTargetWaitTimeoutTime;
881 }
882 return INPUT_EVENT_INJECTION_PENDING;
883 }
884}
885
Jeff Brown53a415e2010-09-15 15:18:56 -0700886void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
887 const sp<InputChannel>& inputChannel) {
Jeff Browna665ca82010-09-08 11:49:43 -0700888 if (newTimeout > 0) {
889 // Extend the timeout.
890 mInputTargetWaitTimeoutTime = now() + newTimeout;
891 } else {
892 // Give up.
893 mInputTargetWaitTimeoutExpired = true;
Jeff Brown53a415e2010-09-15 15:18:56 -0700894
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700895 // Release the touch targets.
896 mTouchState.reset();
Jeff Brown405a1d32010-09-16 12:31:46 -0700897
Jeff Brown53a415e2010-09-15 15:18:56 -0700898 // Input state will not be realistic. Mark it out of sync.
Jeff Brown40ad4702010-09-16 11:02:16 -0700899 if (inputChannel.get()) {
900 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
901 if (connectionIndex >= 0) {
902 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700903 synthesizeCancelationEventsForConnectionLocked(
904 connection, InputState::CANCEL_ALL_EVENTS,
905 "application not responding");
Jeff Brown40ad4702010-09-16 11:02:16 -0700906 }
Jeff Brown53a415e2010-09-15 15:18:56 -0700907 }
Jeff Browna665ca82010-09-08 11:49:43 -0700908 }
909}
910
Jeff Brown53a415e2010-09-15 15:18:56 -0700911nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Browna665ca82010-09-08 11:49:43 -0700912 nsecs_t currentTime) {
913 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
914 return currentTime - mInputTargetWaitStartTime;
915 }
916 return 0;
917}
918
919void InputDispatcher::resetANRTimeoutsLocked() {
920#if DEBUG_FOCUS
921 LOGD("Resetting ANR timeouts.");
922#endif
923
Jeff Browna665ca82010-09-08 11:49:43 -0700924 // Reset input target wait timeout.
925 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
926}
927
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700928int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
929 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -0700930 mCurrentInputTargets.clear();
931
932 int32_t injectionResult;
933
934 // If there is no currently focused window and no focused application
935 // then drop the event.
936 if (! mFocusedWindow) {
937 if (mFocusedApplication) {
938#if DEBUG_FOCUS
939 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -0700940 "focused application that may eventually add a window: %s.",
941 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700942#endif
943 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
944 mFocusedApplication, NULL, nextWakeupTime);
945 goto Unresponsive;
946 }
947
948 LOGI("Dropping event because there is no focused window or focused application.");
949 injectionResult = INPUT_EVENT_INJECTION_FAILED;
950 goto Failed;
951 }
952
953 // Check permissions.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700954 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700955 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
956 goto Failed;
957 }
958
959 // If the currently focused window is paused then keep waiting.
960 if (mFocusedWindow->paused) {
961#if DEBUG_FOCUS
962 LOGD("Waiting because focused window is paused.");
963#endif
964 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
965 mFocusedApplication, mFocusedWindow, nextWakeupTime);
966 goto Unresponsive;
967 }
968
Jeff Brown53a415e2010-09-15 15:18:56 -0700969 // If the currently focused window is still working on previous events then keep waiting.
970 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
971#if DEBUG_FOCUS
972 LOGD("Waiting because focused window still processing previous input.");
973#endif
974 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
975 mFocusedApplication, mFocusedWindow, nextWakeupTime);
976 goto Unresponsive;
977 }
978
Jeff Browna665ca82010-09-08 11:49:43 -0700979 // Success! Output targets.
980 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700981 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -0700982
983 // Done.
984Failed:
985Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -0700986 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
987 updateDispatchStatisticsLocked(currentTime, entry,
988 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -0700989#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700990 LOGD("findFocusedWindow finished: injectionResult=%d, "
991 "timeSpendWaitingForApplication=%0.1fms",
992 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -0700993#endif
994 return injectionResult;
995}
996
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700997int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
998 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -0700999 enum InjectionPermission {
1000 INJECTION_PERMISSION_UNKNOWN,
1001 INJECTION_PERMISSION_GRANTED,
1002 INJECTION_PERMISSION_DENIED
1003 };
1004
Jeff Browna665ca82010-09-08 11:49:43 -07001005 mCurrentInputTargets.clear();
1006
1007 nsecs_t startTime = now();
1008
1009 // For security reasons, we defer updating the touch state until we are sure that
1010 // event injection will be allowed.
1011 //
1012 // FIXME In the original code, screenWasOff could never be set to true.
1013 // The reason is that the POLICY_FLAG_WOKE_HERE
1014 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1015 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1016 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1017 // events upon which no preprocessing took place. So policyFlags was always 0.
1018 // In the new native input dispatcher we're a bit more careful about event
1019 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1020 // Unfortunately we obtain undesirable behavior.
1021 //
1022 // Here's what happens:
1023 //
1024 // When the device dims in anticipation of going to sleep, touches
1025 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1026 // the device to brighten and reset the user activity timer.
1027 // Touches on other windows (such as the launcher window)
1028 // are dropped. Then after a moment, the device goes to sleep. Oops.
1029 //
1030 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1031 // instead of POLICY_FLAG_WOKE_HERE...
1032 //
1033 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1034
1035 int32_t action = entry->action;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001036 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Browna665ca82010-09-08 11:49:43 -07001037
1038 // Update the touch state as needed based on the properties of the touch event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001039 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1040 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1041 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1042 mTempTouchState.reset();
1043 mTempTouchState.down = true;
1044 } else {
1045 mTempTouchState.copyFrom(mTouchState);
1046 }
Jeff Browna665ca82010-09-08 11:49:43 -07001047
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001048 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1049 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1050 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1051 /* Case 1: New splittable pointer going down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001052
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001053 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1054 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1055 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1056 const InputWindow* newTouchedWindow = NULL;
1057 const InputWindow* topErrorWindow = NULL;
Jeff Browna665ca82010-09-08 11:49:43 -07001058
1059 // Traverse windows from front to back to find touched window and outside targets.
1060 size_t numWindows = mWindows.size();
1061 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001062 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07001063 int32_t flags = window->layoutParamsFlags;
1064
1065 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1066 if (! topErrorWindow) {
1067 topErrorWindow = window;
1068 }
1069 }
1070
1071 if (window->visible) {
1072 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1073 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1074 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1075 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1076 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1077 newTouchedWindow = window;
Jeff Browna665ca82010-09-08 11:49:43 -07001078 }
1079 break; // found touched window, exit window loop
1080 }
1081 }
1082
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001083 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1084 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001085 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1086 if (isWindowObscuredAtPointLocked(window, x, y)) {
1087 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1088 }
1089
1090 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -07001091 }
1092 }
1093 }
1094
1095 // If there is an error window but it is not taking focus (typically because
1096 // it is invisible) then wait for it. Any other focused window may in
1097 // fact be in ANR state.
1098 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1099#if DEBUG_FOCUS
1100 LOGD("Waiting because system error window is pending.");
1101#endif
1102 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1103 NULL, NULL, nextWakeupTime);
1104 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1105 goto Unresponsive;
1106 }
1107
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001108 // Figure out whether splitting will be allowed for this window.
Jeff Brown1c322582010-09-28 13:24:41 -07001109 if (newTouchedWindow
1110 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001111 // New window supports splitting.
1112 isSplit = true;
1113 } else if (isSplit) {
1114 // New window does not support splitting but we have already split events.
1115 // Assign the pointer to the first foreground window we find.
1116 // (May be NULL which is why we put this code block before the next check.)
1117 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1118 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001119
Jeff Browna665ca82010-09-08 11:49:43 -07001120 // If we did not find a touched window then fail.
1121 if (! newTouchedWindow) {
1122 if (mFocusedApplication) {
1123#if DEBUG_FOCUS
1124 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -07001125 "focused application that may eventually add a new window: %s.",
1126 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -07001127#endif
1128 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1129 mFocusedApplication, NULL, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -07001130 goto Unresponsive;
1131 }
1132
1133 LOGI("Dropping event because there is no touched window or focused application.");
1134 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001135 goto Failed;
1136 }
1137
Jeff Brown35cf0e92010-10-05 12:26:23 -07001138 // Set target flags.
1139 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1140 if (isSplit) {
1141 targetFlags |= InputTarget::FLAG_SPLIT;
1142 }
1143 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1144 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1145 }
1146
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001147 // Update the temporary touch state.
1148 BitSet32 pointerIds;
1149 if (isSplit) {
1150 uint32_t pointerId = entry->pointerIds[pointerIndex];
1151 pointerIds.markBit(pointerId);
Jeff Browna665ca82010-09-08 11:49:43 -07001152 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001153 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001154 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001155 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001156
1157 // If the pointer is not currently down, then ignore the event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001158 if (! mTempTouchState.down) {
Jeff Browna665ca82010-09-08 11:49:43 -07001159 LOGI("Dropping event because the pointer is not down.");
1160 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001161 goto Failed;
1162 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001163 }
Jeff Browna665ca82010-09-08 11:49:43 -07001164
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001165 // Check permission to inject into all touched foreground windows and ensure there
1166 // is at least one touched foreground window.
1167 {
1168 bool haveForegroundWindow = false;
1169 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1170 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1171 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1172 haveForegroundWindow = true;
1173 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1174 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1175 injectionPermission = INJECTION_PERMISSION_DENIED;
1176 goto Failed;
1177 }
1178 }
1179 }
1180 if (! haveForegroundWindow) {
Jeff Browna665ca82010-09-08 11:49:43 -07001181#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001182 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Browna665ca82010-09-08 11:49:43 -07001183#endif
1184 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001185 goto Failed;
1186 }
1187
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001188 // Permission granted to injection into all touched foreground windows.
1189 injectionPermission = INJECTION_PERMISSION_GRANTED;
1190 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001191
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001192 // Ensure all touched foreground windows are ready for new input.
1193 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1194 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1195 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1196 // If the touched window is paused then keep waiting.
1197 if (touchedWindow.window->paused) {
1198#if DEBUG_INPUT_DISPATCHER_POLICY
1199 LOGD("Waiting because touched window is paused.");
Jeff Brown53a415e2010-09-15 15:18:56 -07001200#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001201 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1202 NULL, touchedWindow.window, nextWakeupTime);
1203 goto Unresponsive;
1204 }
1205
1206 // If the touched window is still working on previous events then keep waiting.
1207 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1208#if DEBUG_FOCUS
1209 LOGD("Waiting because touched window still processing previous input.");
1210#endif
1211 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1212 NULL, touchedWindow.window, nextWakeupTime);
1213 goto Unresponsive;
1214 }
1215 }
1216 }
1217
1218 // If this is the first pointer going down and the touched window has a wallpaper
1219 // then also add the touched wallpaper windows so they are locked in for the duration
1220 // of the touch gesture.
1221 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1222 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1223 if (foregroundWindow->hasWallpaper) {
1224 for (size_t i = 0; i < mWindows.size(); i++) {
1225 const InputWindow* window = & mWindows[i];
1226 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001227 mTempTouchState.addOrUpdateWindow(window,
1228 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001229 }
1230 }
1231 }
1232 }
1233
Jeff Browna665ca82010-09-08 11:49:43 -07001234 // Success! Output targets.
1235 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Browna665ca82010-09-08 11:49:43 -07001236
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001237 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1238 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1239 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1240 touchedWindow.pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001241 }
1242
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001243 // Drop the outside touch window since we will not care about them in the next iteration.
1244 mTempTouchState.removeOutsideTouchWindows();
1245
Jeff Browna665ca82010-09-08 11:49:43 -07001246Failed:
1247 // Check injection permission once and for all.
1248 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001249 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001250 injectionPermission = INJECTION_PERMISSION_GRANTED;
1251 } else {
1252 injectionPermission = INJECTION_PERMISSION_DENIED;
1253 }
1254 }
1255
1256 // Update final pieces of touch state if the injector had permission.
1257 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001258 if (maskedAction == AMOTION_EVENT_ACTION_UP
1259 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1260 // All pointers up or canceled.
1261 mTempTouchState.reset();
1262 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1263 // First pointer went down.
1264 if (mTouchState.down) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001265#if DEBUG_FOCUS
1266 LOGD("Pointer down received while already down.");
1267#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001268 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001269 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1270 // One pointer went up.
1271 if (isSplit) {
1272 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1273 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Browna665ca82010-09-08 11:49:43 -07001274
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001275 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1276 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1277 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1278 touchedWindow.pointerIds.clearBit(pointerId);
1279 if (touchedWindow.pointerIds.isEmpty()) {
1280 mTempTouchState.windows.removeAt(i);
1281 continue;
1282 }
1283 }
1284 i += 1;
1285 }
Jeff Browna665ca82010-09-08 11:49:43 -07001286 }
Jeff Browna665ca82010-09-08 11:49:43 -07001287 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001288
1289 // Save changes to touch state.
1290 mTouchState.copyFrom(mTempTouchState);
Jeff Browna665ca82010-09-08 11:49:43 -07001291 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001292#if DEBUG_FOCUS
1293 LOGD("Not updating touch focus because injection was denied.");
1294#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001295 }
1296
1297Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -07001298 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1299 updateDispatchStatisticsLocked(currentTime, entry,
1300 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001301#if DEBUG_FOCUS
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001302 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1303 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown53a415e2010-09-15 15:18:56 -07001304 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001305#endif
1306 return injectionResult;
1307}
1308
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001309void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1310 BitSet32 pointerIds) {
Jeff Browna665ca82010-09-08 11:49:43 -07001311 mCurrentInputTargets.push();
1312
1313 InputTarget& target = mCurrentInputTargets.editTop();
1314 target.inputChannel = window->inputChannel;
1315 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001316 target.xOffset = - window->frameLeft;
1317 target.yOffset = - window->frameTop;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001318 target.pointerIds = pointerIds;
Jeff Browna665ca82010-09-08 11:49:43 -07001319}
1320
1321void InputDispatcher::addMonitoringTargetsLocked() {
1322 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1323 mCurrentInputTargets.push();
1324
1325 InputTarget& target = mCurrentInputTargets.editTop();
1326 target.inputChannel = mMonitoringChannels[i];
1327 target.flags = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07001328 target.xOffset = 0;
1329 target.yOffset = 0;
1330 }
1331}
1332
1333bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001334 const InjectionState* injectionState) {
1335 if (injectionState
Jeff Brown90f0cee2010-10-08 22:31:17 -07001336 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1337 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1338 if (window) {
1339 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1340 "with input channel %s owned by uid %d",
1341 injectionState->injectorPid, injectionState->injectorUid,
1342 window->inputChannel->getName().string(),
1343 window->ownerUid);
1344 } else {
1345 LOGW("Permission denied: injecting event from pid %d uid %d",
1346 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-09-08 11:49:43 -07001347 }
Jeff Brown90f0cee2010-10-08 22:31:17 -07001348 return false;
Jeff Browna665ca82010-09-08 11:49:43 -07001349 }
1350 return true;
1351}
1352
Jeff Brown35cf0e92010-10-05 12:26:23 -07001353bool InputDispatcher::isWindowObscuredAtPointLocked(
1354 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Browna665ca82010-09-08 11:49:43 -07001355 size_t numWindows = mWindows.size();
1356 for (size_t i = 0; i < numWindows; i++) {
1357 const InputWindow* other = & mWindows.itemAt(i);
1358 if (other == window) {
1359 break;
1360 }
Jeff Brown35cf0e92010-10-05 12:26:23 -07001361 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001362 return true;
1363 }
1364 }
1365 return false;
1366}
1367
Jeff Brown53a415e2010-09-15 15:18:56 -07001368bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1369 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1370 if (connectionIndex >= 0) {
1371 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1372 return connection->outboundQueue.isEmpty();
1373 } else {
1374 return true;
1375 }
1376}
1377
1378String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1379 const InputWindow* window) {
1380 if (application) {
1381 if (window) {
1382 String8 label(application->name);
1383 label.append(" - ");
1384 label.append(window->name);
1385 return label;
1386 } else {
1387 return application->name;
1388 }
1389 } else if (window) {
1390 return window->name;
1391 } else {
1392 return String8("<unknown application or window>");
1393 }
1394}
1395
Jeff Brownef3a8232010-10-18 13:21:23 -07001396void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1397 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
1398 if (eventEntry->type == EventEntry::TYPE_MOTION) {
1399 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
1400 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1401 switch (motionEntry->action) {
1402 case AMOTION_EVENT_ACTION_DOWN:
1403 eventType = POWER_MANAGER_TOUCH_EVENT;
1404 break;
1405 case AMOTION_EVENT_ACTION_UP:
1406 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
1407 break;
1408 default:
1409 if (motionEntry->eventTime - motionEntry->downTime >= EVENT_IGNORE_DURATION) {
1410 eventType = POWER_MANAGER_TOUCH_EVENT;
1411 } else {
1412 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
1413 }
1414 break;
1415 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001416 }
1417 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001418
Jeff Browna665ca82010-09-08 11:49:43 -07001419 CommandEntry* commandEntry = postCommandLocked(
1420 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Brownef3a8232010-10-18 13:21:23 -07001421 commandEntry->eventTime = eventEntry->eventTime;
Jeff Browna665ca82010-09-08 11:49:43 -07001422 commandEntry->userActivityEventType = eventType;
1423}
1424
Jeff Brown51d45a72010-06-17 20:52:56 -07001425void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1426 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -07001427 bool resumeWithAppendedMotionSample) {
1428#if DEBUG_DISPATCH_CYCLE
Jeff Brown53a415e2010-09-15 15:18:56 -07001429 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001430 "xOffset=%f, yOffset=%f, "
1431 "windowType=%d, pointerIds=0x%x, "
1432 "resumeWithAppendedMotionSample=%s",
Jeff Brown53a415e2010-09-15 15:18:56 -07001433 connection->getInputChannelName(), inputTarget->flags,
Jeff Browne839a582010-04-22 18:58:52 -07001434 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001435 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Browna665ca82010-09-08 11:49:43 -07001436 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -07001437#endif
1438
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001439 // Make sure we are never called for streaming when splitting across multiple windows.
1440 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1441 assert(! (resumeWithAppendedMotionSample && isSplit));
1442
Jeff Browne839a582010-04-22 18:58:52 -07001443 // Skip this event if the connection status is not normal.
Jeff Brown53a415e2010-09-15 15:18:56 -07001444 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Browne839a582010-04-22 18:58:52 -07001445 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001446#if DEBUG_DISPATCH_CYCLE
1447 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Browna665ca82010-09-08 11:49:43 -07001448 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown90f0cee2010-10-08 22:31:17 -07001449#endif
Jeff Browne839a582010-04-22 18:58:52 -07001450 return;
1451 }
1452
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001453 // Split a motion event if needed.
1454 if (isSplit) {
1455 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1456
1457 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1458 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1459 MotionEntry* splitMotionEntry = splitMotionEvent(
1460 originalMotionEntry, inputTarget->pointerIds);
1461#if DEBUG_FOCUS
1462 LOGD("channel '%s' ~ Split motion event.",
1463 connection->getInputChannelName());
1464 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1465#endif
1466 eventEntry = splitMotionEntry;
1467 }
1468 }
1469
Jeff Browne839a582010-04-22 18:58:52 -07001470 // Resume the dispatch cycle with a freshly appended motion sample.
1471 // First we check that the last dispatch entry in the outbound queue is for the same
1472 // motion event to which we appended the motion sample. If we find such a dispatch
1473 // entry, and if it is currently in progress then we try to stream the new sample.
1474 bool wasEmpty = connection->outboundQueue.isEmpty();
1475
1476 if (! wasEmpty && resumeWithAppendedMotionSample) {
1477 DispatchEntry* motionEventDispatchEntry =
1478 connection->findQueuedDispatchEntryForEvent(eventEntry);
1479 if (motionEventDispatchEntry) {
1480 // If the dispatch entry is not in progress, then we must be busy dispatching an
1481 // earlier event. Not a problem, the motion event is on the outbound queue and will
1482 // be dispatched later.
1483 if (! motionEventDispatchEntry->inProgress) {
1484#if DEBUG_BATCHING
1485 LOGD("channel '%s' ~ Not streaming because the motion event has "
1486 "not yet been dispatched. "
1487 "(Waiting for earlier events to be consumed.)",
1488 connection->getInputChannelName());
1489#endif
1490 return;
1491 }
1492
1493 // If the dispatch entry is in progress but it already has a tail of pending
1494 // motion samples, then it must mean that the shared memory buffer filled up.
1495 // Not a problem, when this dispatch cycle is finished, we will eventually start
1496 // a new dispatch cycle to process the tail and that tail includes the newly
1497 // appended motion sample.
1498 if (motionEventDispatchEntry->tailMotionSample) {
1499#if DEBUG_BATCHING
1500 LOGD("channel '%s' ~ Not streaming because no new samples can "
1501 "be appended to the motion event in this dispatch cycle. "
1502 "(Waiting for next dispatch cycle to start.)",
1503 connection->getInputChannelName());
1504#endif
1505 return;
1506 }
1507
1508 // The dispatch entry is in progress and is still potentially open for streaming.
1509 // Try to stream the new motion sample. This might fail if the consumer has already
1510 // consumed the motion event (or if the channel is broken).
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001511 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1512 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Browne839a582010-04-22 18:58:52 -07001513 status_t status = connection->inputPublisher.appendMotionSample(
1514 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1515 if (status == OK) {
1516#if DEBUG_BATCHING
1517 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1518 connection->getInputChannelName());
1519#endif
1520 return;
1521 }
1522
1523#if DEBUG_BATCHING
1524 if (status == NO_MEMORY) {
1525 LOGD("channel '%s' ~ Could not append motion sample to currently "
1526 "dispatched move event because the shared memory buffer is full. "
1527 "(Waiting for next dispatch cycle to start.)",
1528 connection->getInputChannelName());
1529 } else if (status == status_t(FAILED_TRANSACTION)) {
1530 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown50de30a2010-06-22 01:27:15 -07001531 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-04-22 18:58:52 -07001532 "(Waiting for next dispatch cycle to start.)",
1533 connection->getInputChannelName());
1534 } else {
1535 LOGD("channel '%s' ~ Could not append motion sample to currently "
1536 "dispatched move event due to an error, status=%d. "
1537 "(Waiting for next dispatch cycle to start.)",
1538 connection->getInputChannelName(), status);
1539 }
1540#endif
1541 // Failed to stream. Start a new tail of pending motion samples to dispatch
1542 // in the next cycle.
1543 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1544 return;
1545 }
1546 }
1547
1548 // This is a new event.
1549 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Browna665ca82010-09-08 11:49:43 -07001550 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown53a415e2010-09-15 15:18:56 -07001551 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1552 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001553 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001554 }
1555
Jeff Browne839a582010-04-22 18:58:52 -07001556 // Handle the case where we could not stream a new motion sample because the consumer has
1557 // already consumed the motion event (otherwise the corresponding dispatch entry would
1558 // still be in the outbound queue for this connection). We set the head motion sample
1559 // to the list starting with the newly appended motion sample.
1560 if (resumeWithAppendedMotionSample) {
1561#if DEBUG_BATCHING
1562 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1563 "that cannot be streamed because the motion event has already been consumed.",
1564 connection->getInputChannelName());
1565#endif
1566 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1567 dispatchEntry->headMotionSample = appendedMotionSample;
1568 }
1569
1570 // Enqueue the dispatch entry.
1571 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1572
1573 // If the outbound queue was previously empty, start the dispatch cycle going.
1574 if (wasEmpty) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001575 activateConnectionLocked(connection.get());
Jeff Brown53a415e2010-09-15 15:18:56 -07001576 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001577 }
1578}
1579
Jeff Brown51d45a72010-06-17 20:52:56 -07001580void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown53a415e2010-09-15 15:18:56 -07001581 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001582#if DEBUG_DISPATCH_CYCLE
1583 LOGD("channel '%s' ~ startDispatchCycle",
1584 connection->getInputChannelName());
1585#endif
1586
1587 assert(connection->status == Connection::STATUS_NORMAL);
1588 assert(! connection->outboundQueue.isEmpty());
1589
Jeff Browna665ca82010-09-08 11:49:43 -07001590 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001591 assert(! dispatchEntry->inProgress);
1592
Jeff Browna665ca82010-09-08 11:49:43 -07001593 // Mark the dispatch entry as in progress.
1594 dispatchEntry->inProgress = true;
1595
1596 // Update the connection's input state.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001597 EventEntry* eventEntry = dispatchEntry->eventEntry;
1598 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001599
1600#if FILTER_INPUT_EVENTS
1601 // Filter out inconsistent sequences of input events.
1602 // The input system may drop or inject events in a way that could violate implicit
1603 // invariants on input state and potentially cause an application to crash
1604 // or think that a key or pointer is stuck down. Technically we make no guarantees
1605 // of consistency but it would be nice to improve on this where possible.
1606 // XXX: This code is a proof of concept only. Not ready for prime time.
1607 if (consistency == InputState::TOLERABLE) {
1608#if DEBUG_DISPATCH_CYCLE
1609 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1610 "current input state but that is likely to be tolerated by the application.",
1611 connection->getInputChannelName());
1612#endif
1613 } else if (consistency == InputState::BROKEN) {
1614 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1615 "current input state and that is likely to cause the application to crash.",
1616 connection->getInputChannelName());
1617 startNextDispatchCycleLocked(currentTime, connection);
1618 return;
1619 }
1620#endif
Jeff Browne839a582010-04-22 18:58:52 -07001621
1622 // Publish the event.
1623 status_t status;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001624 switch (eventEntry->type) {
Jeff Browne839a582010-04-22 18:58:52 -07001625 case EventEntry::TYPE_KEY: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001626 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001627
1628 // Apply target flags.
1629 int32_t action = keyEntry->action;
1630 int32_t flags = keyEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001631
1632 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001633 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-04-22 18:58:52 -07001634 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1635 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1636 keyEntry->eventTime);
1637
1638 if (status) {
1639 LOGE("channel '%s' ~ Could not publish key event, "
1640 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001641 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001642 return;
1643 }
1644 break;
1645 }
1646
1647 case EventEntry::TYPE_MOTION: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001648 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001649
1650 // Apply target flags.
1651 int32_t action = motionEntry->action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07001652 int32_t flags = motionEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001653 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001654 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -07001655 }
Jeff Brownaf30ff62010-09-01 17:01:00 -07001656 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1657 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1658 }
Jeff Browne839a582010-04-22 18:58:52 -07001659
1660 // If headMotionSample is non-NULL, then it points to the first new sample that we
1661 // were unable to dispatch during the previous cycle so we resume dispatching from
1662 // that point in the list of motion samples.
1663 // Otherwise, we just start from the first sample of the motion event.
1664 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1665 if (! firstMotionSample) {
1666 firstMotionSample = & motionEntry->firstSample;
1667 }
1668
Jeff Brownf26db0d2010-07-16 17:21:06 -07001669 // Set the X and Y offset depending on the input source.
1670 float xOffset, yOffset;
1671 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1672 xOffset = dispatchEntry->xOffset;
1673 yOffset = dispatchEntry->yOffset;
1674 } else {
1675 xOffset = 0.0f;
1676 yOffset = 0.0f;
1677 }
1678
Jeff Browne839a582010-04-22 18:58:52 -07001679 // Publish the motion event and the first motion sample.
1680 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001681 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -07001682 xOffset, yOffset,
Jeff Browne839a582010-04-22 18:58:52 -07001683 motionEntry->xPrecision, motionEntry->yPrecision,
1684 motionEntry->downTime, firstMotionSample->eventTime,
1685 motionEntry->pointerCount, motionEntry->pointerIds,
1686 firstMotionSample->pointerCoords);
1687
1688 if (status) {
1689 LOGE("channel '%s' ~ Could not publish motion event, "
1690 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001691 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001692 return;
1693 }
1694
1695 // Append additional motion samples.
1696 MotionSample* nextMotionSample = firstMotionSample->next;
1697 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1698 status = connection->inputPublisher.appendMotionSample(
1699 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1700 if (status == NO_MEMORY) {
1701#if DEBUG_DISPATCH_CYCLE
1702 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1703 "be sent in the next dispatch cycle.",
1704 connection->getInputChannelName());
1705#endif
1706 break;
1707 }
1708 if (status != OK) {
1709 LOGE("channel '%s' ~ Could not append motion sample "
1710 "for a reason other than out of memory, status=%d",
1711 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001712 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001713 return;
1714 }
1715 }
1716
1717 // Remember the next motion sample that we could not dispatch, in case we ran out
1718 // of space in the shared memory buffer.
1719 dispatchEntry->tailMotionSample = nextMotionSample;
1720 break;
1721 }
1722
1723 default: {
1724 assert(false);
1725 }
1726 }
1727
1728 // Send the dispatch signal.
1729 status = connection->inputPublisher.sendDispatchSignal();
1730 if (status) {
1731 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1732 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001733 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001734 return;
1735 }
1736
1737 // Record information about the newly started dispatch cycle.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001738 connection->lastEventTime = eventEntry->eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07001739 connection->lastDispatchTime = currentTime;
1740
Jeff Browne839a582010-04-22 18:58:52 -07001741 // Notify other system components.
1742 onDispatchCycleStartedLocked(currentTime, connection);
1743}
1744
Jeff Brown51d45a72010-06-17 20:52:56 -07001745void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1746 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001747#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001748 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -07001749 "%01.1fms since dispatch",
1750 connection->getInputChannelName(),
1751 connection->getEventLatencyMillis(currentTime),
1752 connection->getDispatchLatencyMillis(currentTime));
1753#endif
1754
Jeff Brown54bc2812010-06-15 01:31:58 -07001755 if (connection->status == Connection::STATUS_BROKEN
1756 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001757 return;
1758 }
1759
Jeff Brown53a415e2010-09-15 15:18:56 -07001760 // Notify other system components.
1761 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001762
1763 // Reset the publisher since the event has been consumed.
1764 // We do this now so that the publisher can release some of its internal resources
1765 // while waiting for the next dispatch cycle to begin.
1766 status_t status = connection->inputPublisher.reset();
1767 if (status) {
1768 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1769 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001770 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001771 return;
1772 }
1773
Jeff Browna665ca82010-09-08 11:49:43 -07001774 startNextDispatchCycleLocked(currentTime, connection);
1775}
1776
1777void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1778 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001779 // Start the next dispatch cycle for this connection.
1780 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001781 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001782 if (dispatchEntry->inProgress) {
1783 // Finish or resume current event in progress.
1784 if (dispatchEntry->tailMotionSample) {
1785 // We have a tail of undispatched motion samples.
1786 // Reuse the same DispatchEntry and start a new cycle.
1787 dispatchEntry->inProgress = false;
1788 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1789 dispatchEntry->tailMotionSample = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07001790 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001791 return;
1792 }
1793 // Finished.
1794 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001795 if (dispatchEntry->hasForegroundTarget()) {
1796 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001797 }
Jeff Browne839a582010-04-22 18:58:52 -07001798 mAllocator.releaseDispatchEntry(dispatchEntry);
1799 } else {
1800 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown53a415e2010-09-15 15:18:56 -07001801 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001802 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001803 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001804 return;
1805 }
1806 }
1807
1808 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001809 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001810}
1811
Jeff Brown90f0cee2010-10-08 22:31:17 -07001812void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1813 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001814#if DEBUG_DISPATCH_CYCLE
Jeff Brown90f0cee2010-10-08 22:31:17 -07001815 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001816 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001817#endif
1818
Jeff Browna665ca82010-09-08 11:49:43 -07001819 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001820 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001821
Jeff Brown90f0cee2010-10-08 22:31:17 -07001822 // The connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001823 // Ignore already broken or zombie connections.
Jeff Brown90f0cee2010-10-08 22:31:17 -07001824 if (connection->status == Connection::STATUS_NORMAL) {
1825 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001826
Jeff Brown90f0cee2010-10-08 22:31:17 -07001827 // Notify other system components.
1828 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001829 }
Jeff Browne839a582010-04-22 18:58:52 -07001830}
1831
Jeff Brown53a415e2010-09-15 15:18:56 -07001832void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1833 while (! connection->outboundQueue.isEmpty()) {
1834 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1835 if (dispatchEntry->hasForegroundTarget()) {
1836 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001837 }
1838 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001839 }
1840
Jeff Brown53a415e2010-09-15 15:18:56 -07001841 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001842}
1843
Jeff Brown59abe7e2010-09-13 23:17:30 -07001844int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-04-22 18:58:52 -07001845 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1846
1847 { // acquire lock
1848 AutoMutex _l(d->mLock);
1849
1850 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1851 if (connectionIndex < 0) {
1852 LOGE("Received spurious receive callback for unknown input channel. "
1853 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001854 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001855 }
1856
Jeff Brown51d45a72010-06-17 20:52:56 -07001857 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001858
1859 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001860 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-04-22 18:58:52 -07001861 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1862 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001863 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001864 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001865 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001866 }
1867
Jeff Brown59abe7e2010-09-13 23:17:30 -07001868 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001869 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1870 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001871 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001872 }
1873
1874 status_t status = connection->inputPublisher.receiveFinishedSignal();
1875 if (status) {
1876 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1877 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001878 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001879 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001880 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001881 }
1882
Jeff Brown51d45a72010-06-17 20:52:56 -07001883 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001884 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001885 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001886 } // release lock
1887}
1888
Jeff Brown90f0cee2010-10-08 22:31:17 -07001889void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1890 InputState::CancelationOptions options, const char* reason) {
1891 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1892 synthesizeCancelationEventsForConnectionLocked(
1893 mConnectionsByReceiveFd.valueAt(i), options, reason);
1894 }
1895}
1896
1897void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1898 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1899 const char* reason) {
1900 ssize_t index = getConnectionIndexLocked(channel);
1901 if (index >= 0) {
1902 synthesizeCancelationEventsForConnectionLocked(
1903 mConnectionsByReceiveFd.valueAt(index), options, reason);
1904 }
1905}
1906
1907void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1908 const sp<Connection>& connection, InputState::CancelationOptions options,
1909 const char* reason) {
1910 nsecs_t currentTime = now();
1911
1912 mTempCancelationEvents.clear();
1913 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1914 mTempCancelationEvents, options);
1915
1916 if (! mTempCancelationEvents.isEmpty()
1917 && connection->status != Connection::STATUS_BROKEN) {
1918#if DEBUG_OUTBOUND_EVENT_DETAILS
1919 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1920 "with reality: %s, options=%d.",
1921 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1922#endif
1923 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1924 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1925 switch (cancelationEventEntry->type) {
1926 case EventEntry::TYPE_KEY:
1927 logOutboundKeyDetailsLocked("cancel - ",
1928 static_cast<KeyEntry*>(cancelationEventEntry));
1929 break;
1930 case EventEntry::TYPE_MOTION:
1931 logOutboundMotionDetailsLocked("cancel - ",
1932 static_cast<MotionEntry*>(cancelationEventEntry));
1933 break;
1934 }
1935
1936 int32_t xOffset, yOffset;
1937 const InputWindow* window = getWindowLocked(connection->inputChannel);
1938 if (window) {
1939 xOffset = -window->frameLeft;
1940 yOffset = -window->frameTop;
1941 } else {
1942 xOffset = 0;
1943 yOffset = 0;
1944 }
1945
1946 DispatchEntry* cancelationDispatchEntry =
1947 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1948 0, xOffset, yOffset);
1949 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1950
1951 mAllocator.releaseEventEntry(cancelationEventEntry);
1952 }
1953
1954 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1955 startDispatchCycleLocked(currentTime, connection);
1956 }
1957 }
1958}
1959
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001960InputDispatcher::MotionEntry*
1961InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1962 assert(pointerIds.value != 0);
1963
1964 uint32_t splitPointerIndexMap[MAX_POINTERS];
1965 int32_t splitPointerIds[MAX_POINTERS];
1966 PointerCoords splitPointerCoords[MAX_POINTERS];
1967
1968 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1969 uint32_t splitPointerCount = 0;
1970
1971 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1972 originalPointerIndex++) {
1973 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1974 if (pointerIds.hasBit(pointerId)) {
1975 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1976 splitPointerIds[splitPointerCount] = pointerId;
1977 splitPointerCoords[splitPointerCount] =
1978 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1979 splitPointerCount += 1;
1980 }
1981 }
1982 assert(splitPointerCount == pointerIds.count());
1983
1984 int32_t action = originalMotionEntry->action;
1985 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1986 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
1987 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1988 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
1989 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
1990 if (pointerIds.hasBit(pointerId)) {
1991 if (pointerIds.count() == 1) {
1992 // The first/last pointer went down/up.
1993 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
1994 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brownffb16d62010-09-27 16:35:11 -07001995 } else {
1996 // A secondary pointer went down/up.
1997 uint32_t splitPointerIndex = 0;
1998 while (pointerId != splitPointerIds[splitPointerIndex]) {
1999 splitPointerIndex += 1;
2000 }
2001 action = maskedAction | (splitPointerIndex
2002 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002003 }
2004 } else {
2005 // An unrelated pointer changed.
2006 action = AMOTION_EVENT_ACTION_MOVE;
2007 }
2008 }
2009
2010 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2011 originalMotionEntry->eventTime,
2012 originalMotionEntry->deviceId,
2013 originalMotionEntry->source,
2014 originalMotionEntry->policyFlags,
2015 action,
2016 originalMotionEntry->flags,
2017 originalMotionEntry->metaState,
2018 originalMotionEntry->edgeFlags,
2019 originalMotionEntry->xPrecision,
2020 originalMotionEntry->yPrecision,
2021 originalMotionEntry->downTime,
2022 splitPointerCount, splitPointerIds, splitPointerCoords);
2023
2024 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2025 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2026 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2027 splitPointerIndex++) {
2028 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2029 splitPointerCoords[splitPointerIndex] =
2030 originalMotionSample->pointerCoords[originalPointerIndex];
2031 }
2032
2033 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2034 splitPointerCoords);
2035 }
2036
2037 return splitMotionEntry;
2038}
2039
Jeff Brown54bc2812010-06-15 01:31:58 -07002040void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002041#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -07002042 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07002043#endif
2044
Jeff Browna665ca82010-09-08 11:49:43 -07002045 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002046 { // acquire lock
2047 AutoMutex _l(mLock);
2048
Jeff Brown51d45a72010-06-17 20:52:56 -07002049 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browna665ca82010-09-08 11:49:43 -07002050 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002051 } // release lock
2052
Jeff Browna665ca82010-09-08 11:49:43 -07002053 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002054 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002055 }
2056}
2057
Jeff Brown5c1ed842010-07-14 18:48:53 -07002058void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -07002059 uint32_t policyFlags, int32_t action, int32_t flags,
2060 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2061#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002062 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07002063 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07002064 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -07002065 keyCode, scanCode, metaState, downTime);
2066#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002067 if (! validateKeyEvent(action)) {
2068 return;
2069 }
Jeff Browne839a582010-04-22 18:58:52 -07002070
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002071 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002072 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2073 keyCode, scanCode, /*byref*/ policyFlags);
2074
Jeff Browna665ca82010-09-08 11:49:43 -07002075 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002076 { // acquire lock
2077 AutoMutex _l(mLock);
2078
Jeff Brown51d45a72010-06-17 20:52:56 -07002079 int32_t repeatCount = 0;
2080 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002081 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07002082 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07002083
Jeff Browna665ca82010-09-08 11:49:43 -07002084 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002085 } // release lock
2086
Jeff Browna665ca82010-09-08 11:49:43 -07002087 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002088 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002089 }
2090}
2091
Jeff Brown5c1ed842010-07-14 18:48:53 -07002092void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002093 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002094 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2095 float xPrecision, float yPrecision, nsecs_t downTime) {
2096#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002097 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002098 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2099 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2100 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002101 xPrecision, yPrecision, downTime);
2102 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07002103 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002104 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07002105 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07002106 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-08-30 03:02:23 -07002107 pointerCoords[i].pressure, pointerCoords[i].size,
2108 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2109 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2110 pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -07002111 }
2112#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002113 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2114 return;
2115 }
Jeff Browne839a582010-04-22 18:58:52 -07002116
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002117 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002118 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2119
Jeff Browna665ca82010-09-08 11:49:43 -07002120 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002121 { // acquire lock
2122 AutoMutex _l(mLock);
2123
2124 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07002125 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07002126 // BATCHING CASE
2127 //
2128 // Try to append a move sample to the tail of the inbound queue for this device.
2129 // Give up if we encounter a non-move motion event for this device since that
2130 // means we cannot append any new samples until a new motion event has started.
Jeff Browna665ca82010-09-08 11:49:43 -07002131 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2132 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07002133 if (entry->type != EventEntry::TYPE_MOTION) {
2134 // Keep looking for motion events.
2135 continue;
2136 }
2137
2138 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2139 if (motionEntry->deviceId != deviceId) {
2140 // Keep looking for this device.
2141 continue;
2142 }
2143
Jeff Brown5c1ed842010-07-14 18:48:53 -07002144 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07002145 || motionEntry->pointerCount != pointerCount
2146 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07002147 // Last motion event in the queue for this device is not compatible for
2148 // appending new samples. Stop here.
2149 goto NoBatchingOrStreaming;
2150 }
2151
2152 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07002153 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07002154 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002155#if DEBUG_BATCHING
2156 LOGD("Appended motion sample onto batch for most recent "
2157 "motion event for this device in the inbound queue.");
2158#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07002159 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002160 }
2161
2162 // STREAMING CASE
2163 //
2164 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07002165 // Search the outbound queue for the current foreground targets to find a dispatched
2166 // motion event that is still in progress. If found, then, appen the new sample to
2167 // that event and push it out to all current targets. The logic in
2168 // prepareDispatchCycleLocked takes care of the case where some targets may
2169 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown54bc2812010-06-15 01:31:58 -07002170 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002171 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2172 const InputTarget& inputTarget = mCurrentInputTargets[i];
2173 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2174 // Skip non-foreground targets. We only want to stream if there is at
2175 // least one foreground target whose dispatch is still in progress.
2176 continue;
Jeff Browne839a582010-04-22 18:58:52 -07002177 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002178
2179 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2180 if (connectionIndex < 0) {
2181 // Connection must no longer be valid.
2182 continue;
2183 }
2184
2185 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2186 if (connection->outboundQueue.isEmpty()) {
2187 // This foreground target has an empty outbound queue.
2188 continue;
2189 }
2190
2191 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2192 if (! dispatchEntry->inProgress
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002193 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2194 || dispatchEntry->isSplit()) {
2195 // No motion event is being dispatched, or it is being split across
2196 // windows in which case we cannot stream.
Jeff Brown53a415e2010-09-15 15:18:56 -07002197 continue;
2198 }
2199
2200 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2201 dispatchEntry->eventEntry);
2202 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2203 || motionEntry->deviceId != deviceId
2204 || motionEntry->pointerCount != pointerCount
2205 || motionEntry->isInjected()) {
2206 // The motion event is not compatible with this move.
2207 continue;
2208 }
2209
2210 // Hurray! This foreground target is currently dispatching a move event
2211 // that we can stream onto. Append the motion sample and resume dispatch.
2212 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2213#if DEBUG_BATCHING
2214 LOGD("Appended motion sample onto batch for most recently dispatched "
2215 "motion event for this device in the outbound queues. "
2216 "Attempting to stream the motion sample.");
2217#endif
2218 nsecs_t currentTime = now();
2219 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2220 true /*resumeWithAppendedMotionSample*/);
2221
2222 runCommandsLockedInterruptible();
2223 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002224 }
2225 }
2226
2227NoBatchingOrStreaming:;
2228 }
2229
2230 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07002231 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002232 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002233 xPrecision, yPrecision, downTime,
2234 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002235
Jeff Browna665ca82010-09-08 11:49:43 -07002236 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002237 } // release lock
2238
Jeff Browna665ca82010-09-08 11:49:43 -07002239 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002240 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002241 }
2242}
2243
Jeff Brown90f0cee2010-10-08 22:31:17 -07002244void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2245 uint32_t policyFlags) {
2246#if DEBUG_INBOUND_EVENT_DETAILS
2247 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2248 switchCode, switchValue, policyFlags);
2249#endif
2250
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002251 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002252 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2253}
2254
Jeff Brown51d45a72010-06-17 20:52:56 -07002255int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07002256 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002257#if DEBUG_INBOUND_EVENT_DETAILS
2258 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002259 "syncMode=%d, timeoutMillis=%d",
2260 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07002261#endif
2262
2263 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002264
2265 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2266 if (hasInjectionPermission(injectorPid, injectorUid)) {
2267 policyFlags |= POLICY_FLAG_TRUSTED;
2268 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002269
Jeff Brown90f0cee2010-10-08 22:31:17 -07002270 EventEntry* injectedEntry;
2271 switch (event->getType()) {
2272 case AINPUT_EVENT_TYPE_KEY: {
2273 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2274 int32_t action = keyEvent->getAction();
2275 if (! validateKeyEvent(action)) {
Jeff Browna665ca82010-09-08 11:49:43 -07002276 return INPUT_EVENT_INJECTION_FAILED;
2277 }
2278
Jeff Brown90f0cee2010-10-08 22:31:17 -07002279 nsecs_t eventTime = keyEvent->getEventTime();
2280 int32_t deviceId = keyEvent->getDeviceId();
2281 int32_t flags = keyEvent->getFlags();
2282 int32_t keyCode = keyEvent->getKeyCode();
2283 int32_t scanCode = keyEvent->getScanCode();
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002284 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2285 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002286
Jeff Brown90f0cee2010-10-08 22:31:17 -07002287 mLock.lock();
2288 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2289 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2290 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2291 break;
2292 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002293
Jeff Brown90f0cee2010-10-08 22:31:17 -07002294 case AINPUT_EVENT_TYPE_MOTION: {
2295 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2296 int32_t action = motionEvent->getAction();
2297 size_t pointerCount = motionEvent->getPointerCount();
2298 const int32_t* pointerIds = motionEvent->getPointerIds();
2299 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2300 return INPUT_EVENT_INJECTION_FAILED;
2301 }
2302
2303 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002304 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002305
2306 mLock.lock();
2307 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2308 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2309 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2310 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2311 action, motionEvent->getFlags(),
2312 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2313 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2314 motionEvent->getDownTime(), uint32_t(pointerCount),
2315 pointerIds, samplePointerCoords);
2316 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2317 sampleEventTimes += 1;
2318 samplePointerCoords += pointerCount;
2319 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2320 }
2321 injectedEntry = motionEntry;
2322 break;
2323 }
2324
2325 default:
2326 LOGW("Cannot inject event of type %d", event->getType());
2327 return INPUT_EVENT_INJECTION_FAILED;
2328 }
2329
2330 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2331 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2332 injectionState->injectionIsAsync = true;
2333 }
2334
2335 injectionState->refCount += 1;
2336 injectedEntry->injectionState = injectionState;
2337
2338 bool needWake = enqueueInboundEventLocked(injectedEntry);
2339 mLock.unlock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002340
Jeff Browna665ca82010-09-08 11:49:43 -07002341 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002342 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07002343 }
2344
2345 int32_t injectionResult;
2346 { // acquire lock
2347 AutoMutex _l(mLock);
2348
Jeff Brownf67c53e2010-07-28 15:48:59 -07002349 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2350 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2351 } else {
2352 for (;;) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002353 injectionResult = injectionState->injectionResult;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002354 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2355 break;
2356 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002357
Jeff Brown51d45a72010-06-17 20:52:56 -07002358 nsecs_t remainingTimeout = endTime - now();
2359 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002360#if DEBUG_INJECTION
2361 LOGD("injectInputEvent - Timed out waiting for injection result "
2362 "to become available.");
2363#endif
Jeff Brown51d45a72010-06-17 20:52:56 -07002364 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2365 break;
2366 }
2367
Jeff Brownf67c53e2010-07-28 15:48:59 -07002368 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2369 }
2370
2371 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2372 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002373 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002374#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002375 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002376 injectionState->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002377#endif
2378 nsecs_t remainingTimeout = endTime - now();
2379 if (remainingTimeout <= 0) {
2380#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002381 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002382 "dispatches to finish.");
2383#endif
2384 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2385 break;
2386 }
2387
2388 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2389 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002390 }
2391 }
2392
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002393 mAllocator.releaseInjectionState(injectionState);
Jeff Brown51d45a72010-06-17 20:52:56 -07002394 } // release lock
2395
Jeff Brownf67c53e2010-07-28 15:48:59 -07002396#if DEBUG_INJECTION
2397 LOGD("injectInputEvent - Finished with result %d. "
2398 "injectorPid=%d, injectorUid=%d",
2399 injectionResult, injectorPid, injectorUid);
2400#endif
2401
Jeff Brown51d45a72010-06-17 20:52:56 -07002402 return injectionResult;
2403}
2404
Jeff Brown90f0cee2010-10-08 22:31:17 -07002405bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2406 return injectorUid == 0
2407 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2408}
2409
Jeff Brown51d45a72010-06-17 20:52:56 -07002410void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002411 InjectionState* injectionState = entry->injectionState;
2412 if (injectionState) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002413#if DEBUG_INJECTION
2414 LOGD("Setting input event injection result to %d. "
2415 "injectorPid=%d, injectorUid=%d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002416 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002417#endif
2418
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002419 if (injectionState->injectionIsAsync) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002420 // Log the outcome since the injector did not wait for the injection result.
2421 switch (injectionResult) {
2422 case INPUT_EVENT_INJECTION_SUCCEEDED:
2423 LOGV("Asynchronous input event injection succeeded.");
2424 break;
2425 case INPUT_EVENT_INJECTION_FAILED:
2426 LOGW("Asynchronous input event injection failed.");
2427 break;
2428 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2429 LOGW("Asynchronous input event injection permission denied.");
2430 break;
2431 case INPUT_EVENT_INJECTION_TIMED_OUT:
2432 LOGW("Asynchronous input event injection timed out.");
2433 break;
2434 }
2435 }
2436
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002437 injectionState->injectionResult = injectionResult;
Jeff Brown51d45a72010-06-17 20:52:56 -07002438 mInjectionResultAvailableCondition.broadcast();
2439 }
2440}
2441
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002442void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2443 InjectionState* injectionState = entry->injectionState;
2444 if (injectionState) {
2445 injectionState->pendingForegroundDispatches += 1;
2446 }
2447}
2448
Jeff Brown53a415e2010-09-15 15:18:56 -07002449void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002450 InjectionState* injectionState = entry->injectionState;
2451 if (injectionState) {
2452 injectionState->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002453
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002454 if (injectionState->pendingForegroundDispatches == 0) {
2455 mInjectionSyncFinishedCondition.broadcast();
2456 }
Jeff Browna665ca82010-09-08 11:49:43 -07002457 }
2458}
2459
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002460const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2461 for (size_t i = 0; i < mWindows.size(); i++) {
2462 const InputWindow* window = & mWindows[i];
2463 if (window->inputChannel == inputChannel) {
2464 return window;
2465 }
2466 }
2467 return NULL;
2468}
2469
Jeff Browna665ca82010-09-08 11:49:43 -07002470void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2471#if DEBUG_FOCUS
2472 LOGD("setInputWindows");
2473#endif
2474 { // acquire lock
2475 AutoMutex _l(mLock);
2476
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002477 // Clear old window pointers.
Jeff Brown90f0cee2010-10-08 22:31:17 -07002478 sp<InputChannel> oldFocusedWindowChannel;
2479 if (mFocusedWindow) {
2480 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2481 mFocusedWindow = NULL;
2482 }
2483
Jeff Browna665ca82010-09-08 11:49:43 -07002484 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002485
2486 // Loop over new windows and rebuild the necessary window pointers for
2487 // tracking focus and touch.
Jeff Browna665ca82010-09-08 11:49:43 -07002488 mWindows.appendVector(inputWindows);
2489
2490 size_t numWindows = mWindows.size();
2491 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002492 const InputWindow* window = & mWindows.itemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07002493 if (window->hasFocus) {
2494 mFocusedWindow = window;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002495 break;
Jeff Browna665ca82010-09-08 11:49:43 -07002496 }
2497 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002498
Jeff Brown90f0cee2010-10-08 22:31:17 -07002499 if (oldFocusedWindowChannel != NULL) {
2500 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2501#if DEBUG_FOCUS
2502 LOGD("Focus left window: %s",
2503 oldFocusedWindowChannel->getName().string());
2504#endif
2505 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2506 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2507 oldFocusedWindowChannel.clear();
2508 }
2509 }
2510 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2511#if DEBUG_FOCUS
2512 LOGD("Focus entered window: %s",
2513 mFocusedWindow->inputChannel->getName().string());
2514#endif
2515 }
2516
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002517 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2518 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2519 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2520 if (window) {
2521 touchedWindow.window = window;
2522 i += 1;
2523 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -07002524#if DEBUG_FOCUS
2525 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2526#endif
Jeff Brown90f0cee2010-10-08 22:31:17 -07002527 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2528 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownb13d7b52010-10-15 16:20:51 -07002529 mTouchState.windows.removeAt(i);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002530 }
2531 }
Jeff Browna665ca82010-09-08 11:49:43 -07002532
Jeff Browna665ca82010-09-08 11:49:43 -07002533#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002534 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002535#endif
2536 } // release lock
2537
2538 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002539 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002540}
2541
2542void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2543#if DEBUG_FOCUS
2544 LOGD("setFocusedApplication");
2545#endif
2546 { // acquire lock
2547 AutoMutex _l(mLock);
2548
2549 releaseFocusedApplicationLocked();
2550
2551 if (inputApplication) {
2552 mFocusedApplicationStorage = *inputApplication;
2553 mFocusedApplication = & mFocusedApplicationStorage;
2554 }
2555
2556#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002557 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002558#endif
2559 } // release lock
2560
2561 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002562 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002563}
2564
2565void InputDispatcher::releaseFocusedApplicationLocked() {
2566 if (mFocusedApplication) {
2567 mFocusedApplication = NULL;
2568 mFocusedApplicationStorage.handle.clear();
2569 }
2570}
2571
2572void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2573#if DEBUG_FOCUS
2574 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2575#endif
2576
2577 bool changed;
2578 { // acquire lock
2579 AutoMutex _l(mLock);
2580
2581 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2582 if (mDispatchFrozen && ! frozen) {
2583 resetANRTimeoutsLocked();
2584 }
2585
2586 mDispatchEnabled = enabled;
2587 mDispatchFrozen = frozen;
2588 changed = true;
2589 } else {
2590 changed = false;
2591 }
2592
2593#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002594 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002595#endif
2596 } // release lock
2597
2598 if (changed) {
2599 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002600 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002601 }
2602}
2603
Jeff Browna665ca82010-09-08 11:49:43 -07002604void InputDispatcher::logDispatchStateLocked() {
2605 String8 dump;
2606 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002607
2608 char* text = dump.lockBuffer(dump.size());
2609 char* start = text;
2610 while (*start != '\0') {
2611 char* end = strchr(start, '\n');
2612 if (*end == '\n') {
2613 *(end++) = '\0';
2614 }
2615 LOGD("%s", start);
2616 start = end;
2617 }
Jeff Browna665ca82010-09-08 11:49:43 -07002618}
2619
2620void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002621 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2622 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002623
2624 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002625 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002626 mFocusedApplication->name.string(),
2627 mFocusedApplication->dispatchingTimeout / 1000000.0);
2628 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002629 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002630 }
Jeff Brown2806e382010-10-01 17:46:21 -07002631 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002632 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-10-01 17:46:21 -07002633
2634 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2635 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2636 if (!mTouchState.windows.isEmpty()) {
2637 dump.append(INDENT "TouchedWindows:\n");
2638 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2639 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2640 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2641 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2642 touchedWindow.targetFlags);
2643 }
2644 } else {
2645 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002646 }
2647
Jeff Brown2806e382010-10-01 17:46:21 -07002648 if (!mWindows.isEmpty()) {
2649 dump.append(INDENT "Windows:\n");
2650 for (size_t i = 0; i < mWindows.size(); i++) {
2651 const InputWindow& window = mWindows[i];
2652 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2653 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2654 "frame=[%d,%d][%d,%d], "
2655 "visibleFrame=[%d,%d][%d,%d], "
2656 "touchableArea=[%d,%d][%d,%d], "
2657 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2658 i, window.name.string(),
2659 toString(window.paused),
2660 toString(window.hasFocus),
2661 toString(window.hasWallpaper),
2662 toString(window.visible),
2663 toString(window.canReceiveKeys),
2664 window.layoutParamsFlags, window.layoutParamsType,
2665 window.layer,
2666 window.frameLeft, window.frameTop,
2667 window.frameRight, window.frameBottom,
2668 window.visibleFrameLeft, window.visibleFrameTop,
2669 window.visibleFrameRight, window.visibleFrameBottom,
2670 window.touchableAreaLeft, window.touchableAreaTop,
2671 window.touchableAreaRight, window.touchableAreaBottom,
2672 window.ownerPid, window.ownerUid,
2673 window.dispatchingTimeout / 1000000.0);
2674 }
2675 } else {
2676 dump.append(INDENT "Windows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002677 }
2678
Jeff Brown2806e382010-10-01 17:46:21 -07002679 if (!mMonitoringChannels.isEmpty()) {
2680 dump.append(INDENT "MonitoringChannels:\n");
2681 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2682 const sp<InputChannel>& channel = mMonitoringChannels[i];
2683 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2684 }
2685 } else {
2686 dump.append(INDENT "MonitoringChannels: <none>\n");
2687 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002688
Jeff Brown2806e382010-10-01 17:46:21 -07002689 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2690
2691 if (!mActiveConnections.isEmpty()) {
2692 dump.append(INDENT "ActiveConnections:\n");
2693 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2694 const Connection* connection = mActiveConnections[i];
2695 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
Jeff Brown90f0cee2010-10-08 22:31:17 -07002696 "inputState.isNeutral=%s\n",
Jeff Brown2806e382010-10-01 17:46:21 -07002697 i, connection->getInputChannelName(), connection->getStatusLabel(),
2698 connection->outboundQueue.count(),
Jeff Brown90f0cee2010-10-08 22:31:17 -07002699 toString(connection->inputState.isNeutral()));
Jeff Brown2806e382010-10-01 17:46:21 -07002700 }
2701 } else {
2702 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002703 }
2704
2705 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002706 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002707 (mAppSwitchDueTime - now()) / 1000000.0);
2708 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002709 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002710 }
2711}
2712
2713status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002714#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002715 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2716 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002717#endif
2718
Jeff Browne839a582010-04-22 18:58:52 -07002719 { // acquire lock
2720 AutoMutex _l(mLock);
2721
Jeff Brown53a415e2010-09-15 15:18:56 -07002722 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002723 LOGW("Attempted to register already registered input channel '%s'",
2724 inputChannel->getName().string());
2725 return BAD_VALUE;
2726 }
2727
2728 sp<Connection> connection = new Connection(inputChannel);
2729 status_t status = connection->initialize();
2730 if (status) {
2731 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2732 inputChannel->getName().string(), status);
2733 return status;
2734 }
2735
Jeff Brown0cacb872010-08-17 15:59:26 -07002736 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002737 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002738
Jeff Browna665ca82010-09-08 11:49:43 -07002739 if (monitor) {
2740 mMonitoringChannels.push(inputChannel);
2741 }
2742
Jeff Brown59abe7e2010-09-13 23:17:30 -07002743 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002744
Jeff Brown54bc2812010-06-15 01:31:58 -07002745 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002746 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002747 return OK;
2748}
2749
2750status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002751#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002752 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002753#endif
2754
Jeff Browne839a582010-04-22 18:58:52 -07002755 { // acquire lock
2756 AutoMutex _l(mLock);
2757
Jeff Brown53a415e2010-09-15 15:18:56 -07002758 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002759 if (connectionIndex < 0) {
2760 LOGW("Attempted to unregister already unregistered input channel '%s'",
2761 inputChannel->getName().string());
2762 return BAD_VALUE;
2763 }
2764
2765 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2766 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2767
2768 connection->status = Connection::STATUS_ZOMBIE;
2769
Jeff Browna665ca82010-09-08 11:49:43 -07002770 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2771 if (mMonitoringChannels[i] == inputChannel) {
2772 mMonitoringChannels.removeAt(i);
2773 break;
2774 }
2775 }
2776
Jeff Brown59abe7e2010-09-13 23:17:30 -07002777 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002778
Jeff Brown51d45a72010-06-17 20:52:56 -07002779 nsecs_t currentTime = now();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002780 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002781
2782 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002783 } // release lock
2784
Jeff Browne839a582010-04-22 18:58:52 -07002785 // Wake the poll loop because removing the connection may have changed the current
2786 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002787 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002788 return OK;
2789}
2790
Jeff Brown53a415e2010-09-15 15:18:56 -07002791ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002792 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2793 if (connectionIndex >= 0) {
2794 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2795 if (connection->inputChannel.get() == inputChannel.get()) {
2796 return connectionIndex;
2797 }
2798 }
2799
2800 return -1;
2801}
2802
Jeff Browne839a582010-04-22 18:58:52 -07002803void InputDispatcher::activateConnectionLocked(Connection* connection) {
2804 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2805 if (mActiveConnections.itemAt(i) == connection) {
2806 return;
2807 }
2808 }
2809 mActiveConnections.add(connection);
2810}
2811
2812void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2813 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2814 if (mActiveConnections.itemAt(i) == connection) {
2815 mActiveConnections.removeAt(i);
2816 return;
2817 }
2818 }
2819}
2820
Jeff Brown54bc2812010-06-15 01:31:58 -07002821void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002822 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002823}
2824
Jeff Brown54bc2812010-06-15 01:31:58 -07002825void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002826 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002827}
2828
Jeff Brown54bc2812010-06-15 01:31:58 -07002829void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002830 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002831 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2832 connection->getInputChannelName());
2833
Jeff Brown54bc2812010-06-15 01:31:58 -07002834 CommandEntry* commandEntry = postCommandLocked(
2835 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002836 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002837}
2838
Jeff Brown53a415e2010-09-15 15:18:56 -07002839void InputDispatcher::onANRLocked(
2840 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2841 nsecs_t eventTime, nsecs_t waitStartTime) {
2842 LOGI("Application is not responding: %s. "
2843 "%01.1fms since event, %01.1fms since wait started",
2844 getApplicationWindowLabelLocked(application, window).string(),
2845 (currentTime - eventTime) / 1000000.0,
2846 (currentTime - waitStartTime) / 1000000.0);
2847
2848 CommandEntry* commandEntry = postCommandLocked(
2849 & InputDispatcher::doNotifyANRLockedInterruptible);
2850 if (application) {
2851 commandEntry->inputApplicationHandle = application->handle;
2852 }
2853 if (window) {
2854 commandEntry->inputChannel = window->inputChannel;
2855 }
2856}
2857
Jeff Browna665ca82010-09-08 11:49:43 -07002858void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2859 CommandEntry* commandEntry) {
2860 mLock.unlock();
2861
2862 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2863
2864 mLock.lock();
2865}
2866
Jeff Brown54bc2812010-06-15 01:31:58 -07002867void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2868 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002869 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002870
Jeff Brown51d45a72010-06-17 20:52:56 -07002871 if (connection->status != Connection::STATUS_ZOMBIE) {
2872 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002873
Jeff Brown51d45a72010-06-17 20:52:56 -07002874 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2875
2876 mLock.lock();
2877 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002878}
2879
Jeff Brown53a415e2010-09-15 15:18:56 -07002880void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002881 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002882 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002883
Jeff Brown53a415e2010-09-15 15:18:56 -07002884 nsecs_t newTimeout = mPolicy->notifyANR(
2885 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002886
Jeff Brown53a415e2010-09-15 15:18:56 -07002887 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002888
Jeff Brown53a415e2010-09-15 15:18:56 -07002889 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002890}
2891
Jeff Browna665ca82010-09-08 11:49:43 -07002892void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2893 CommandEntry* commandEntry) {
2894 KeyEntry* entry = commandEntry->keyEntry;
2895 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2896 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2897 entry->downTime, entry->eventTime);
2898
2899 mLock.unlock();
2900
2901 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2902 & mReusableKeyEvent, entry->policyFlags);
2903
2904 mLock.lock();
2905
2906 entry->interceptKeyResult = consumed
2907 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2908 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2909 mAllocator.releaseKeyEntry(entry);
2910}
2911
2912void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2913 mLock.unlock();
2914
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002915 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07002916
2917 mLock.lock();
2918}
2919
Jeff Brown53a415e2010-09-15 15:18:56 -07002920void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
2921 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
2922 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07002923}
2924
2925void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002926 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002927 dumpDispatchStateLocked(dump);
2928}
2929
Jeff Brown54bc2812010-06-15 01:31:58 -07002930
Jeff Brown53a415e2010-09-15 15:18:56 -07002931// --- InputDispatcher::Queue ---
2932
2933template <typename T>
2934uint32_t InputDispatcher::Queue<T>::count() const {
2935 uint32_t result = 0;
2936 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
2937 result += 1;
2938 }
2939 return result;
2940}
2941
2942
Jeff Browne839a582010-04-22 18:58:52 -07002943// --- InputDispatcher::Allocator ---
2944
2945InputDispatcher::Allocator::Allocator() {
2946}
2947
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002948InputDispatcher::InjectionState*
2949InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
2950 InjectionState* injectionState = mInjectionStatePool.alloc();
2951 injectionState->refCount = 1;
2952 injectionState->injectorPid = injectorPid;
2953 injectionState->injectorUid = injectorUid;
2954 injectionState->injectionIsAsync = false;
2955 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
2956 injectionState->pendingForegroundDispatches = 0;
2957 return injectionState;
2958}
2959
Jeff Brown51d45a72010-06-17 20:52:56 -07002960void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brown90f0cee2010-10-08 22:31:17 -07002961 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002962 entry->type = type;
2963 entry->refCount = 1;
2964 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07002965 entry->eventTime = eventTime;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002966 entry->policyFlags = policyFlags;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002967 entry->injectionState = NULL;
2968}
2969
2970void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
2971 if (entry->injectionState) {
2972 releaseInjectionState(entry->injectionState);
2973 entry->injectionState = NULL;
2974 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002975}
2976
Jeff Browne839a582010-04-22 18:58:52 -07002977InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07002978InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002979 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002980 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Browne839a582010-04-22 18:58:52 -07002981 return entry;
2982}
2983
Jeff Brown51d45a72010-06-17 20:52:56 -07002984InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002985 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07002986 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
2987 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002988 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002989 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07002990
2991 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07002992 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07002993 entry->action = action;
2994 entry->flags = flags;
2995 entry->keyCode = keyCode;
2996 entry->scanCode = scanCode;
2997 entry->metaState = metaState;
2998 entry->repeatCount = repeatCount;
2999 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07003000 entry->syntheticRepeat = false;
3001 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07003002 return entry;
3003}
3004
Jeff Brown51d45a72010-06-17 20:52:56 -07003005InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07003006 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07003007 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3008 nsecs_t downTime, uint32_t pointerCount,
3009 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003010 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003011 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003012
3013 entry->eventTime = eventTime;
3014 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003015 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003016 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07003017 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07003018 entry->metaState = metaState;
3019 entry->edgeFlags = edgeFlags;
3020 entry->xPrecision = xPrecision;
3021 entry->yPrecision = yPrecision;
3022 entry->downTime = downTime;
3023 entry->pointerCount = pointerCount;
3024 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07003025 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07003026 entry->lastSample = & entry->firstSample;
3027 for (uint32_t i = 0; i < pointerCount; i++) {
3028 entry->pointerIds[i] = pointerIds[i];
3029 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3030 }
Jeff Browne839a582010-04-22 18:58:52 -07003031 return entry;
3032}
3033
3034InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07003035 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07003036 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07003037 DispatchEntry* entry = mDispatchEntryPool.alloc();
3038 entry->eventEntry = eventEntry;
3039 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07003040 entry->targetFlags = targetFlags;
3041 entry->xOffset = xOffset;
3042 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07003043 entry->inProgress = false;
3044 entry->headMotionSample = NULL;
3045 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07003046 return entry;
3047}
3048
Jeff Brown54bc2812010-06-15 01:31:58 -07003049InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3050 CommandEntry* entry = mCommandEntryPool.alloc();
3051 entry->command = command;
3052 return entry;
3053}
3054
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003055void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3056 injectionState->refCount -= 1;
3057 if (injectionState->refCount == 0) {
3058 mInjectionStatePool.free(injectionState);
3059 } else {
3060 assert(injectionState->refCount > 0);
3061 }
3062}
3063
Jeff Browne839a582010-04-22 18:58:52 -07003064void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3065 switch (entry->type) {
3066 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3067 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3068 break;
3069 case EventEntry::TYPE_KEY:
3070 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3071 break;
3072 case EventEntry::TYPE_MOTION:
3073 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3074 break;
3075 default:
3076 assert(false);
3077 break;
3078 }
3079}
3080
3081void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3082 ConfigurationChangedEntry* entry) {
3083 entry->refCount -= 1;
3084 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003085 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003086 mConfigurationChangeEntryPool.free(entry);
3087 } else {
3088 assert(entry->refCount > 0);
3089 }
3090}
3091
3092void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3093 entry->refCount -= 1;
3094 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003095 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003096 mKeyEntryPool.free(entry);
3097 } else {
3098 assert(entry->refCount > 0);
3099 }
3100}
3101
3102void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3103 entry->refCount -= 1;
3104 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003105 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -07003106 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3107 MotionSample* next = sample->next;
3108 mMotionSamplePool.free(sample);
3109 sample = next;
3110 }
Jeff Browne839a582010-04-22 18:58:52 -07003111 mMotionEntryPool.free(entry);
3112 } else {
3113 assert(entry->refCount > 0);
3114 }
3115}
3116
3117void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3118 releaseEventEntry(entry->eventEntry);
3119 mDispatchEntryPool.free(entry);
3120}
3121
Jeff Brown54bc2812010-06-15 01:31:58 -07003122void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3123 mCommandEntryPool.free(entry);
3124}
3125
Jeff Browne839a582010-04-22 18:58:52 -07003126void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003127 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003128 MotionSample* sample = mMotionSamplePool.alloc();
3129 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003130 uint32_t pointerCount = motionEntry->pointerCount;
3131 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07003132 sample->pointerCoords[i] = pointerCoords[i];
3133 }
3134
3135 sample->next = NULL;
3136 motionEntry->lastSample->next = sample;
3137 motionEntry->lastSample = sample;
3138}
3139
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003140void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3141 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003142
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003143 keyEntry->dispatchInProgress = false;
3144 keyEntry->syntheticRepeat = false;
3145 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003146}
3147
3148
Jeff Brown542412c2010-08-18 15:51:08 -07003149// --- InputDispatcher::MotionEntry ---
3150
3151uint32_t InputDispatcher::MotionEntry::countSamples() const {
3152 uint32_t count = 1;
3153 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3154 count += 1;
3155 }
3156 return count;
3157}
3158
Jeff Browna665ca82010-09-08 11:49:43 -07003159
3160// --- InputDispatcher::InputState ---
3161
Jeff Brown90f0cee2010-10-08 22:31:17 -07003162InputDispatcher::InputState::InputState() {
Jeff Browna665ca82010-09-08 11:49:43 -07003163}
3164
3165InputDispatcher::InputState::~InputState() {
3166}
3167
3168bool InputDispatcher::InputState::isNeutral() const {
3169 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3170}
3171
Jeff Browna665ca82010-09-08 11:49:43 -07003172InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3173 const EventEntry* entry) {
3174 switch (entry->type) {
3175 case EventEntry::TYPE_KEY:
3176 return trackKey(static_cast<const KeyEntry*>(entry));
3177
3178 case EventEntry::TYPE_MOTION:
3179 return trackMotion(static_cast<const MotionEntry*>(entry));
3180
3181 default:
3182 return CONSISTENT;
3183 }
3184}
3185
3186InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3187 const KeyEntry* entry) {
3188 int32_t action = entry->action;
3189 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3190 KeyMemento& memento = mKeyMementos.editItemAt(i);
3191 if (memento.deviceId == entry->deviceId
3192 && memento.source == entry->source
3193 && memento.keyCode == entry->keyCode
3194 && memento.scanCode == entry->scanCode) {
3195 switch (action) {
3196 case AKEY_EVENT_ACTION_UP:
3197 mKeyMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003198 return CONSISTENT;
3199
3200 case AKEY_EVENT_ACTION_DOWN:
3201 return TOLERABLE;
3202
3203 default:
3204 return BROKEN;
3205 }
3206 }
3207 }
3208
3209 switch (action) {
3210 case AKEY_EVENT_ACTION_DOWN: {
3211 mKeyMementos.push();
3212 KeyMemento& memento = mKeyMementos.editTop();
3213 memento.deviceId = entry->deviceId;
3214 memento.source = entry->source;
3215 memento.keyCode = entry->keyCode;
3216 memento.scanCode = entry->scanCode;
3217 memento.downTime = entry->downTime;
3218 return CONSISTENT;
3219 }
3220
3221 default:
3222 return BROKEN;
3223 }
3224}
3225
3226InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3227 const MotionEntry* entry) {
3228 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3229 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3230 MotionMemento& memento = mMotionMementos.editItemAt(i);
3231 if (memento.deviceId == entry->deviceId
3232 && memento.source == entry->source) {
3233 switch (action) {
3234 case AMOTION_EVENT_ACTION_UP:
3235 case AMOTION_EVENT_ACTION_CANCEL:
3236 mMotionMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003237 return CONSISTENT;
3238
3239 case AMOTION_EVENT_ACTION_DOWN:
3240 return TOLERABLE;
3241
3242 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3243 if (entry->pointerCount == memento.pointerCount + 1) {
3244 memento.setPointers(entry);
3245 return CONSISTENT;
3246 }
3247 return BROKEN;
3248
3249 case AMOTION_EVENT_ACTION_POINTER_UP:
3250 if (entry->pointerCount == memento.pointerCount - 1) {
3251 memento.setPointers(entry);
3252 return CONSISTENT;
3253 }
3254 return BROKEN;
3255
3256 case AMOTION_EVENT_ACTION_MOVE:
3257 if (entry->pointerCount == memento.pointerCount) {
3258 return CONSISTENT;
3259 }
3260 return BROKEN;
3261
3262 default:
3263 return BROKEN;
3264 }
3265 }
3266 }
3267
3268 switch (action) {
3269 case AMOTION_EVENT_ACTION_DOWN: {
3270 mMotionMementos.push();
3271 MotionMemento& memento = mMotionMementos.editTop();
3272 memento.deviceId = entry->deviceId;
3273 memento.source = entry->source;
3274 memento.xPrecision = entry->xPrecision;
3275 memento.yPrecision = entry->yPrecision;
3276 memento.downTime = entry->downTime;
3277 memento.setPointers(entry);
3278 return CONSISTENT;
3279 }
3280
3281 default:
3282 return BROKEN;
3283 }
3284}
3285
3286void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3287 pointerCount = entry->pointerCount;
3288 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3289 pointerIds[i] = entry->pointerIds[i];
3290 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3291 }
3292}
3293
Jeff Brown90f0cee2010-10-08 22:31:17 -07003294void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3295 Allocator* allocator, Vector<EventEntry*>& outEvents,
3296 CancelationOptions options) {
3297 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003298 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003299 if (shouldCancelEvent(memento.source, options)) {
3300 outEvents.push(allocator->obtainKeyEntry(currentTime,
3301 memento.deviceId, memento.source, 0,
3302 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3303 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3304 mKeyMementos.removeAt(i);
3305 } else {
3306 i += 1;
3307 }
Jeff Browna665ca82010-09-08 11:49:43 -07003308 }
3309
Jeff Brown316237d2010-10-11 18:22:53 -07003310 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003311 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003312 if (shouldCancelEvent(memento.source, options)) {
3313 outEvents.push(allocator->obtainMotionEntry(currentTime,
3314 memento.deviceId, memento.source, 0,
3315 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3316 memento.xPrecision, memento.yPrecision, memento.downTime,
3317 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3318 mMotionMementos.removeAt(i);
3319 } else {
3320 i += 1;
3321 }
Jeff Browna665ca82010-09-08 11:49:43 -07003322 }
3323}
3324
3325void InputDispatcher::InputState::clear() {
3326 mKeyMementos.clear();
3327 mMotionMementos.clear();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003328}
3329
3330bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3331 CancelationOptions options) {
3332 switch (options) {
3333 case CANCEL_POINTER_EVENTS:
3334 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3335 case CANCEL_NON_POINTER_EVENTS:
3336 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3337 default:
3338 return true;
3339 }
Jeff Browna665ca82010-09-08 11:49:43 -07003340}
3341
3342
Jeff Browne839a582010-04-22 18:58:52 -07003343// --- InputDispatcher::Connection ---
3344
3345InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3346 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003347 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003348}
3349
3350InputDispatcher::Connection::~Connection() {
3351}
3352
3353status_t InputDispatcher::Connection::initialize() {
3354 return inputPublisher.initialize();
3355}
3356
Jeff Brown54bc2812010-06-15 01:31:58 -07003357const char* InputDispatcher::Connection::getStatusLabel() const {
3358 switch (status) {
3359 case STATUS_NORMAL:
3360 return "NORMAL";
3361
3362 case STATUS_BROKEN:
3363 return "BROKEN";
3364
Jeff Brown54bc2812010-06-15 01:31:58 -07003365 case STATUS_ZOMBIE:
3366 return "ZOMBIE";
3367
3368 default:
3369 return "UNKNOWN";
3370 }
3371}
3372
Jeff Browne839a582010-04-22 18:58:52 -07003373InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3374 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003375 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3376 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003377 if (dispatchEntry->eventEntry == eventEntry) {
3378 return dispatchEntry;
3379 }
3380 }
3381 return NULL;
3382}
3383
Jeff Browna665ca82010-09-08 11:49:43 -07003384
Jeff Brown54bc2812010-06-15 01:31:58 -07003385// --- InputDispatcher::CommandEntry ---
3386
Jeff Browna665ca82010-09-08 11:49:43 -07003387InputDispatcher::CommandEntry::CommandEntry() :
3388 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003389}
3390
3391InputDispatcher::CommandEntry::~CommandEntry() {
3392}
3393
Jeff Browne839a582010-04-22 18:58:52 -07003394
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003395// --- InputDispatcher::TouchState ---
3396
3397InputDispatcher::TouchState::TouchState() :
3398 down(false), split(false) {
3399}
3400
3401InputDispatcher::TouchState::~TouchState() {
3402}
3403
3404void InputDispatcher::TouchState::reset() {
3405 down = false;
3406 split = false;
3407 windows.clear();
3408}
3409
3410void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3411 down = other.down;
3412 split = other.split;
3413 windows.clear();
3414 windows.appendVector(other.windows);
3415}
3416
3417void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3418 int32_t targetFlags, BitSet32 pointerIds) {
3419 if (targetFlags & InputTarget::FLAG_SPLIT) {
3420 split = true;
3421 }
3422
3423 for (size_t i = 0; i < windows.size(); i++) {
3424 TouchedWindow& touchedWindow = windows.editItemAt(i);
3425 if (touchedWindow.window == window) {
3426 touchedWindow.targetFlags |= targetFlags;
3427 touchedWindow.pointerIds.value |= pointerIds.value;
3428 return;
3429 }
3430 }
3431
3432 windows.push();
3433
3434 TouchedWindow& touchedWindow = windows.editTop();
3435 touchedWindow.window = window;
3436 touchedWindow.targetFlags = targetFlags;
3437 touchedWindow.pointerIds = pointerIds;
3438 touchedWindow.channel = window->inputChannel;
3439}
3440
3441void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3442 for (size_t i = 0 ; i < windows.size(); ) {
3443 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3444 windows.removeAt(i);
3445 } else {
3446 i += 1;
3447 }
3448 }
3449}
3450
3451const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3452 for (size_t i = 0; i < windows.size(); i++) {
3453 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3454 return windows[i].window;
3455 }
3456 }
3457 return NULL;
3458}
3459
3460
Jeff Browne839a582010-04-22 18:58:52 -07003461// --- InputDispatcherThread ---
3462
3463InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3464 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3465}
3466
3467InputDispatcherThread::~InputDispatcherThread() {
3468}
3469
3470bool InputDispatcherThread::threadLoop() {
3471 mDispatcher->dispatchOnce();
3472 return true;
3473}
3474
3475} // namespace android