blob: 92daee19eaecd727788ac79ec3eda1768d14bf58 [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 }
343 }
344
345 // Now we have an event to dispatch.
346 assert(mPendingEvent != NULL);
Jeff Brownd8816c32010-09-16 14:07:33 -0700347 bool done = false;
Jeff Brown90f0cee2010-10-08 22:31:17 -0700348 DropReason dropReason = DROP_REASON_NOT_DROPPED;
349 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
350 dropReason = DROP_REASON_POLICY;
351 } else if (!mDispatchEnabled) {
352 dropReason = DROP_REASON_DISABLED;
353 }
Jeff Browna665ca82010-09-08 11:49:43 -0700354 switch (mPendingEvent->type) {
355 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
356 ConfigurationChangedEntry* typedEntry =
357 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brownd8816c32010-09-16 14:07:33 -0700358 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700359 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Browna665ca82010-09-08 11:49:43 -0700360 break;
361 }
362
363 case EventEntry::TYPE_KEY: {
364 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700365 if (isAppSwitchDue) {
366 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700367 resetPendingAppSwitchLocked(true);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700368 isAppSwitchDue = false;
369 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
370 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700371 }
372 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700373 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700374 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700375 break;
376 }
377
378 case EventEntry::TYPE_MOTION: {
379 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700380 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
381 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700382 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700383 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700384 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700385 break;
386 }
387
388 default:
389 assert(false);
Jeff Browna665ca82010-09-08 11:49:43 -0700390 break;
391 }
392
Jeff Brownd8816c32010-09-16 14:07:33 -0700393 if (done) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700394 if (dropReason != DROP_REASON_NOT_DROPPED) {
395 dropInboundEventLocked(mPendingEvent, dropReason);
396 }
397
Jeff Brownd8816c32010-09-16 14:07:33 -0700398 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700399 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
400 }
401}
402
403bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
404 bool needWake = mInboundQueue.isEmpty();
405 mInboundQueue.enqueueAtTail(entry);
406
407 switch (entry->type) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700408 case EventEntry::TYPE_KEY: {
409 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
410 if (isAppSwitchKeyEventLocked(keyEntry)) {
411 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
412 mAppSwitchSawKeyDown = true;
413 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
414 if (mAppSwitchSawKeyDown) {
415#if DEBUG_APP_SWITCH
416 LOGD("App switch is pending!");
417#endif
418 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
419 mAppSwitchSawKeyDown = false;
420 needWake = true;
421 }
422 }
423 }
Jeff Browna665ca82010-09-08 11:49:43 -0700424 break;
425 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700426 }
Jeff Browna665ca82010-09-08 11:49:43 -0700427
428 return needWake;
429}
430
Jeff Brown90f0cee2010-10-08 22:31:17 -0700431void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
432 const char* reason;
433 switch (dropReason) {
434 case DROP_REASON_POLICY:
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700435#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Browna8ed8562010-10-11 23:32:49 -0700436 LOGD("Dropped event because policy consumed it.");
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700437#endif
Jeff Browna8ed8562010-10-11 23:32:49 -0700438 reason = "inbound event was dropped because the policy consumed it";
Jeff Brown90f0cee2010-10-08 22:31:17 -0700439 break;
440 case DROP_REASON_DISABLED:
441 LOGI("Dropped event because input dispatch is disabled.");
442 reason = "inbound event was dropped because input dispatch is disabled";
443 break;
444 case DROP_REASON_APP_SWITCH:
445 LOGI("Dropped event because of pending overdue app switch.");
446 reason = "inbound event was dropped because of pending overdue app switch";
447 break;
448 default:
449 assert(false);
450 return;
451 }
452
453 switch (entry->type) {
454 case EventEntry::TYPE_KEY:
455 synthesizeCancelationEventsForAllConnectionsLocked(
456 InputState::CANCEL_NON_POINTER_EVENTS, reason);
457 break;
458 case EventEntry::TYPE_MOTION: {
459 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
460 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
461 synthesizeCancelationEventsForAllConnectionsLocked(
462 InputState::CANCEL_POINTER_EVENTS, reason);
463 } else {
464 synthesizeCancelationEventsForAllConnectionsLocked(
465 InputState::CANCEL_NON_POINTER_EVENTS, reason);
466 }
467 break;
468 }
469 }
470}
471
472bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Browna665ca82010-09-08 11:49:43 -0700473 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
474}
475
Jeff Brown90f0cee2010-10-08 22:31:17 -0700476bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
477 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
478 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700479 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brown90f0cee2010-10-08 22:31:17 -0700480 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
481}
482
Jeff Browna665ca82010-09-08 11:49:43 -0700483bool InputDispatcher::isAppSwitchPendingLocked() {
484 return mAppSwitchDueTime != LONG_LONG_MAX;
485}
486
Jeff Browna665ca82010-09-08 11:49:43 -0700487void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
488 mAppSwitchDueTime = LONG_LONG_MAX;
489
490#if DEBUG_APP_SWITCH
491 if (handled) {
492 LOGD("App switch has arrived.");
493 } else {
494 LOGD("App switch was abandoned.");
495 }
496#endif
Jeff Browne839a582010-04-22 18:58:52 -0700497}
498
Jeff Brown54bc2812010-06-15 01:31:58 -0700499bool InputDispatcher::runCommandsLockedInterruptible() {
500 if (mCommandQueue.isEmpty()) {
501 return false;
502 }
Jeff Browne839a582010-04-22 18:58:52 -0700503
Jeff Brown54bc2812010-06-15 01:31:58 -0700504 do {
505 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
506
507 Command command = commandEntry->command;
508 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
509
Jeff Brown51d45a72010-06-17 20:52:56 -0700510 commandEntry->connection.clear();
Jeff Brown54bc2812010-06-15 01:31:58 -0700511 mAllocator.releaseCommandEntry(commandEntry);
512 } while (! mCommandQueue.isEmpty());
513 return true;
Jeff Browne839a582010-04-22 18:58:52 -0700514}
515
Jeff Brown54bc2812010-06-15 01:31:58 -0700516InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
517 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
518 mCommandQueue.enqueueAtTail(commandEntry);
519 return commandEntry;
520}
521
Jeff Browna665ca82010-09-08 11:49:43 -0700522void InputDispatcher::drainInboundQueueLocked() {
523 while (! mInboundQueue.isEmpty()) {
524 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brownd8816c32010-09-16 14:07:33 -0700525 releaseInboundEventLocked(entry);
Jeff Browne839a582010-04-22 18:58:52 -0700526 }
Jeff Browne839a582010-04-22 18:58:52 -0700527}
528
Jeff Brownd8816c32010-09-16 14:07:33 -0700529void InputDispatcher::releasePendingEventLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700530 if (mPendingEvent) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700531 releaseInboundEventLocked(mPendingEvent);
Jeff Browna665ca82010-09-08 11:49:43 -0700532 mPendingEvent = NULL;
533 }
534}
535
Jeff Brownd8816c32010-09-16 14:07:33 -0700536void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700537 InjectionState* injectionState = entry->injectionState;
538 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Browna665ca82010-09-08 11:49:43 -0700539#if DEBUG_DISPATCH_CYCLE
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700540 LOGD("Injected inbound event was dropped.");
Jeff Browna665ca82010-09-08 11:49:43 -0700541#endif
542 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
543 }
544 mAllocator.releaseEventEntry(entry);
545}
546
Jeff Browna665ca82010-09-08 11:49:43 -0700547void InputDispatcher::resetKeyRepeatLocked() {
548 if (mKeyRepeatState.lastKeyEntry) {
549 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
550 mKeyRepeatState.lastKeyEntry = NULL;
551 }
552}
553
554InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brown61ce3982010-09-07 10:44:57 -0700555 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown50de30a2010-06-22 01:27:15 -0700556 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
557
Jeff Brown50de30a2010-06-22 01:27:15 -0700558 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700559 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
560 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Browne839a582010-04-22 18:58:52 -0700561 if (entry->refCount == 1) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700562 mAllocator.recycleKeyEntry(entry);
Jeff Brown51d45a72010-06-17 20:52:56 -0700563 entry->eventTime = currentTime;
Jeff Brown51d45a72010-06-17 20:52:56 -0700564 entry->policyFlags = policyFlags;
Jeff Browne839a582010-04-22 18:58:52 -0700565 entry->repeatCount += 1;
566 } else {
Jeff Brown51d45a72010-06-17 20:52:56 -0700567 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700568 entry->deviceId, entry->source, policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700569 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brownf16c26d2010-07-02 15:37:36 -0700570 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Browne839a582010-04-22 18:58:52 -0700571
572 mKeyRepeatState.lastKeyEntry = newEntry;
573 mAllocator.releaseKeyEntry(entry);
574
575 entry = newEntry;
576 }
Jeff Browna665ca82010-09-08 11:49:43 -0700577 entry->syntheticRepeat = true;
578
579 // Increment reference count since we keep a reference to the event in
580 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
581 entry->refCount += 1;
Jeff Browne839a582010-04-22 18:58:52 -0700582
Jeff Brownf16c26d2010-07-02 15:37:36 -0700583 if (entry->repeatCount == 1) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700584 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brownf16c26d2010-07-02 15:37:36 -0700585 }
586
Jeff Brown61ce3982010-09-07 10:44:57 -0700587 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Browna665ca82010-09-08 11:49:43 -0700588 return entry;
Jeff Browne839a582010-04-22 18:58:52 -0700589}
590
Jeff Browna665ca82010-09-08 11:49:43 -0700591bool InputDispatcher::dispatchConfigurationChangedLocked(
592 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Browne839a582010-04-22 18:58:52 -0700593#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Browna665ca82010-09-08 11:49:43 -0700594 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
595#endif
596
597 // Reset key repeating in case a keyboard device was added or removed or something.
598 resetKeyRepeatLocked();
599
600 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
601 CommandEntry* commandEntry = postCommandLocked(
602 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
603 commandEntry->eventTime = entry->eventTime;
604 return true;
605}
606
607bool InputDispatcher::dispatchKeyLocked(
608 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700609 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700610 // Give the policy a chance to intercept the key.
611 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700612 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700613 CommandEntry* commandEntry = postCommandLocked(
614 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700615 if (mFocusedWindow) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700616 commandEntry->inputChannel = mFocusedWindow->inputChannel;
617 }
618 commandEntry->keyEntry = entry;
619 entry->refCount += 1;
620 return false; // wait for the command to run
621 } else {
622 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
623 }
624 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700625 if (*dropReason == DROP_REASON_NOT_DROPPED) {
626 *dropReason = DROP_REASON_POLICY;
627 }
Jeff Brownd8816c32010-09-16 14:07:33 -0700628 }
629
630 // Clean up if dropping the event.
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700631 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700632 resetTargetsLocked();
Jeff Browna8ed8562010-10-11 23:32:49 -0700633 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
634 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brownd8816c32010-09-16 14:07:33 -0700635 return true;
636 }
637
Jeff Browna665ca82010-09-08 11:49:43 -0700638 // Preprocessing.
639 if (! entry->dispatchInProgress) {
640 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
641
642 if (entry->repeatCount == 0
643 && entry->action == AKEY_EVENT_ACTION_DOWN
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700644 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
645 && !entry->isInjected()) {
Jeff Browna665ca82010-09-08 11:49:43 -0700646 if (mKeyRepeatState.lastKeyEntry
647 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
648 // We have seen two identical key downs in a row which indicates that the device
649 // driver is automatically generating key repeats itself. We take note of the
650 // repeat here, but we disable our own next key repeat timer since it is clear that
651 // we will not need to synthesize key repeats ourselves.
652 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
653 resetKeyRepeatLocked();
654 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
655 } else {
656 // Not a repeat. Save key down state in case we do see a repeat later.
657 resetKeyRepeatLocked();
658 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
659 }
660 mKeyRepeatState.lastKeyEntry = entry;
661 entry->refCount += 1;
662 } else if (! entry->syntheticRepeat) {
663 resetKeyRepeatLocked();
664 }
665
666 entry->dispatchInProgress = true;
Jeff Brownd8816c32010-09-16 14:07:33 -0700667 resetTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700668 }
669
670 // Identify targets.
671 if (! mCurrentInputTargetsValid) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700672 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
673 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700674 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
675 return false;
676 }
677
678 setInjectionResultLocked(entry, injectionResult);
679 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
680 return true;
681 }
682
683 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700684 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700685 }
686
687 // Dispatch the key.
688 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
689
690 // Poke user activity.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700691 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
692 pokeUserActivityLocked(entry->eventTime, POWER_MANAGER_BUTTON_EVENT);
693 }
Jeff Browna665ca82010-09-08 11:49:43 -0700694 return true;
695}
696
697void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
698#if DEBUG_OUTBOUND_EVENT_DETAILS
699 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
700 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
701 "downTime=%lld",
702 prefix,
703 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
704 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
705 entry->downTime);
706#endif
707}
708
709bool InputDispatcher::dispatchMotionLocked(
Jeff 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);
756
757 // Poke user activity.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700758 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
759 int32_t eventType;
760 if (isPointerEvent) {
761 switch (entry->action) {
762 case AMOTION_EVENT_ACTION_DOWN:
Jeff Browna665ca82010-09-08 11:49:43 -0700763 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700764 break;
765 case AMOTION_EVENT_ACTION_UP:
766 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
767 break;
768 default:
769 if (entry->eventTime - entry->downTime >= EVENT_IGNORE_DURATION) {
770 eventType = POWER_MANAGER_TOUCH_EVENT;
771 } else {
772 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
773 }
774 break;
Jeff Browna665ca82010-09-08 11:49:43 -0700775 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700776 } else {
777 eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Browna665ca82010-09-08 11:49:43 -0700778 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700779 pokeUserActivityLocked(entry->eventTime, eventType);
Jeff Browna665ca82010-09-08 11:49:43 -0700780 }
Jeff Browna665ca82010-09-08 11:49:43 -0700781 return true;
782}
783
784
785void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
786#if DEBUG_OUTBOUND_EVENT_DETAILS
787 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700788 "action=0x%x, flags=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700789 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700790 prefix,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700791 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
792 entry->action, entry->flags,
Jeff Browne839a582010-04-22 18:58:52 -0700793 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
794 entry->downTime);
795
796 // Print the most recent sample that we have available, this may change due to batching.
797 size_t sampleCount = 1;
Jeff Browna665ca82010-09-08 11:49:43 -0700798 const MotionSample* sample = & entry->firstSample;
Jeff Browne839a582010-04-22 18:58:52 -0700799 for (; sample->next != NULL; sample = sample->next) {
800 sampleCount += 1;
801 }
802 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -0700803 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700804 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -0700805 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -0700806 i, entry->pointerIds[i],
Jeff Brown38a7fab2010-08-30 03:02:23 -0700807 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
808 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
809 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
810 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
811 sample->pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -0700812 }
813
814 // Keep in mind that due to batching, it is possible for the number of samples actually
815 // dispatched to change before the application finally consumed them.
Jeff Brown5c1ed842010-07-14 18:48:53 -0700816 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -0700817 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
818 }
819#endif
Jeff Browne839a582010-04-22 18:58:52 -0700820}
821
822void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
823 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
824#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700825 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700826 "resumeWithAppendedMotionSample=%s",
Jeff Browna665ca82010-09-08 11:49:43 -0700827 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -0700828#endif
829
Jeff Brown54bc2812010-06-15 01:31:58 -0700830 assert(eventEntry->dispatchInProgress); // should already have been set to true
831
Jeff Browne839a582010-04-22 18:58:52 -0700832 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
833 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
834
Jeff Brown53a415e2010-09-15 15:18:56 -0700835 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -0700836 if (connectionIndex >= 0) {
837 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown51d45a72010-06-17 20:52:56 -0700838 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -0700839 resumeWithAppendedMotionSample);
840 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700841#if DEBUG_FOCUS
842 LOGD("Dropping event delivery to target with channel '%s' because it "
843 "is no longer registered with the input dispatcher.",
Jeff Browne839a582010-04-22 18:58:52 -0700844 inputTarget.inputChannel->getName().string());
Jeff Brown90f0cee2010-10-08 22:31:17 -0700845#endif
Jeff Browne839a582010-04-22 18:58:52 -0700846 }
847 }
848}
849
Jeff Brownd8816c32010-09-16 14:07:33 -0700850void InputDispatcher::resetTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700851 mCurrentInputTargetsValid = false;
852 mCurrentInputTargets.clear();
Jeff Browna665ca82010-09-08 11:49:43 -0700853 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
854}
855
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700856void InputDispatcher::commitTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700857 mCurrentInputTargetsValid = true;
858}
859
860int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
861 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
862 nsecs_t* nextWakeupTime) {
863 if (application == NULL && window == NULL) {
864 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
865#if DEBUG_FOCUS
866 LOGD("Waiting for system to become ready for input.");
867#endif
868 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
869 mInputTargetWaitStartTime = currentTime;
870 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
871 mInputTargetWaitTimeoutExpired = false;
872 }
873 } else {
874 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
875#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700876 LOGD("Waiting for application to become ready for input: %s",
877 getApplicationWindowLabelLocked(application, window).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700878#endif
879 nsecs_t timeout = window ? window->dispatchingTimeout :
880 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
881
882 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
883 mInputTargetWaitStartTime = currentTime;
884 mInputTargetWaitTimeoutTime = currentTime + timeout;
885 mInputTargetWaitTimeoutExpired = false;
886 }
887 }
888
889 if (mInputTargetWaitTimeoutExpired) {
890 return INPUT_EVENT_INJECTION_TIMED_OUT;
891 }
892
893 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown53a415e2010-09-15 15:18:56 -0700894 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700895
896 // Force poll loop to wake up immediately on next iteration once we get the
897 // ANR response back from the policy.
898 *nextWakeupTime = LONG_LONG_MIN;
899 return INPUT_EVENT_INJECTION_PENDING;
900 } else {
901 // Force poll loop to wake up when timeout is due.
902 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
903 *nextWakeupTime = mInputTargetWaitTimeoutTime;
904 }
905 return INPUT_EVENT_INJECTION_PENDING;
906 }
907}
908
Jeff Brown53a415e2010-09-15 15:18:56 -0700909void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
910 const sp<InputChannel>& inputChannel) {
Jeff Browna665ca82010-09-08 11:49:43 -0700911 if (newTimeout > 0) {
912 // Extend the timeout.
913 mInputTargetWaitTimeoutTime = now() + newTimeout;
914 } else {
915 // Give up.
916 mInputTargetWaitTimeoutExpired = true;
Jeff Brown53a415e2010-09-15 15:18:56 -0700917
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700918 // Release the touch targets.
919 mTouchState.reset();
Jeff Brown405a1d32010-09-16 12:31:46 -0700920
Jeff Brown53a415e2010-09-15 15:18:56 -0700921 // Input state will not be realistic. Mark it out of sync.
Jeff Brown40ad4702010-09-16 11:02:16 -0700922 if (inputChannel.get()) {
923 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
924 if (connectionIndex >= 0) {
925 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700926 synthesizeCancelationEventsForConnectionLocked(
927 connection, InputState::CANCEL_ALL_EVENTS,
928 "application not responding");
Jeff Brown40ad4702010-09-16 11:02:16 -0700929 }
Jeff Brown53a415e2010-09-15 15:18:56 -0700930 }
Jeff Browna665ca82010-09-08 11:49:43 -0700931 }
932}
933
Jeff Brown53a415e2010-09-15 15:18:56 -0700934nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Browna665ca82010-09-08 11:49:43 -0700935 nsecs_t currentTime) {
936 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
937 return currentTime - mInputTargetWaitStartTime;
938 }
939 return 0;
940}
941
942void InputDispatcher::resetANRTimeoutsLocked() {
943#if DEBUG_FOCUS
944 LOGD("Resetting ANR timeouts.");
945#endif
946
Jeff Browna665ca82010-09-08 11:49:43 -0700947 // Reset input target wait timeout.
948 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
949}
950
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700951int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
952 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -0700953 mCurrentInputTargets.clear();
954
955 int32_t injectionResult;
956
957 // If there is no currently focused window and no focused application
958 // then drop the event.
959 if (! mFocusedWindow) {
960 if (mFocusedApplication) {
961#if DEBUG_FOCUS
962 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -0700963 "focused application that may eventually add a window: %s.",
964 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700965#endif
966 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
967 mFocusedApplication, NULL, nextWakeupTime);
968 goto Unresponsive;
969 }
970
971 LOGI("Dropping event because there is no focused window or focused application.");
972 injectionResult = INPUT_EVENT_INJECTION_FAILED;
973 goto Failed;
974 }
975
976 // Check permissions.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700977 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700978 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
979 goto Failed;
980 }
981
982 // If the currently focused window is paused then keep waiting.
983 if (mFocusedWindow->paused) {
984#if DEBUG_FOCUS
985 LOGD("Waiting because focused window is paused.");
986#endif
987 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
988 mFocusedApplication, mFocusedWindow, nextWakeupTime);
989 goto Unresponsive;
990 }
991
Jeff Brown53a415e2010-09-15 15:18:56 -0700992 // If the currently focused window is still working on previous events then keep waiting.
993 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
994#if DEBUG_FOCUS
995 LOGD("Waiting because focused window still processing previous input.");
996#endif
997 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
998 mFocusedApplication, mFocusedWindow, nextWakeupTime);
999 goto Unresponsive;
1000 }
1001
Jeff Browna665ca82010-09-08 11:49:43 -07001002 // Success! Output targets.
1003 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001004 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -07001005
1006 // Done.
1007Failed:
1008Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -07001009 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1010 updateDispatchStatisticsLocked(currentTime, entry,
1011 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001012#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -07001013 LOGD("findFocusedWindow finished: injectionResult=%d, "
1014 "timeSpendWaitingForApplication=%0.1fms",
1015 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001016#endif
1017 return injectionResult;
1018}
1019
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001020int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1021 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -07001022 enum InjectionPermission {
1023 INJECTION_PERMISSION_UNKNOWN,
1024 INJECTION_PERMISSION_GRANTED,
1025 INJECTION_PERMISSION_DENIED
1026 };
1027
Jeff Browna665ca82010-09-08 11:49:43 -07001028 mCurrentInputTargets.clear();
1029
1030 nsecs_t startTime = now();
1031
1032 // For security reasons, we defer updating the touch state until we are sure that
1033 // event injection will be allowed.
1034 //
1035 // FIXME In the original code, screenWasOff could never be set to true.
1036 // The reason is that the POLICY_FLAG_WOKE_HERE
1037 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1038 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1039 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1040 // events upon which no preprocessing took place. So policyFlags was always 0.
1041 // In the new native input dispatcher we're a bit more careful about event
1042 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1043 // Unfortunately we obtain undesirable behavior.
1044 //
1045 // Here's what happens:
1046 //
1047 // When the device dims in anticipation of going to sleep, touches
1048 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1049 // the device to brighten and reset the user activity timer.
1050 // Touches on other windows (such as the launcher window)
1051 // are dropped. Then after a moment, the device goes to sleep. Oops.
1052 //
1053 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1054 // instead of POLICY_FLAG_WOKE_HERE...
1055 //
1056 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1057
1058 int32_t action = entry->action;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001059 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Browna665ca82010-09-08 11:49:43 -07001060
1061 // Update the touch state as needed based on the properties of the touch event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001062 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1063 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1064 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1065 mTempTouchState.reset();
1066 mTempTouchState.down = true;
1067 } else {
1068 mTempTouchState.copyFrom(mTouchState);
1069 }
Jeff Browna665ca82010-09-08 11:49:43 -07001070
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001071 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1072 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1073 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1074 /* Case 1: New splittable pointer going down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001075
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001076 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1077 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1078 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1079 const InputWindow* newTouchedWindow = NULL;
1080 const InputWindow* topErrorWindow = NULL;
Jeff Browna665ca82010-09-08 11:49:43 -07001081
1082 // Traverse windows from front to back to find touched window and outside targets.
1083 size_t numWindows = mWindows.size();
1084 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001085 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07001086 int32_t flags = window->layoutParamsFlags;
1087
1088 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1089 if (! topErrorWindow) {
1090 topErrorWindow = window;
1091 }
1092 }
1093
1094 if (window->visible) {
1095 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1096 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1097 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1098 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1099 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1100 newTouchedWindow = window;
Jeff Browna665ca82010-09-08 11:49:43 -07001101 }
1102 break; // found touched window, exit window loop
1103 }
1104 }
1105
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001106 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1107 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001108 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1109 if (isWindowObscuredAtPointLocked(window, x, y)) {
1110 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1111 }
1112
1113 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -07001114 }
1115 }
1116 }
1117
1118 // If there is an error window but it is not taking focus (typically because
1119 // it is invisible) then wait for it. Any other focused window may in
1120 // fact be in ANR state.
1121 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1122#if DEBUG_FOCUS
1123 LOGD("Waiting because system error window is pending.");
1124#endif
1125 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1126 NULL, NULL, nextWakeupTime);
1127 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1128 goto Unresponsive;
1129 }
1130
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001131 // Figure out whether splitting will be allowed for this window.
Jeff Brown1c322582010-09-28 13:24:41 -07001132 if (newTouchedWindow
1133 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001134 // New window supports splitting.
1135 isSplit = true;
1136 } else if (isSplit) {
1137 // New window does not support splitting but we have already split events.
1138 // Assign the pointer to the first foreground window we find.
1139 // (May be NULL which is why we put this code block before the next check.)
1140 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1141 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001142
Jeff Browna665ca82010-09-08 11:49:43 -07001143 // If we did not find a touched window then fail.
1144 if (! newTouchedWindow) {
1145 if (mFocusedApplication) {
1146#if DEBUG_FOCUS
1147 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -07001148 "focused application that may eventually add a new window: %s.",
1149 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -07001150#endif
1151 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1152 mFocusedApplication, NULL, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -07001153 goto Unresponsive;
1154 }
1155
1156 LOGI("Dropping event because there is no touched window or focused application.");
1157 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001158 goto Failed;
1159 }
1160
Jeff Brown35cf0e92010-10-05 12:26:23 -07001161 // Set target flags.
1162 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1163 if (isSplit) {
1164 targetFlags |= InputTarget::FLAG_SPLIT;
1165 }
1166 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1167 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1168 }
1169
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001170 // Update the temporary touch state.
1171 BitSet32 pointerIds;
1172 if (isSplit) {
1173 uint32_t pointerId = entry->pointerIds[pointerIndex];
1174 pointerIds.markBit(pointerId);
Jeff Browna665ca82010-09-08 11:49:43 -07001175 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001176 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001177 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001178 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001179
1180 // If the pointer is not currently down, then ignore the event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001181 if (! mTempTouchState.down) {
Jeff Browna665ca82010-09-08 11:49:43 -07001182 LOGI("Dropping event because the pointer is not down.");
1183 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001184 goto Failed;
1185 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001186 }
Jeff Browna665ca82010-09-08 11:49:43 -07001187
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001188 // Check permission to inject into all touched foreground windows and ensure there
1189 // is at least one touched foreground window.
1190 {
1191 bool haveForegroundWindow = false;
1192 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1193 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1194 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1195 haveForegroundWindow = true;
1196 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1197 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1198 injectionPermission = INJECTION_PERMISSION_DENIED;
1199 goto Failed;
1200 }
1201 }
1202 }
1203 if (! haveForegroundWindow) {
Jeff Browna665ca82010-09-08 11:49:43 -07001204#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001205 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Browna665ca82010-09-08 11:49:43 -07001206#endif
1207 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001208 goto Failed;
1209 }
1210
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001211 // Permission granted to injection into all touched foreground windows.
1212 injectionPermission = INJECTION_PERMISSION_GRANTED;
1213 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001214
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001215 // Ensure all touched foreground windows are ready for new input.
1216 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1217 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1218 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1219 // If the touched window is paused then keep waiting.
1220 if (touchedWindow.window->paused) {
1221#if DEBUG_INPUT_DISPATCHER_POLICY
1222 LOGD("Waiting because touched window is paused.");
Jeff Brown53a415e2010-09-15 15:18:56 -07001223#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001224 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1225 NULL, touchedWindow.window, nextWakeupTime);
1226 goto Unresponsive;
1227 }
1228
1229 // If the touched window is still working on previous events then keep waiting.
1230 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1231#if DEBUG_FOCUS
1232 LOGD("Waiting because touched window still processing previous input.");
1233#endif
1234 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1235 NULL, touchedWindow.window, nextWakeupTime);
1236 goto Unresponsive;
1237 }
1238 }
1239 }
1240
1241 // If this is the first pointer going down and the touched window has a wallpaper
1242 // then also add the touched wallpaper windows so they are locked in for the duration
1243 // of the touch gesture.
1244 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1245 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1246 if (foregroundWindow->hasWallpaper) {
1247 for (size_t i = 0; i < mWindows.size(); i++) {
1248 const InputWindow* window = & mWindows[i];
1249 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001250 mTempTouchState.addOrUpdateWindow(window,
1251 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001252 }
1253 }
1254 }
1255 }
1256
Jeff Browna665ca82010-09-08 11:49:43 -07001257 // Success! Output targets.
1258 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Browna665ca82010-09-08 11:49:43 -07001259
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001260 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1261 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1262 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1263 touchedWindow.pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001264 }
1265
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001266 // Drop the outside touch window since we will not care about them in the next iteration.
1267 mTempTouchState.removeOutsideTouchWindows();
1268
Jeff Browna665ca82010-09-08 11:49:43 -07001269Failed:
1270 // Check injection permission once and for all.
1271 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001272 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001273 injectionPermission = INJECTION_PERMISSION_GRANTED;
1274 } else {
1275 injectionPermission = INJECTION_PERMISSION_DENIED;
1276 }
1277 }
1278
1279 // Update final pieces of touch state if the injector had permission.
1280 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001281 if (maskedAction == AMOTION_EVENT_ACTION_UP
1282 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1283 // All pointers up or canceled.
1284 mTempTouchState.reset();
1285 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1286 // First pointer went down.
1287 if (mTouchState.down) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001288#if DEBUG_FOCUS
1289 LOGD("Pointer down received while already down.");
1290#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001291 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001292 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1293 // One pointer went up.
1294 if (isSplit) {
1295 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1296 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Browna665ca82010-09-08 11:49:43 -07001297
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001298 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1299 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1300 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1301 touchedWindow.pointerIds.clearBit(pointerId);
1302 if (touchedWindow.pointerIds.isEmpty()) {
1303 mTempTouchState.windows.removeAt(i);
1304 continue;
1305 }
1306 }
1307 i += 1;
1308 }
Jeff Browna665ca82010-09-08 11:49:43 -07001309 }
Jeff Browna665ca82010-09-08 11:49:43 -07001310 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001311
1312 // Save changes to touch state.
1313 mTouchState.copyFrom(mTempTouchState);
Jeff Browna665ca82010-09-08 11:49:43 -07001314 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001315#if DEBUG_FOCUS
1316 LOGD("Not updating touch focus because injection was denied.");
1317#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001318 }
1319
1320Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -07001321 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1322 updateDispatchStatisticsLocked(currentTime, entry,
1323 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001324#if DEBUG_FOCUS
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001325 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1326 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown53a415e2010-09-15 15:18:56 -07001327 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001328#endif
1329 return injectionResult;
1330}
1331
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001332void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1333 BitSet32 pointerIds) {
Jeff Browna665ca82010-09-08 11:49:43 -07001334 mCurrentInputTargets.push();
1335
1336 InputTarget& target = mCurrentInputTargets.editTop();
1337 target.inputChannel = window->inputChannel;
1338 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001339 target.xOffset = - window->frameLeft;
1340 target.yOffset = - window->frameTop;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001341 target.windowType = window->layoutParamsType;
1342 target.pointerIds = pointerIds;
Jeff Browna665ca82010-09-08 11:49:43 -07001343}
1344
1345void InputDispatcher::addMonitoringTargetsLocked() {
1346 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1347 mCurrentInputTargets.push();
1348
1349 InputTarget& target = mCurrentInputTargets.editTop();
1350 target.inputChannel = mMonitoringChannels[i];
1351 target.flags = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07001352 target.xOffset = 0;
1353 target.yOffset = 0;
Jeff Brownd9dd44d2010-10-15 00:54:27 -07001354 target.windowType = -1;
Jeff Browna665ca82010-09-08 11:49:43 -07001355 }
1356}
1357
1358bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001359 const InjectionState* injectionState) {
1360 if (injectionState
Jeff Brown90f0cee2010-10-08 22:31:17 -07001361 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1362 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1363 if (window) {
1364 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1365 "with input channel %s owned by uid %d",
1366 injectionState->injectorPid, injectionState->injectorUid,
1367 window->inputChannel->getName().string(),
1368 window->ownerUid);
1369 } else {
1370 LOGW("Permission denied: injecting event from pid %d uid %d",
1371 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-09-08 11:49:43 -07001372 }
Jeff Brown90f0cee2010-10-08 22:31:17 -07001373 return false;
Jeff Browna665ca82010-09-08 11:49:43 -07001374 }
1375 return true;
1376}
1377
Jeff Brown35cf0e92010-10-05 12:26:23 -07001378bool InputDispatcher::isWindowObscuredAtPointLocked(
1379 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Browna665ca82010-09-08 11:49:43 -07001380 size_t numWindows = mWindows.size();
1381 for (size_t i = 0; i < numWindows; i++) {
1382 const InputWindow* other = & mWindows.itemAt(i);
1383 if (other == window) {
1384 break;
1385 }
Jeff Brown35cf0e92010-10-05 12:26:23 -07001386 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001387 return true;
1388 }
1389 }
1390 return false;
1391}
1392
Jeff Brown53a415e2010-09-15 15:18:56 -07001393bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1394 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1395 if (connectionIndex >= 0) {
1396 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1397 return connection->outboundQueue.isEmpty();
1398 } else {
1399 return true;
1400 }
1401}
1402
1403String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1404 const InputWindow* window) {
1405 if (application) {
1406 if (window) {
1407 String8 label(application->name);
1408 label.append(" - ");
1409 label.append(window->name);
1410 return label;
1411 } else {
1412 return application->name;
1413 }
1414 } else if (window) {
1415 return window->name;
1416 } else {
1417 return String8("<unknown application or window>");
1418 }
1419}
1420
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001421bool InputDispatcher::shouldPokeUserActivityForCurrentInputTargetsLocked() {
1422 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
1423 if (mCurrentInputTargets[i].windowType == InputWindow::TYPE_KEYGUARD) {
1424 return false;
1425 }
1426 }
1427 return true;
1428}
1429
1430void InputDispatcher::pokeUserActivityLocked(nsecs_t eventTime, int32_t eventType) {
Jeff Browna665ca82010-09-08 11:49:43 -07001431 CommandEntry* commandEntry = postCommandLocked(
1432 & InputDispatcher::doPokeUserActivityLockedInterruptible);
1433 commandEntry->eventTime = eventTime;
Jeff Browna665ca82010-09-08 11:49:43 -07001434 commandEntry->userActivityEventType = eventType;
1435}
1436
Jeff Brown51d45a72010-06-17 20:52:56 -07001437void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1438 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -07001439 bool resumeWithAppendedMotionSample) {
1440#if DEBUG_DISPATCH_CYCLE
Jeff Brown53a415e2010-09-15 15:18:56 -07001441 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001442 "xOffset=%f, yOffset=%f, "
1443 "windowType=%d, pointerIds=0x%x, "
1444 "resumeWithAppendedMotionSample=%s",
Jeff Brown53a415e2010-09-15 15:18:56 -07001445 connection->getInputChannelName(), inputTarget->flags,
Jeff Browne839a582010-04-22 18:58:52 -07001446 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001447 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Browna665ca82010-09-08 11:49:43 -07001448 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -07001449#endif
1450
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001451 // Make sure we are never called for streaming when splitting across multiple windows.
1452 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1453 assert(! (resumeWithAppendedMotionSample && isSplit));
1454
Jeff Browne839a582010-04-22 18:58:52 -07001455 // Skip this event if the connection status is not normal.
Jeff Brown53a415e2010-09-15 15:18:56 -07001456 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Browne839a582010-04-22 18:58:52 -07001457 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001458#if DEBUG_DISPATCH_CYCLE
1459 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Browna665ca82010-09-08 11:49:43 -07001460 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown90f0cee2010-10-08 22:31:17 -07001461#endif
Jeff Browne839a582010-04-22 18:58:52 -07001462 return;
1463 }
1464
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001465 // Split a motion event if needed.
1466 if (isSplit) {
1467 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1468
1469 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1470 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1471 MotionEntry* splitMotionEntry = splitMotionEvent(
1472 originalMotionEntry, inputTarget->pointerIds);
1473#if DEBUG_FOCUS
1474 LOGD("channel '%s' ~ Split motion event.",
1475 connection->getInputChannelName());
1476 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1477#endif
1478 eventEntry = splitMotionEntry;
1479 }
1480 }
1481
Jeff Browne839a582010-04-22 18:58:52 -07001482 // Resume the dispatch cycle with a freshly appended motion sample.
1483 // First we check that the last dispatch entry in the outbound queue is for the same
1484 // motion event to which we appended the motion sample. If we find such a dispatch
1485 // entry, and if it is currently in progress then we try to stream the new sample.
1486 bool wasEmpty = connection->outboundQueue.isEmpty();
1487
1488 if (! wasEmpty && resumeWithAppendedMotionSample) {
1489 DispatchEntry* motionEventDispatchEntry =
1490 connection->findQueuedDispatchEntryForEvent(eventEntry);
1491 if (motionEventDispatchEntry) {
1492 // If the dispatch entry is not in progress, then we must be busy dispatching an
1493 // earlier event. Not a problem, the motion event is on the outbound queue and will
1494 // be dispatched later.
1495 if (! motionEventDispatchEntry->inProgress) {
1496#if DEBUG_BATCHING
1497 LOGD("channel '%s' ~ Not streaming because the motion event has "
1498 "not yet been dispatched. "
1499 "(Waiting for earlier events to be consumed.)",
1500 connection->getInputChannelName());
1501#endif
1502 return;
1503 }
1504
1505 // If the dispatch entry is in progress but it already has a tail of pending
1506 // motion samples, then it must mean that the shared memory buffer filled up.
1507 // Not a problem, when this dispatch cycle is finished, we will eventually start
1508 // a new dispatch cycle to process the tail and that tail includes the newly
1509 // appended motion sample.
1510 if (motionEventDispatchEntry->tailMotionSample) {
1511#if DEBUG_BATCHING
1512 LOGD("channel '%s' ~ Not streaming because no new samples can "
1513 "be appended to the motion event in this dispatch cycle. "
1514 "(Waiting for next dispatch cycle to start.)",
1515 connection->getInputChannelName());
1516#endif
1517 return;
1518 }
1519
1520 // The dispatch entry is in progress and is still potentially open for streaming.
1521 // Try to stream the new motion sample. This might fail if the consumer has already
1522 // consumed the motion event (or if the channel is broken).
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001523 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1524 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Browne839a582010-04-22 18:58:52 -07001525 status_t status = connection->inputPublisher.appendMotionSample(
1526 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1527 if (status == OK) {
1528#if DEBUG_BATCHING
1529 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1530 connection->getInputChannelName());
1531#endif
1532 return;
1533 }
1534
1535#if DEBUG_BATCHING
1536 if (status == NO_MEMORY) {
1537 LOGD("channel '%s' ~ Could not append motion sample to currently "
1538 "dispatched move event because the shared memory buffer is full. "
1539 "(Waiting for next dispatch cycle to start.)",
1540 connection->getInputChannelName());
1541 } else if (status == status_t(FAILED_TRANSACTION)) {
1542 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown50de30a2010-06-22 01:27:15 -07001543 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-04-22 18:58:52 -07001544 "(Waiting for next dispatch cycle to start.)",
1545 connection->getInputChannelName());
1546 } else {
1547 LOGD("channel '%s' ~ Could not append motion sample to currently "
1548 "dispatched move event due to an error, status=%d. "
1549 "(Waiting for next dispatch cycle to start.)",
1550 connection->getInputChannelName(), status);
1551 }
1552#endif
1553 // Failed to stream. Start a new tail of pending motion samples to dispatch
1554 // in the next cycle.
1555 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1556 return;
1557 }
1558 }
1559
1560 // This is a new event.
1561 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Browna665ca82010-09-08 11:49:43 -07001562 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown53a415e2010-09-15 15:18:56 -07001563 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1564 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001565 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001566 }
1567
Jeff Browne839a582010-04-22 18:58:52 -07001568 // Handle the case where we could not stream a new motion sample because the consumer has
1569 // already consumed the motion event (otherwise the corresponding dispatch entry would
1570 // still be in the outbound queue for this connection). We set the head motion sample
1571 // to the list starting with the newly appended motion sample.
1572 if (resumeWithAppendedMotionSample) {
1573#if DEBUG_BATCHING
1574 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1575 "that cannot be streamed because the motion event has already been consumed.",
1576 connection->getInputChannelName());
1577#endif
1578 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1579 dispatchEntry->headMotionSample = appendedMotionSample;
1580 }
1581
1582 // Enqueue the dispatch entry.
1583 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1584
1585 // If the outbound queue was previously empty, start the dispatch cycle going.
1586 if (wasEmpty) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001587 activateConnectionLocked(connection.get());
Jeff Brown53a415e2010-09-15 15:18:56 -07001588 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001589 }
1590}
1591
Jeff Brown51d45a72010-06-17 20:52:56 -07001592void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown53a415e2010-09-15 15:18:56 -07001593 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001594#if DEBUG_DISPATCH_CYCLE
1595 LOGD("channel '%s' ~ startDispatchCycle",
1596 connection->getInputChannelName());
1597#endif
1598
1599 assert(connection->status == Connection::STATUS_NORMAL);
1600 assert(! connection->outboundQueue.isEmpty());
1601
Jeff Browna665ca82010-09-08 11:49:43 -07001602 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001603 assert(! dispatchEntry->inProgress);
1604
Jeff Browna665ca82010-09-08 11:49:43 -07001605 // Mark the dispatch entry as in progress.
1606 dispatchEntry->inProgress = true;
1607
1608 // Update the connection's input state.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001609 EventEntry* eventEntry = dispatchEntry->eventEntry;
1610 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001611
1612#if FILTER_INPUT_EVENTS
1613 // Filter out inconsistent sequences of input events.
1614 // The input system may drop or inject events in a way that could violate implicit
1615 // invariants on input state and potentially cause an application to crash
1616 // or think that a key or pointer is stuck down. Technically we make no guarantees
1617 // of consistency but it would be nice to improve on this where possible.
1618 // XXX: This code is a proof of concept only. Not ready for prime time.
1619 if (consistency == InputState::TOLERABLE) {
1620#if DEBUG_DISPATCH_CYCLE
1621 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1622 "current input state but that is likely to be tolerated by the application.",
1623 connection->getInputChannelName());
1624#endif
1625 } else if (consistency == InputState::BROKEN) {
1626 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1627 "current input state and that is likely to cause the application to crash.",
1628 connection->getInputChannelName());
1629 startNextDispatchCycleLocked(currentTime, connection);
1630 return;
1631 }
1632#endif
Jeff Browne839a582010-04-22 18:58:52 -07001633
1634 // Publish the event.
1635 status_t status;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001636 switch (eventEntry->type) {
Jeff Browne839a582010-04-22 18:58:52 -07001637 case EventEntry::TYPE_KEY: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001638 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001639
1640 // Apply target flags.
1641 int32_t action = keyEntry->action;
1642 int32_t flags = keyEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001643
1644 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001645 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-04-22 18:58:52 -07001646 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1647 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1648 keyEntry->eventTime);
1649
1650 if (status) {
1651 LOGE("channel '%s' ~ Could not publish key event, "
1652 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001653 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001654 return;
1655 }
1656 break;
1657 }
1658
1659 case EventEntry::TYPE_MOTION: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001660 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001661
1662 // Apply target flags.
1663 int32_t action = motionEntry->action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07001664 int32_t flags = motionEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001665 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001666 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -07001667 }
Jeff Brownaf30ff62010-09-01 17:01:00 -07001668 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1669 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1670 }
Jeff Browne839a582010-04-22 18:58:52 -07001671
1672 // If headMotionSample is non-NULL, then it points to the first new sample that we
1673 // were unable to dispatch during the previous cycle so we resume dispatching from
1674 // that point in the list of motion samples.
1675 // Otherwise, we just start from the first sample of the motion event.
1676 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1677 if (! firstMotionSample) {
1678 firstMotionSample = & motionEntry->firstSample;
1679 }
1680
Jeff Brownf26db0d2010-07-16 17:21:06 -07001681 // Set the X and Y offset depending on the input source.
1682 float xOffset, yOffset;
1683 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1684 xOffset = dispatchEntry->xOffset;
1685 yOffset = dispatchEntry->yOffset;
1686 } else {
1687 xOffset = 0.0f;
1688 yOffset = 0.0f;
1689 }
1690
Jeff Browne839a582010-04-22 18:58:52 -07001691 // Publish the motion event and the first motion sample.
1692 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001693 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -07001694 xOffset, yOffset,
Jeff Browne839a582010-04-22 18:58:52 -07001695 motionEntry->xPrecision, motionEntry->yPrecision,
1696 motionEntry->downTime, firstMotionSample->eventTime,
1697 motionEntry->pointerCount, motionEntry->pointerIds,
1698 firstMotionSample->pointerCoords);
1699
1700 if (status) {
1701 LOGE("channel '%s' ~ Could not publish motion event, "
1702 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001703 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001704 return;
1705 }
1706
1707 // Append additional motion samples.
1708 MotionSample* nextMotionSample = firstMotionSample->next;
1709 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1710 status = connection->inputPublisher.appendMotionSample(
1711 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1712 if (status == NO_MEMORY) {
1713#if DEBUG_DISPATCH_CYCLE
1714 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1715 "be sent in the next dispatch cycle.",
1716 connection->getInputChannelName());
1717#endif
1718 break;
1719 }
1720 if (status != OK) {
1721 LOGE("channel '%s' ~ Could not append motion sample "
1722 "for a reason other than out of memory, status=%d",
1723 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001724 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001725 return;
1726 }
1727 }
1728
1729 // Remember the next motion sample that we could not dispatch, in case we ran out
1730 // of space in the shared memory buffer.
1731 dispatchEntry->tailMotionSample = nextMotionSample;
1732 break;
1733 }
1734
1735 default: {
1736 assert(false);
1737 }
1738 }
1739
1740 // Send the dispatch signal.
1741 status = connection->inputPublisher.sendDispatchSignal();
1742 if (status) {
1743 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1744 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001745 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001746 return;
1747 }
1748
1749 // Record information about the newly started dispatch cycle.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001750 connection->lastEventTime = eventEntry->eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07001751 connection->lastDispatchTime = currentTime;
1752
Jeff Browne839a582010-04-22 18:58:52 -07001753 // Notify other system components.
1754 onDispatchCycleStartedLocked(currentTime, connection);
1755}
1756
Jeff Brown51d45a72010-06-17 20:52:56 -07001757void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1758 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001759#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001760 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -07001761 "%01.1fms since dispatch",
1762 connection->getInputChannelName(),
1763 connection->getEventLatencyMillis(currentTime),
1764 connection->getDispatchLatencyMillis(currentTime));
1765#endif
1766
Jeff Brown54bc2812010-06-15 01:31:58 -07001767 if (connection->status == Connection::STATUS_BROKEN
1768 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001769 return;
1770 }
1771
Jeff Brown53a415e2010-09-15 15:18:56 -07001772 // Notify other system components.
1773 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001774
1775 // Reset the publisher since the event has been consumed.
1776 // We do this now so that the publisher can release some of its internal resources
1777 // while waiting for the next dispatch cycle to begin.
1778 status_t status = connection->inputPublisher.reset();
1779 if (status) {
1780 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1781 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001782 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001783 return;
1784 }
1785
Jeff Browna665ca82010-09-08 11:49:43 -07001786 startNextDispatchCycleLocked(currentTime, connection);
1787}
1788
1789void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1790 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001791 // Start the next dispatch cycle for this connection.
1792 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001793 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001794 if (dispatchEntry->inProgress) {
1795 // Finish or resume current event in progress.
1796 if (dispatchEntry->tailMotionSample) {
1797 // We have a tail of undispatched motion samples.
1798 // Reuse the same DispatchEntry and start a new cycle.
1799 dispatchEntry->inProgress = false;
1800 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1801 dispatchEntry->tailMotionSample = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07001802 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001803 return;
1804 }
1805 // Finished.
1806 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001807 if (dispatchEntry->hasForegroundTarget()) {
1808 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001809 }
Jeff Browne839a582010-04-22 18:58:52 -07001810 mAllocator.releaseDispatchEntry(dispatchEntry);
1811 } else {
1812 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown53a415e2010-09-15 15:18:56 -07001813 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001814 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001815 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001816 return;
1817 }
1818 }
1819
1820 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001821 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001822}
1823
Jeff Brown90f0cee2010-10-08 22:31:17 -07001824void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1825 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001826#if DEBUG_DISPATCH_CYCLE
Jeff Brown90f0cee2010-10-08 22:31:17 -07001827 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001828 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001829#endif
1830
Jeff Browna665ca82010-09-08 11:49:43 -07001831 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001832 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001833
Jeff Brown90f0cee2010-10-08 22:31:17 -07001834 // The connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001835 // Ignore already broken or zombie connections.
Jeff Brown90f0cee2010-10-08 22:31:17 -07001836 if (connection->status == Connection::STATUS_NORMAL) {
1837 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001838
Jeff Brown90f0cee2010-10-08 22:31:17 -07001839 // Notify other system components.
1840 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001841 }
Jeff Browne839a582010-04-22 18:58:52 -07001842}
1843
Jeff Brown53a415e2010-09-15 15:18:56 -07001844void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1845 while (! connection->outboundQueue.isEmpty()) {
1846 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1847 if (dispatchEntry->hasForegroundTarget()) {
1848 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001849 }
1850 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001851 }
1852
Jeff Brown53a415e2010-09-15 15:18:56 -07001853 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001854}
1855
Jeff Brown59abe7e2010-09-13 23:17:30 -07001856int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-04-22 18:58:52 -07001857 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1858
1859 { // acquire lock
1860 AutoMutex _l(d->mLock);
1861
1862 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1863 if (connectionIndex < 0) {
1864 LOGE("Received spurious receive callback for unknown input channel. "
1865 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001866 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001867 }
1868
Jeff Brown51d45a72010-06-17 20:52:56 -07001869 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001870
1871 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001872 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-04-22 18:58:52 -07001873 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1874 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001875 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001876 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001877 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001878 }
1879
Jeff Brown59abe7e2010-09-13 23:17:30 -07001880 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001881 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1882 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001883 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001884 }
1885
1886 status_t status = connection->inputPublisher.receiveFinishedSignal();
1887 if (status) {
1888 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1889 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001890 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001891 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001892 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001893 }
1894
Jeff Brown51d45a72010-06-17 20:52:56 -07001895 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001896 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001897 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001898 } // release lock
1899}
1900
Jeff Brown90f0cee2010-10-08 22:31:17 -07001901void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1902 InputState::CancelationOptions options, const char* reason) {
1903 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1904 synthesizeCancelationEventsForConnectionLocked(
1905 mConnectionsByReceiveFd.valueAt(i), options, reason);
1906 }
1907}
1908
1909void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1910 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1911 const char* reason) {
1912 ssize_t index = getConnectionIndexLocked(channel);
1913 if (index >= 0) {
1914 synthesizeCancelationEventsForConnectionLocked(
1915 mConnectionsByReceiveFd.valueAt(index), options, reason);
1916 }
1917}
1918
1919void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1920 const sp<Connection>& connection, InputState::CancelationOptions options,
1921 const char* reason) {
1922 nsecs_t currentTime = now();
1923
1924 mTempCancelationEvents.clear();
1925 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1926 mTempCancelationEvents, options);
1927
1928 if (! mTempCancelationEvents.isEmpty()
1929 && connection->status != Connection::STATUS_BROKEN) {
1930#if DEBUG_OUTBOUND_EVENT_DETAILS
1931 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1932 "with reality: %s, options=%d.",
1933 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1934#endif
1935 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1936 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1937 switch (cancelationEventEntry->type) {
1938 case EventEntry::TYPE_KEY:
1939 logOutboundKeyDetailsLocked("cancel - ",
1940 static_cast<KeyEntry*>(cancelationEventEntry));
1941 break;
1942 case EventEntry::TYPE_MOTION:
1943 logOutboundMotionDetailsLocked("cancel - ",
1944 static_cast<MotionEntry*>(cancelationEventEntry));
1945 break;
1946 }
1947
1948 int32_t xOffset, yOffset;
1949 const InputWindow* window = getWindowLocked(connection->inputChannel);
1950 if (window) {
1951 xOffset = -window->frameLeft;
1952 yOffset = -window->frameTop;
1953 } else {
1954 xOffset = 0;
1955 yOffset = 0;
1956 }
1957
1958 DispatchEntry* cancelationDispatchEntry =
1959 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1960 0, xOffset, yOffset);
1961 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1962
1963 mAllocator.releaseEventEntry(cancelationEventEntry);
1964 }
1965
1966 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1967 startDispatchCycleLocked(currentTime, connection);
1968 }
1969 }
1970}
1971
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001972InputDispatcher::MotionEntry*
1973InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1974 assert(pointerIds.value != 0);
1975
1976 uint32_t splitPointerIndexMap[MAX_POINTERS];
1977 int32_t splitPointerIds[MAX_POINTERS];
1978 PointerCoords splitPointerCoords[MAX_POINTERS];
1979
1980 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1981 uint32_t splitPointerCount = 0;
1982
1983 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1984 originalPointerIndex++) {
1985 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1986 if (pointerIds.hasBit(pointerId)) {
1987 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1988 splitPointerIds[splitPointerCount] = pointerId;
1989 splitPointerCoords[splitPointerCount] =
1990 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1991 splitPointerCount += 1;
1992 }
1993 }
1994 assert(splitPointerCount == pointerIds.count());
1995
1996 int32_t action = originalMotionEntry->action;
1997 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1998 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
1999 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2000 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2001 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2002 if (pointerIds.hasBit(pointerId)) {
2003 if (pointerIds.count() == 1) {
2004 // The first/last pointer went down/up.
2005 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2006 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brownffb16d62010-09-27 16:35:11 -07002007 } else {
2008 // A secondary pointer went down/up.
2009 uint32_t splitPointerIndex = 0;
2010 while (pointerId != splitPointerIds[splitPointerIndex]) {
2011 splitPointerIndex += 1;
2012 }
2013 action = maskedAction | (splitPointerIndex
2014 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002015 }
2016 } else {
2017 // An unrelated pointer changed.
2018 action = AMOTION_EVENT_ACTION_MOVE;
2019 }
2020 }
2021
2022 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2023 originalMotionEntry->eventTime,
2024 originalMotionEntry->deviceId,
2025 originalMotionEntry->source,
2026 originalMotionEntry->policyFlags,
2027 action,
2028 originalMotionEntry->flags,
2029 originalMotionEntry->metaState,
2030 originalMotionEntry->edgeFlags,
2031 originalMotionEntry->xPrecision,
2032 originalMotionEntry->yPrecision,
2033 originalMotionEntry->downTime,
2034 splitPointerCount, splitPointerIds, splitPointerCoords);
2035
2036 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2037 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2038 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2039 splitPointerIndex++) {
2040 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2041 splitPointerCoords[splitPointerIndex] =
2042 originalMotionSample->pointerCoords[originalPointerIndex];
2043 }
2044
2045 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2046 splitPointerCoords);
2047 }
2048
2049 return splitMotionEntry;
2050}
2051
Jeff Brown54bc2812010-06-15 01:31:58 -07002052void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002053#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -07002054 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07002055#endif
2056
Jeff Browna665ca82010-09-08 11:49:43 -07002057 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002058 { // acquire lock
2059 AutoMutex _l(mLock);
2060
Jeff Brown51d45a72010-06-17 20:52:56 -07002061 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browna665ca82010-09-08 11:49:43 -07002062 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002063 } // release lock
2064
Jeff Browna665ca82010-09-08 11:49:43 -07002065 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002066 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002067 }
2068}
2069
Jeff Brown5c1ed842010-07-14 18:48:53 -07002070void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -07002071 uint32_t policyFlags, int32_t action, int32_t flags,
2072 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2073#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002074 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07002075 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07002076 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -07002077 keyCode, scanCode, metaState, downTime);
2078#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002079 if (! validateKeyEvent(action)) {
2080 return;
2081 }
Jeff Browne839a582010-04-22 18:58:52 -07002082
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002083 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002084 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2085 keyCode, scanCode, /*byref*/ policyFlags);
2086
Jeff Browna665ca82010-09-08 11:49:43 -07002087 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002088 { // acquire lock
2089 AutoMutex _l(mLock);
2090
Jeff Brown51d45a72010-06-17 20:52:56 -07002091 int32_t repeatCount = 0;
2092 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002093 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07002094 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07002095
Jeff Browna665ca82010-09-08 11:49:43 -07002096 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002097 } // release lock
2098
Jeff Browna665ca82010-09-08 11:49:43 -07002099 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002100 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002101 }
2102}
2103
Jeff Brown5c1ed842010-07-14 18:48:53 -07002104void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002105 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002106 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2107 float xPrecision, float yPrecision, nsecs_t downTime) {
2108#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002109 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002110 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2111 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2112 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002113 xPrecision, yPrecision, downTime);
2114 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07002115 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002116 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07002117 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07002118 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-08-30 03:02:23 -07002119 pointerCoords[i].pressure, pointerCoords[i].size,
2120 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2121 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2122 pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -07002123 }
2124#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002125 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2126 return;
2127 }
Jeff Browne839a582010-04-22 18:58:52 -07002128
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002129 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002130 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2131
Jeff Browna665ca82010-09-08 11:49:43 -07002132 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002133 { // acquire lock
2134 AutoMutex _l(mLock);
2135
2136 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07002137 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07002138 // BATCHING CASE
2139 //
2140 // Try to append a move sample to the tail of the inbound queue for this device.
2141 // Give up if we encounter a non-move motion event for this device since that
2142 // means we cannot append any new samples until a new motion event has started.
Jeff Browna665ca82010-09-08 11:49:43 -07002143 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2144 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07002145 if (entry->type != EventEntry::TYPE_MOTION) {
2146 // Keep looking for motion events.
2147 continue;
2148 }
2149
2150 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2151 if (motionEntry->deviceId != deviceId) {
2152 // Keep looking for this device.
2153 continue;
2154 }
2155
Jeff Brown5c1ed842010-07-14 18:48:53 -07002156 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07002157 || motionEntry->pointerCount != pointerCount
2158 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07002159 // Last motion event in the queue for this device is not compatible for
2160 // appending new samples. Stop here.
2161 goto NoBatchingOrStreaming;
2162 }
2163
2164 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07002165 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07002166 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002167#if DEBUG_BATCHING
2168 LOGD("Appended motion sample onto batch for most recent "
2169 "motion event for this device in the inbound queue.");
2170#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07002171 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002172 }
2173
2174 // STREAMING CASE
2175 //
2176 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07002177 // Search the outbound queue for the current foreground targets to find a dispatched
2178 // motion event that is still in progress. If found, then, appen the new sample to
2179 // that event and push it out to all current targets. The logic in
2180 // prepareDispatchCycleLocked takes care of the case where some targets may
2181 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown54bc2812010-06-15 01:31:58 -07002182 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002183 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2184 const InputTarget& inputTarget = mCurrentInputTargets[i];
2185 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2186 // Skip non-foreground targets. We only want to stream if there is at
2187 // least one foreground target whose dispatch is still in progress.
2188 continue;
Jeff Browne839a582010-04-22 18:58:52 -07002189 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002190
2191 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2192 if (connectionIndex < 0) {
2193 // Connection must no longer be valid.
2194 continue;
2195 }
2196
2197 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2198 if (connection->outboundQueue.isEmpty()) {
2199 // This foreground target has an empty outbound queue.
2200 continue;
2201 }
2202
2203 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2204 if (! dispatchEntry->inProgress
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002205 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2206 || dispatchEntry->isSplit()) {
2207 // No motion event is being dispatched, or it is being split across
2208 // windows in which case we cannot stream.
Jeff Brown53a415e2010-09-15 15:18:56 -07002209 continue;
2210 }
2211
2212 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2213 dispatchEntry->eventEntry);
2214 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2215 || motionEntry->deviceId != deviceId
2216 || motionEntry->pointerCount != pointerCount
2217 || motionEntry->isInjected()) {
2218 // The motion event is not compatible with this move.
2219 continue;
2220 }
2221
2222 // Hurray! This foreground target is currently dispatching a move event
2223 // that we can stream onto. Append the motion sample and resume dispatch.
2224 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2225#if DEBUG_BATCHING
2226 LOGD("Appended motion sample onto batch for most recently dispatched "
2227 "motion event for this device in the outbound queues. "
2228 "Attempting to stream the motion sample.");
2229#endif
2230 nsecs_t currentTime = now();
2231 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2232 true /*resumeWithAppendedMotionSample*/);
2233
2234 runCommandsLockedInterruptible();
2235 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002236 }
2237 }
2238
2239NoBatchingOrStreaming:;
2240 }
2241
2242 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07002243 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002244 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002245 xPrecision, yPrecision, downTime,
2246 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002247
Jeff Browna665ca82010-09-08 11:49:43 -07002248 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002249 } // release lock
2250
Jeff Browna665ca82010-09-08 11:49:43 -07002251 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002252 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002253 }
2254}
2255
Jeff Brown90f0cee2010-10-08 22:31:17 -07002256void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2257 uint32_t policyFlags) {
2258#if DEBUG_INBOUND_EVENT_DETAILS
2259 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2260 switchCode, switchValue, policyFlags);
2261#endif
2262
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002263 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002264 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2265}
2266
Jeff Brown51d45a72010-06-17 20:52:56 -07002267int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07002268 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002269#if DEBUG_INBOUND_EVENT_DETAILS
2270 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002271 "syncMode=%d, timeoutMillis=%d",
2272 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07002273#endif
2274
2275 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002276
2277 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2278 if (hasInjectionPermission(injectorPid, injectorUid)) {
2279 policyFlags |= POLICY_FLAG_TRUSTED;
2280 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002281
Jeff Brown90f0cee2010-10-08 22:31:17 -07002282 EventEntry* injectedEntry;
2283 switch (event->getType()) {
2284 case AINPUT_EVENT_TYPE_KEY: {
2285 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2286 int32_t action = keyEvent->getAction();
2287 if (! validateKeyEvent(action)) {
Jeff Browna665ca82010-09-08 11:49:43 -07002288 return INPUT_EVENT_INJECTION_FAILED;
2289 }
2290
Jeff Brown90f0cee2010-10-08 22:31:17 -07002291 nsecs_t eventTime = keyEvent->getEventTime();
2292 int32_t deviceId = keyEvent->getDeviceId();
2293 int32_t flags = keyEvent->getFlags();
2294 int32_t keyCode = keyEvent->getKeyCode();
2295 int32_t scanCode = keyEvent->getScanCode();
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002296 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2297 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002298
Jeff Brown90f0cee2010-10-08 22:31:17 -07002299 mLock.lock();
2300 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2301 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2302 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2303 break;
2304 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002305
Jeff Brown90f0cee2010-10-08 22:31:17 -07002306 case AINPUT_EVENT_TYPE_MOTION: {
2307 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2308 int32_t action = motionEvent->getAction();
2309 size_t pointerCount = motionEvent->getPointerCount();
2310 const int32_t* pointerIds = motionEvent->getPointerIds();
2311 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2312 return INPUT_EVENT_INJECTION_FAILED;
2313 }
2314
2315 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002316 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002317
2318 mLock.lock();
2319 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2320 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2321 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2322 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2323 action, motionEvent->getFlags(),
2324 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2325 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2326 motionEvent->getDownTime(), uint32_t(pointerCount),
2327 pointerIds, samplePointerCoords);
2328 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2329 sampleEventTimes += 1;
2330 samplePointerCoords += pointerCount;
2331 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2332 }
2333 injectedEntry = motionEntry;
2334 break;
2335 }
2336
2337 default:
2338 LOGW("Cannot inject event of type %d", event->getType());
2339 return INPUT_EVENT_INJECTION_FAILED;
2340 }
2341
2342 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2343 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2344 injectionState->injectionIsAsync = true;
2345 }
2346
2347 injectionState->refCount += 1;
2348 injectedEntry->injectionState = injectionState;
2349
2350 bool needWake = enqueueInboundEventLocked(injectedEntry);
2351 mLock.unlock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002352
Jeff Browna665ca82010-09-08 11:49:43 -07002353 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002354 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07002355 }
2356
2357 int32_t injectionResult;
2358 { // acquire lock
2359 AutoMutex _l(mLock);
2360
Jeff Brownf67c53e2010-07-28 15:48:59 -07002361 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2362 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2363 } else {
2364 for (;;) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002365 injectionResult = injectionState->injectionResult;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002366 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2367 break;
2368 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002369
Jeff Brown51d45a72010-06-17 20:52:56 -07002370 nsecs_t remainingTimeout = endTime - now();
2371 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002372#if DEBUG_INJECTION
2373 LOGD("injectInputEvent - Timed out waiting for injection result "
2374 "to become available.");
2375#endif
Jeff Brown51d45a72010-06-17 20:52:56 -07002376 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2377 break;
2378 }
2379
Jeff Brownf67c53e2010-07-28 15:48:59 -07002380 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2381 }
2382
2383 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2384 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002385 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002386#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002387 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002388 injectionState->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002389#endif
2390 nsecs_t remainingTimeout = endTime - now();
2391 if (remainingTimeout <= 0) {
2392#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002393 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002394 "dispatches to finish.");
2395#endif
2396 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2397 break;
2398 }
2399
2400 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2401 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002402 }
2403 }
2404
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002405 mAllocator.releaseInjectionState(injectionState);
Jeff Brown51d45a72010-06-17 20:52:56 -07002406 } // release lock
2407
Jeff Brownf67c53e2010-07-28 15:48:59 -07002408#if DEBUG_INJECTION
2409 LOGD("injectInputEvent - Finished with result %d. "
2410 "injectorPid=%d, injectorUid=%d",
2411 injectionResult, injectorPid, injectorUid);
2412#endif
2413
Jeff Brown51d45a72010-06-17 20:52:56 -07002414 return injectionResult;
2415}
2416
Jeff Brown90f0cee2010-10-08 22:31:17 -07002417bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2418 return injectorUid == 0
2419 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2420}
2421
Jeff Brown51d45a72010-06-17 20:52:56 -07002422void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002423 InjectionState* injectionState = entry->injectionState;
2424 if (injectionState) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002425#if DEBUG_INJECTION
2426 LOGD("Setting input event injection result to %d. "
2427 "injectorPid=%d, injectorUid=%d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002428 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002429#endif
2430
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002431 if (injectionState->injectionIsAsync) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002432 // Log the outcome since the injector did not wait for the injection result.
2433 switch (injectionResult) {
2434 case INPUT_EVENT_INJECTION_SUCCEEDED:
2435 LOGV("Asynchronous input event injection succeeded.");
2436 break;
2437 case INPUT_EVENT_INJECTION_FAILED:
2438 LOGW("Asynchronous input event injection failed.");
2439 break;
2440 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2441 LOGW("Asynchronous input event injection permission denied.");
2442 break;
2443 case INPUT_EVENT_INJECTION_TIMED_OUT:
2444 LOGW("Asynchronous input event injection timed out.");
2445 break;
2446 }
2447 }
2448
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002449 injectionState->injectionResult = injectionResult;
Jeff Brown51d45a72010-06-17 20:52:56 -07002450 mInjectionResultAvailableCondition.broadcast();
2451 }
2452}
2453
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002454void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2455 InjectionState* injectionState = entry->injectionState;
2456 if (injectionState) {
2457 injectionState->pendingForegroundDispatches += 1;
2458 }
2459}
2460
Jeff Brown53a415e2010-09-15 15:18:56 -07002461void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002462 InjectionState* injectionState = entry->injectionState;
2463 if (injectionState) {
2464 injectionState->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002465
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002466 if (injectionState->pendingForegroundDispatches == 0) {
2467 mInjectionSyncFinishedCondition.broadcast();
2468 }
Jeff Browna665ca82010-09-08 11:49:43 -07002469 }
2470}
2471
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002472const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2473 for (size_t i = 0; i < mWindows.size(); i++) {
2474 const InputWindow* window = & mWindows[i];
2475 if (window->inputChannel == inputChannel) {
2476 return window;
2477 }
2478 }
2479 return NULL;
2480}
2481
Jeff Browna665ca82010-09-08 11:49:43 -07002482void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2483#if DEBUG_FOCUS
2484 LOGD("setInputWindows");
2485#endif
2486 { // acquire lock
2487 AutoMutex _l(mLock);
2488
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002489 // Clear old window pointers.
Jeff Brown90f0cee2010-10-08 22:31:17 -07002490 sp<InputChannel> oldFocusedWindowChannel;
2491 if (mFocusedWindow) {
2492 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2493 mFocusedWindow = NULL;
2494 }
2495
Jeff Browna665ca82010-09-08 11:49:43 -07002496 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002497
2498 // Loop over new windows and rebuild the necessary window pointers for
2499 // tracking focus and touch.
Jeff Browna665ca82010-09-08 11:49:43 -07002500 mWindows.appendVector(inputWindows);
2501
2502 size_t numWindows = mWindows.size();
2503 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002504 const InputWindow* window = & mWindows.itemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07002505 if (window->hasFocus) {
2506 mFocusedWindow = window;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002507 break;
Jeff Browna665ca82010-09-08 11:49:43 -07002508 }
2509 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002510
Jeff Brown90f0cee2010-10-08 22:31:17 -07002511 if (oldFocusedWindowChannel != NULL) {
2512 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2513#if DEBUG_FOCUS
2514 LOGD("Focus left window: %s",
2515 oldFocusedWindowChannel->getName().string());
2516#endif
2517 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2518 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2519 oldFocusedWindowChannel.clear();
2520 }
2521 }
2522 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2523#if DEBUG_FOCUS
2524 LOGD("Focus entered window: %s",
2525 mFocusedWindow->inputChannel->getName().string());
2526#endif
2527 }
2528
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002529 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2530 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2531 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2532 if (window) {
2533 touchedWindow.window = window;
2534 i += 1;
2535 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -07002536#if DEBUG_FOCUS
2537 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2538#endif
Jeff Brown90f0cee2010-10-08 22:31:17 -07002539 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2540 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownb13d7b52010-10-15 16:20:51 -07002541 mTouchState.windows.removeAt(i);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002542 }
2543 }
Jeff Browna665ca82010-09-08 11:49:43 -07002544
Jeff Browna665ca82010-09-08 11:49:43 -07002545#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002546 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002547#endif
2548 } // release lock
2549
2550 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002551 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002552}
2553
2554void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2555#if DEBUG_FOCUS
2556 LOGD("setFocusedApplication");
2557#endif
2558 { // acquire lock
2559 AutoMutex _l(mLock);
2560
2561 releaseFocusedApplicationLocked();
2562
2563 if (inputApplication) {
2564 mFocusedApplicationStorage = *inputApplication;
2565 mFocusedApplication = & mFocusedApplicationStorage;
2566 }
2567
2568#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002569 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002570#endif
2571 } // release lock
2572
2573 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002574 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002575}
2576
2577void InputDispatcher::releaseFocusedApplicationLocked() {
2578 if (mFocusedApplication) {
2579 mFocusedApplication = NULL;
2580 mFocusedApplicationStorage.handle.clear();
2581 }
2582}
2583
2584void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2585#if DEBUG_FOCUS
2586 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2587#endif
2588
2589 bool changed;
2590 { // acquire lock
2591 AutoMutex _l(mLock);
2592
2593 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2594 if (mDispatchFrozen && ! frozen) {
2595 resetANRTimeoutsLocked();
2596 }
2597
2598 mDispatchEnabled = enabled;
2599 mDispatchFrozen = frozen;
2600 changed = true;
2601 } else {
2602 changed = false;
2603 }
2604
2605#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002606 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002607#endif
2608 } // release lock
2609
2610 if (changed) {
2611 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002612 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002613 }
2614}
2615
Jeff Browna665ca82010-09-08 11:49:43 -07002616void InputDispatcher::logDispatchStateLocked() {
2617 String8 dump;
2618 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002619
2620 char* text = dump.lockBuffer(dump.size());
2621 char* start = text;
2622 while (*start != '\0') {
2623 char* end = strchr(start, '\n');
2624 if (*end == '\n') {
2625 *(end++) = '\0';
2626 }
2627 LOGD("%s", start);
2628 start = end;
2629 }
Jeff Browna665ca82010-09-08 11:49:43 -07002630}
2631
2632void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002633 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2634 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002635
2636 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002637 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002638 mFocusedApplication->name.string(),
2639 mFocusedApplication->dispatchingTimeout / 1000000.0);
2640 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002641 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002642 }
Jeff Brown2806e382010-10-01 17:46:21 -07002643 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002644 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-10-01 17:46:21 -07002645
2646 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2647 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2648 if (!mTouchState.windows.isEmpty()) {
2649 dump.append(INDENT "TouchedWindows:\n");
2650 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2651 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2652 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2653 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2654 touchedWindow.targetFlags);
2655 }
2656 } else {
2657 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002658 }
2659
Jeff Brown2806e382010-10-01 17:46:21 -07002660 if (!mWindows.isEmpty()) {
2661 dump.append(INDENT "Windows:\n");
2662 for (size_t i = 0; i < mWindows.size(); i++) {
2663 const InputWindow& window = mWindows[i];
2664 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2665 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2666 "frame=[%d,%d][%d,%d], "
2667 "visibleFrame=[%d,%d][%d,%d], "
2668 "touchableArea=[%d,%d][%d,%d], "
2669 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2670 i, window.name.string(),
2671 toString(window.paused),
2672 toString(window.hasFocus),
2673 toString(window.hasWallpaper),
2674 toString(window.visible),
2675 toString(window.canReceiveKeys),
2676 window.layoutParamsFlags, window.layoutParamsType,
2677 window.layer,
2678 window.frameLeft, window.frameTop,
2679 window.frameRight, window.frameBottom,
2680 window.visibleFrameLeft, window.visibleFrameTop,
2681 window.visibleFrameRight, window.visibleFrameBottom,
2682 window.touchableAreaLeft, window.touchableAreaTop,
2683 window.touchableAreaRight, window.touchableAreaBottom,
2684 window.ownerPid, window.ownerUid,
2685 window.dispatchingTimeout / 1000000.0);
2686 }
2687 } else {
2688 dump.append(INDENT "Windows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002689 }
2690
Jeff Brown2806e382010-10-01 17:46:21 -07002691 if (!mMonitoringChannels.isEmpty()) {
2692 dump.append(INDENT "MonitoringChannels:\n");
2693 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2694 const sp<InputChannel>& channel = mMonitoringChannels[i];
2695 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2696 }
2697 } else {
2698 dump.append(INDENT "MonitoringChannels: <none>\n");
2699 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002700
Jeff Brown2806e382010-10-01 17:46:21 -07002701 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2702
2703 if (!mActiveConnections.isEmpty()) {
2704 dump.append(INDENT "ActiveConnections:\n");
2705 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2706 const Connection* connection = mActiveConnections[i];
2707 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
Jeff Brown90f0cee2010-10-08 22:31:17 -07002708 "inputState.isNeutral=%s\n",
Jeff Brown2806e382010-10-01 17:46:21 -07002709 i, connection->getInputChannelName(), connection->getStatusLabel(),
2710 connection->outboundQueue.count(),
Jeff Brown90f0cee2010-10-08 22:31:17 -07002711 toString(connection->inputState.isNeutral()));
Jeff Brown2806e382010-10-01 17:46:21 -07002712 }
2713 } else {
2714 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002715 }
2716
2717 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002718 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002719 (mAppSwitchDueTime - now()) / 1000000.0);
2720 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002721 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002722 }
2723}
2724
2725status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002726#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002727 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2728 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002729#endif
2730
Jeff Browne839a582010-04-22 18:58:52 -07002731 { // acquire lock
2732 AutoMutex _l(mLock);
2733
Jeff Brown53a415e2010-09-15 15:18:56 -07002734 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002735 LOGW("Attempted to register already registered input channel '%s'",
2736 inputChannel->getName().string());
2737 return BAD_VALUE;
2738 }
2739
2740 sp<Connection> connection = new Connection(inputChannel);
2741 status_t status = connection->initialize();
2742 if (status) {
2743 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2744 inputChannel->getName().string(), status);
2745 return status;
2746 }
2747
Jeff Brown0cacb872010-08-17 15:59:26 -07002748 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002749 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002750
Jeff Browna665ca82010-09-08 11:49:43 -07002751 if (monitor) {
2752 mMonitoringChannels.push(inputChannel);
2753 }
2754
Jeff Brown59abe7e2010-09-13 23:17:30 -07002755 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002756
Jeff Brown54bc2812010-06-15 01:31:58 -07002757 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002758 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002759 return OK;
2760}
2761
2762status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002763#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002764 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002765#endif
2766
Jeff Browne839a582010-04-22 18:58:52 -07002767 { // acquire lock
2768 AutoMutex _l(mLock);
2769
Jeff Brown53a415e2010-09-15 15:18:56 -07002770 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002771 if (connectionIndex < 0) {
2772 LOGW("Attempted to unregister already unregistered input channel '%s'",
2773 inputChannel->getName().string());
2774 return BAD_VALUE;
2775 }
2776
2777 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2778 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2779
2780 connection->status = Connection::STATUS_ZOMBIE;
2781
Jeff Browna665ca82010-09-08 11:49:43 -07002782 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2783 if (mMonitoringChannels[i] == inputChannel) {
2784 mMonitoringChannels.removeAt(i);
2785 break;
2786 }
2787 }
2788
Jeff Brown59abe7e2010-09-13 23:17:30 -07002789 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002790
Jeff Brown51d45a72010-06-17 20:52:56 -07002791 nsecs_t currentTime = now();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002792 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002793
2794 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002795 } // release lock
2796
Jeff Browne839a582010-04-22 18:58:52 -07002797 // Wake the poll loop because removing the connection may have changed the current
2798 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002799 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002800 return OK;
2801}
2802
Jeff Brown53a415e2010-09-15 15:18:56 -07002803ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002804 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2805 if (connectionIndex >= 0) {
2806 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2807 if (connection->inputChannel.get() == inputChannel.get()) {
2808 return connectionIndex;
2809 }
2810 }
2811
2812 return -1;
2813}
2814
Jeff Browne839a582010-04-22 18:58:52 -07002815void InputDispatcher::activateConnectionLocked(Connection* connection) {
2816 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2817 if (mActiveConnections.itemAt(i) == connection) {
2818 return;
2819 }
2820 }
2821 mActiveConnections.add(connection);
2822}
2823
2824void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2825 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2826 if (mActiveConnections.itemAt(i) == connection) {
2827 mActiveConnections.removeAt(i);
2828 return;
2829 }
2830 }
2831}
2832
Jeff Brown54bc2812010-06-15 01:31:58 -07002833void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002834 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002835}
2836
Jeff Brown54bc2812010-06-15 01:31:58 -07002837void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002838 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002839}
2840
Jeff Brown54bc2812010-06-15 01:31:58 -07002841void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002842 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002843 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2844 connection->getInputChannelName());
2845
Jeff Brown54bc2812010-06-15 01:31:58 -07002846 CommandEntry* commandEntry = postCommandLocked(
2847 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002848 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002849}
2850
Jeff Brown53a415e2010-09-15 15:18:56 -07002851void InputDispatcher::onANRLocked(
2852 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2853 nsecs_t eventTime, nsecs_t waitStartTime) {
2854 LOGI("Application is not responding: %s. "
2855 "%01.1fms since event, %01.1fms since wait started",
2856 getApplicationWindowLabelLocked(application, window).string(),
2857 (currentTime - eventTime) / 1000000.0,
2858 (currentTime - waitStartTime) / 1000000.0);
2859
2860 CommandEntry* commandEntry = postCommandLocked(
2861 & InputDispatcher::doNotifyANRLockedInterruptible);
2862 if (application) {
2863 commandEntry->inputApplicationHandle = application->handle;
2864 }
2865 if (window) {
2866 commandEntry->inputChannel = window->inputChannel;
2867 }
2868}
2869
Jeff Browna665ca82010-09-08 11:49:43 -07002870void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2871 CommandEntry* commandEntry) {
2872 mLock.unlock();
2873
2874 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2875
2876 mLock.lock();
2877}
2878
Jeff Brown54bc2812010-06-15 01:31:58 -07002879void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2880 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002881 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002882
Jeff Brown51d45a72010-06-17 20:52:56 -07002883 if (connection->status != Connection::STATUS_ZOMBIE) {
2884 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002885
Jeff Brown51d45a72010-06-17 20:52:56 -07002886 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2887
2888 mLock.lock();
2889 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002890}
2891
Jeff Brown53a415e2010-09-15 15:18:56 -07002892void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002893 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002894 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002895
Jeff Brown53a415e2010-09-15 15:18:56 -07002896 nsecs_t newTimeout = mPolicy->notifyANR(
2897 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002898
Jeff Brown53a415e2010-09-15 15:18:56 -07002899 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002900
Jeff Brown53a415e2010-09-15 15:18:56 -07002901 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002902}
2903
Jeff Browna665ca82010-09-08 11:49:43 -07002904void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2905 CommandEntry* commandEntry) {
2906 KeyEntry* entry = commandEntry->keyEntry;
2907 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2908 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2909 entry->downTime, entry->eventTime);
2910
2911 mLock.unlock();
2912
2913 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2914 & mReusableKeyEvent, entry->policyFlags);
2915
2916 mLock.lock();
2917
2918 entry->interceptKeyResult = consumed
2919 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2920 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2921 mAllocator.releaseKeyEntry(entry);
2922}
2923
2924void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2925 mLock.unlock();
2926
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002927 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07002928
2929 mLock.lock();
2930}
2931
Jeff Brown53a415e2010-09-15 15:18:56 -07002932void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
2933 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
2934 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07002935}
2936
2937void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002938 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002939 dumpDispatchStateLocked(dump);
2940}
2941
Jeff Brown54bc2812010-06-15 01:31:58 -07002942
Jeff Brown53a415e2010-09-15 15:18:56 -07002943// --- InputDispatcher::Queue ---
2944
2945template <typename T>
2946uint32_t InputDispatcher::Queue<T>::count() const {
2947 uint32_t result = 0;
2948 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
2949 result += 1;
2950 }
2951 return result;
2952}
2953
2954
Jeff Browne839a582010-04-22 18:58:52 -07002955// --- InputDispatcher::Allocator ---
2956
2957InputDispatcher::Allocator::Allocator() {
2958}
2959
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002960InputDispatcher::InjectionState*
2961InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
2962 InjectionState* injectionState = mInjectionStatePool.alloc();
2963 injectionState->refCount = 1;
2964 injectionState->injectorPid = injectorPid;
2965 injectionState->injectorUid = injectorUid;
2966 injectionState->injectionIsAsync = false;
2967 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
2968 injectionState->pendingForegroundDispatches = 0;
2969 return injectionState;
2970}
2971
Jeff Brown51d45a72010-06-17 20:52:56 -07002972void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brown90f0cee2010-10-08 22:31:17 -07002973 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002974 entry->type = type;
2975 entry->refCount = 1;
2976 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07002977 entry->eventTime = eventTime;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002978 entry->policyFlags = policyFlags;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002979 entry->injectionState = NULL;
2980}
2981
2982void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
2983 if (entry->injectionState) {
2984 releaseInjectionState(entry->injectionState);
2985 entry->injectionState = NULL;
2986 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002987}
2988
Jeff Browne839a582010-04-22 18:58:52 -07002989InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07002990InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002991 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002992 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Browne839a582010-04-22 18:58:52 -07002993 return entry;
2994}
2995
Jeff Brown51d45a72010-06-17 20:52:56 -07002996InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002997 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07002998 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
2999 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003000 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003001 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003002
3003 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003004 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003005 entry->action = action;
3006 entry->flags = flags;
3007 entry->keyCode = keyCode;
3008 entry->scanCode = scanCode;
3009 entry->metaState = metaState;
3010 entry->repeatCount = repeatCount;
3011 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07003012 entry->syntheticRepeat = false;
3013 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07003014 return entry;
3015}
3016
Jeff Brown51d45a72010-06-17 20:52:56 -07003017InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07003018 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07003019 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3020 nsecs_t downTime, uint32_t pointerCount,
3021 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003022 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003023 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003024
3025 entry->eventTime = eventTime;
3026 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003027 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003028 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07003029 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07003030 entry->metaState = metaState;
3031 entry->edgeFlags = edgeFlags;
3032 entry->xPrecision = xPrecision;
3033 entry->yPrecision = yPrecision;
3034 entry->downTime = downTime;
3035 entry->pointerCount = pointerCount;
3036 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07003037 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07003038 entry->lastSample = & entry->firstSample;
3039 for (uint32_t i = 0; i < pointerCount; i++) {
3040 entry->pointerIds[i] = pointerIds[i];
3041 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3042 }
Jeff Browne839a582010-04-22 18:58:52 -07003043 return entry;
3044}
3045
3046InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07003047 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07003048 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07003049 DispatchEntry* entry = mDispatchEntryPool.alloc();
3050 entry->eventEntry = eventEntry;
3051 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07003052 entry->targetFlags = targetFlags;
3053 entry->xOffset = xOffset;
3054 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07003055 entry->inProgress = false;
3056 entry->headMotionSample = NULL;
3057 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07003058 return entry;
3059}
3060
Jeff Brown54bc2812010-06-15 01:31:58 -07003061InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3062 CommandEntry* entry = mCommandEntryPool.alloc();
3063 entry->command = command;
3064 return entry;
3065}
3066
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003067void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3068 injectionState->refCount -= 1;
3069 if (injectionState->refCount == 0) {
3070 mInjectionStatePool.free(injectionState);
3071 } else {
3072 assert(injectionState->refCount > 0);
3073 }
3074}
3075
Jeff Browne839a582010-04-22 18:58:52 -07003076void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3077 switch (entry->type) {
3078 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3079 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3080 break;
3081 case EventEntry::TYPE_KEY:
3082 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3083 break;
3084 case EventEntry::TYPE_MOTION:
3085 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3086 break;
3087 default:
3088 assert(false);
3089 break;
3090 }
3091}
3092
3093void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3094 ConfigurationChangedEntry* entry) {
3095 entry->refCount -= 1;
3096 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003097 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003098 mConfigurationChangeEntryPool.free(entry);
3099 } else {
3100 assert(entry->refCount > 0);
3101 }
3102}
3103
3104void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3105 entry->refCount -= 1;
3106 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003107 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003108 mKeyEntryPool.free(entry);
3109 } else {
3110 assert(entry->refCount > 0);
3111 }
3112}
3113
3114void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3115 entry->refCount -= 1;
3116 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003117 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -07003118 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3119 MotionSample* next = sample->next;
3120 mMotionSamplePool.free(sample);
3121 sample = next;
3122 }
Jeff Browne839a582010-04-22 18:58:52 -07003123 mMotionEntryPool.free(entry);
3124 } else {
3125 assert(entry->refCount > 0);
3126 }
3127}
3128
3129void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3130 releaseEventEntry(entry->eventEntry);
3131 mDispatchEntryPool.free(entry);
3132}
3133
Jeff Brown54bc2812010-06-15 01:31:58 -07003134void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3135 mCommandEntryPool.free(entry);
3136}
3137
Jeff Browne839a582010-04-22 18:58:52 -07003138void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003139 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003140 MotionSample* sample = mMotionSamplePool.alloc();
3141 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003142 uint32_t pointerCount = motionEntry->pointerCount;
3143 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07003144 sample->pointerCoords[i] = pointerCoords[i];
3145 }
3146
3147 sample->next = NULL;
3148 motionEntry->lastSample->next = sample;
3149 motionEntry->lastSample = sample;
3150}
3151
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003152void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3153 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003154
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003155 keyEntry->dispatchInProgress = false;
3156 keyEntry->syntheticRepeat = false;
3157 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003158}
3159
3160
Jeff Brown542412c2010-08-18 15:51:08 -07003161// --- InputDispatcher::MotionEntry ---
3162
3163uint32_t InputDispatcher::MotionEntry::countSamples() const {
3164 uint32_t count = 1;
3165 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3166 count += 1;
3167 }
3168 return count;
3169}
3170
Jeff Browna665ca82010-09-08 11:49:43 -07003171
3172// --- InputDispatcher::InputState ---
3173
Jeff Brown90f0cee2010-10-08 22:31:17 -07003174InputDispatcher::InputState::InputState() {
Jeff Browna665ca82010-09-08 11:49:43 -07003175}
3176
3177InputDispatcher::InputState::~InputState() {
3178}
3179
3180bool InputDispatcher::InputState::isNeutral() const {
3181 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3182}
3183
Jeff Browna665ca82010-09-08 11:49:43 -07003184InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3185 const EventEntry* entry) {
3186 switch (entry->type) {
3187 case EventEntry::TYPE_KEY:
3188 return trackKey(static_cast<const KeyEntry*>(entry));
3189
3190 case EventEntry::TYPE_MOTION:
3191 return trackMotion(static_cast<const MotionEntry*>(entry));
3192
3193 default:
3194 return CONSISTENT;
3195 }
3196}
3197
3198InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3199 const KeyEntry* entry) {
3200 int32_t action = entry->action;
3201 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3202 KeyMemento& memento = mKeyMementos.editItemAt(i);
3203 if (memento.deviceId == entry->deviceId
3204 && memento.source == entry->source
3205 && memento.keyCode == entry->keyCode
3206 && memento.scanCode == entry->scanCode) {
3207 switch (action) {
3208 case AKEY_EVENT_ACTION_UP:
3209 mKeyMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003210 return CONSISTENT;
3211
3212 case AKEY_EVENT_ACTION_DOWN:
3213 return TOLERABLE;
3214
3215 default:
3216 return BROKEN;
3217 }
3218 }
3219 }
3220
3221 switch (action) {
3222 case AKEY_EVENT_ACTION_DOWN: {
3223 mKeyMementos.push();
3224 KeyMemento& memento = mKeyMementos.editTop();
3225 memento.deviceId = entry->deviceId;
3226 memento.source = entry->source;
3227 memento.keyCode = entry->keyCode;
3228 memento.scanCode = entry->scanCode;
3229 memento.downTime = entry->downTime;
3230 return CONSISTENT;
3231 }
3232
3233 default:
3234 return BROKEN;
3235 }
3236}
3237
3238InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3239 const MotionEntry* entry) {
3240 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3241 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3242 MotionMemento& memento = mMotionMementos.editItemAt(i);
3243 if (memento.deviceId == entry->deviceId
3244 && memento.source == entry->source) {
3245 switch (action) {
3246 case AMOTION_EVENT_ACTION_UP:
3247 case AMOTION_EVENT_ACTION_CANCEL:
3248 mMotionMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003249 return CONSISTENT;
3250
3251 case AMOTION_EVENT_ACTION_DOWN:
3252 return TOLERABLE;
3253
3254 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3255 if (entry->pointerCount == memento.pointerCount + 1) {
3256 memento.setPointers(entry);
3257 return CONSISTENT;
3258 }
3259 return BROKEN;
3260
3261 case AMOTION_EVENT_ACTION_POINTER_UP:
3262 if (entry->pointerCount == memento.pointerCount - 1) {
3263 memento.setPointers(entry);
3264 return CONSISTENT;
3265 }
3266 return BROKEN;
3267
3268 case AMOTION_EVENT_ACTION_MOVE:
3269 if (entry->pointerCount == memento.pointerCount) {
3270 return CONSISTENT;
3271 }
3272 return BROKEN;
3273
3274 default:
3275 return BROKEN;
3276 }
3277 }
3278 }
3279
3280 switch (action) {
3281 case AMOTION_EVENT_ACTION_DOWN: {
3282 mMotionMementos.push();
3283 MotionMemento& memento = mMotionMementos.editTop();
3284 memento.deviceId = entry->deviceId;
3285 memento.source = entry->source;
3286 memento.xPrecision = entry->xPrecision;
3287 memento.yPrecision = entry->yPrecision;
3288 memento.downTime = entry->downTime;
3289 memento.setPointers(entry);
3290 return CONSISTENT;
3291 }
3292
3293 default:
3294 return BROKEN;
3295 }
3296}
3297
3298void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3299 pointerCount = entry->pointerCount;
3300 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3301 pointerIds[i] = entry->pointerIds[i];
3302 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3303 }
3304}
3305
Jeff Brown90f0cee2010-10-08 22:31:17 -07003306void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3307 Allocator* allocator, Vector<EventEntry*>& outEvents,
3308 CancelationOptions options) {
3309 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003310 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003311 if (shouldCancelEvent(memento.source, options)) {
3312 outEvents.push(allocator->obtainKeyEntry(currentTime,
3313 memento.deviceId, memento.source, 0,
3314 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3315 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3316 mKeyMementos.removeAt(i);
3317 } else {
3318 i += 1;
3319 }
Jeff Browna665ca82010-09-08 11:49:43 -07003320 }
3321
Jeff Brown316237d2010-10-11 18:22:53 -07003322 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003323 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003324 if (shouldCancelEvent(memento.source, options)) {
3325 outEvents.push(allocator->obtainMotionEntry(currentTime,
3326 memento.deviceId, memento.source, 0,
3327 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3328 memento.xPrecision, memento.yPrecision, memento.downTime,
3329 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3330 mMotionMementos.removeAt(i);
3331 } else {
3332 i += 1;
3333 }
Jeff Browna665ca82010-09-08 11:49:43 -07003334 }
3335}
3336
3337void InputDispatcher::InputState::clear() {
3338 mKeyMementos.clear();
3339 mMotionMementos.clear();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003340}
3341
3342bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3343 CancelationOptions options) {
3344 switch (options) {
3345 case CANCEL_POINTER_EVENTS:
3346 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3347 case CANCEL_NON_POINTER_EVENTS:
3348 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3349 default:
3350 return true;
3351 }
Jeff Browna665ca82010-09-08 11:49:43 -07003352}
3353
3354
Jeff Browne839a582010-04-22 18:58:52 -07003355// --- InputDispatcher::Connection ---
3356
3357InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3358 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003359 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003360}
3361
3362InputDispatcher::Connection::~Connection() {
3363}
3364
3365status_t InputDispatcher::Connection::initialize() {
3366 return inputPublisher.initialize();
3367}
3368
Jeff Brown54bc2812010-06-15 01:31:58 -07003369const char* InputDispatcher::Connection::getStatusLabel() const {
3370 switch (status) {
3371 case STATUS_NORMAL:
3372 return "NORMAL";
3373
3374 case STATUS_BROKEN:
3375 return "BROKEN";
3376
Jeff Brown54bc2812010-06-15 01:31:58 -07003377 case STATUS_ZOMBIE:
3378 return "ZOMBIE";
3379
3380 default:
3381 return "UNKNOWN";
3382 }
3383}
3384
Jeff Browne839a582010-04-22 18:58:52 -07003385InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3386 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003387 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3388 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003389 if (dispatchEntry->eventEntry == eventEntry) {
3390 return dispatchEntry;
3391 }
3392 }
3393 return NULL;
3394}
3395
Jeff Browna665ca82010-09-08 11:49:43 -07003396
Jeff Brown54bc2812010-06-15 01:31:58 -07003397// --- InputDispatcher::CommandEntry ---
3398
Jeff Browna665ca82010-09-08 11:49:43 -07003399InputDispatcher::CommandEntry::CommandEntry() :
3400 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003401}
3402
3403InputDispatcher::CommandEntry::~CommandEntry() {
3404}
3405
Jeff Browne839a582010-04-22 18:58:52 -07003406
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003407// --- InputDispatcher::TouchState ---
3408
3409InputDispatcher::TouchState::TouchState() :
3410 down(false), split(false) {
3411}
3412
3413InputDispatcher::TouchState::~TouchState() {
3414}
3415
3416void InputDispatcher::TouchState::reset() {
3417 down = false;
3418 split = false;
3419 windows.clear();
3420}
3421
3422void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3423 down = other.down;
3424 split = other.split;
3425 windows.clear();
3426 windows.appendVector(other.windows);
3427}
3428
3429void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3430 int32_t targetFlags, BitSet32 pointerIds) {
3431 if (targetFlags & InputTarget::FLAG_SPLIT) {
3432 split = true;
3433 }
3434
3435 for (size_t i = 0; i < windows.size(); i++) {
3436 TouchedWindow& touchedWindow = windows.editItemAt(i);
3437 if (touchedWindow.window == window) {
3438 touchedWindow.targetFlags |= targetFlags;
3439 touchedWindow.pointerIds.value |= pointerIds.value;
3440 return;
3441 }
3442 }
3443
3444 windows.push();
3445
3446 TouchedWindow& touchedWindow = windows.editTop();
3447 touchedWindow.window = window;
3448 touchedWindow.targetFlags = targetFlags;
3449 touchedWindow.pointerIds = pointerIds;
3450 touchedWindow.channel = window->inputChannel;
3451}
3452
3453void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3454 for (size_t i = 0 ; i < windows.size(); ) {
3455 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3456 windows.removeAt(i);
3457 } else {
3458 i += 1;
3459 }
3460 }
3461}
3462
3463const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3464 for (size_t i = 0; i < windows.size(); i++) {
3465 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3466 return windows[i].window;
3467 }
3468 }
3469 return NULL;
3470}
3471
3472
Jeff Browne839a582010-04-22 18:58:52 -07003473// --- InputDispatcherThread ---
3474
3475InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3476 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3477}
3478
3479InputDispatcherThread::~InputDispatcherThread() {
3480}
3481
3482bool InputDispatcherThread::threadLoop() {
3483 mDispatcher->dispatchOnce();
3484 return true;
3485}
3486
3487} // namespace android