blob: 52e488a87337e4240aad17074856fafc633f527a [file] [log] [blame]
Jeff Brown46b9ac02010-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 Brown349703e2010-06-22 01:27:15 -070011#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070012
13// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070014#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070015
16// Log debug messages about batching.
Jeff Brown349703e2010-06-22 01:27:15 -070017#define DEBUG_BATCHING 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070018
19// Log debug messages about the dispatch cycle.
Jeff Brown349703e2010-06-22 01:27:15 -070020#define DEBUG_DISPATCH_CYCLE 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070021
Jeff Brown9c3cda02010-06-15 01:31:58 -070022// Log debug messages about registrations.
Jeff Brown349703e2010-06-22 01:27:15 -070023#define DEBUG_REGISTRATION 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070024
Jeff Brown46b9ac02010-04-22 18:58:52 -070025// Log debug messages about performance statistics.
Jeff Brown349703e2010-06-22 01:27:15 -070026#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070027
Jeff Brown7fbdc842010-06-17 20:52:56 -070028// Log debug messages about input event injection.
Jeff Brown349703e2010-06-22 01:27:15 -070029#define DEBUG_INJECTION 0
Jeff Brown7fbdc842010-06-17 20:52:56 -070030
Jeff Brownae9fc032010-08-18 15:51:08 -070031// Log debug messages about input event throttling.
32#define DEBUG_THROTTLING 0
33
Jeff Brownb88102f2010-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 Brown46b9ac02010-04-22 18:58:52 -070040#include <cutils/log.h>
41#include <ui/InputDispatcher.h>
Jeff Brownb88102f2010-09-08 11:49:43 -070042#include <ui/PowerManager.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070043
44#include <stddef.h>
45#include <unistd.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070046#include <errno.h>
47#include <limits.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070048
Jeff Brownf2f48712010-10-01 17:46:21 -070049#define INDENT " "
50#define INDENT2 " "
51
Jeff Brown46b9ac02010-04-22 18:58:52 -070052namespace android {
53
Jeff Brownb88102f2010-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 Brown46b9ac02010-04-22 18:58:52 -070066
Jeff Brown7fbdc842010-06-17 20:52:56 -070067static inline nsecs_t now() {
68 return systemTime(SYSTEM_TIME_MONOTONIC);
69}
70
Jeff Brownb88102f2010-09-08 11:49:43 -070071static inline const char* toString(bool value) {
72 return value ? "true" : "false";
73}
74
Jeff Brown01ce2e92010-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 Brownb6997262010-10-08 22:31:17 -070098static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brown01ce2e92010-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 Brown01ce2e92010-09-26 22:20:12 -0700104 case AMOTION_EVENT_ACTION_OUTSIDE:
105 return true;
Jeff Brownb6997262010-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 Brown01ce2e92010-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 Brownb6997262010-10-08 22:31:17 -0700118 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brown01ce2e92010-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 Brownb88102f2010-09-08 11:49:43 -0700137
138// --- InputWindow ---
139
Jeff Brownb88102f2010-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 Brown19dfc832010-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
152 || layoutParamsType == TYPE_INPUT_METHOD_DIALOG;
153}
154
Jeff Brownb88102f2010-09-08 11:49:43 -0700155
Jeff Brown46b9ac02010-04-22 18:58:52 -0700156// --- InputDispatcher ---
157
Jeff Brown9c3cda02010-06-15 01:31:58 -0700158InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Brownb88102f2010-09-08 11:49:43 -0700159 mPolicy(policy),
160 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
161 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brown01ce2e92010-09-26 22:20:12 -0700162 mFocusedWindow(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700163 mFocusedApplication(NULL),
164 mCurrentInputTargetsValid(false),
165 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700166 mLooper = new Looper(false);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700167
Jeff Brownb88102f2010-09-08 11:49:43 -0700168 mInboundQueue.headSentinel.refCount = -1;
169 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
170 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700171
Jeff Brownb88102f2010-09-08 11:49:43 -0700172 mInboundQueue.tailSentinel.refCount = -1;
173 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
174 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700175
176 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700177
Jeff Brownae9fc032010-08-18 15:51:08 -0700178 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
179 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
180 mThrottleState.lastDeviceId = -1;
181
182#if DEBUG_THROTTLING
183 mThrottleState.originalSampleCount = 0;
184 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
185#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -0700186}
187
188InputDispatcher::~InputDispatcher() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700189 { // acquire lock
190 AutoMutex _l(mLock);
191
192 resetKeyRepeatLocked();
Jeff Brown54a18252010-09-16 14:07:33 -0700193 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700194 drainInboundQueueLocked();
195 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700196
197 while (mConnectionsByReceiveFd.size() != 0) {
198 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
199 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700200}
201
202void InputDispatcher::dispatchOnce() {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700203 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700204 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700205
Jeff Brown46b9ac02010-04-22 18:58:52 -0700206 nsecs_t nextWakeupTime = LONG_LONG_MAX;
207 { // acquire lock
208 AutoMutex _l(mLock);
Jeff Brownb88102f2010-09-08 11:49:43 -0700209 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700210
Jeff Brownb88102f2010-09-08 11:49:43 -0700211 if (runCommandsLockedInterruptible()) {
212 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Brown46b9ac02010-04-22 18:58:52 -0700213 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700214 } // release lock
215
Jeff Brownb88102f2010-09-08 11:49:43 -0700216 // Wait for callback or timeout or wake. (make sure we round up, not down)
217 nsecs_t currentTime = now();
218 int32_t timeoutMillis;
219 if (nextWakeupTime > currentTime) {
220 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
221 timeout = (timeout + 999999LL) / 1000000LL;
222 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
223 } else {
224 timeoutMillis = 0;
225 }
226
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700227 mLooper->pollOnce(timeoutMillis);
Jeff Brownb88102f2010-09-08 11:49:43 -0700228}
229
230void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
231 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
232 nsecs_t currentTime = now();
233
234 // Reset the key repeat timer whenever we disallow key events, even if the next event
235 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
236 // out of sleep.
237 if (keyRepeatTimeout < 0) {
238 resetKeyRepeatLocked();
239 }
240
Jeff Brownb88102f2010-09-08 11:49:43 -0700241 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
242 if (mDispatchFrozen) {
243#if DEBUG_FOCUS
244 LOGD("Dispatch frozen. Waiting some more.");
245#endif
246 return;
247 }
248
249 // Optimize latency of app switches.
250 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
251 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
252 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
253 if (mAppSwitchDueTime < *nextWakeupTime) {
254 *nextWakeupTime = mAppSwitchDueTime;
255 }
256
Jeff Brownb88102f2010-09-08 11:49:43 -0700257 // Ready to start a new event.
258 // If we don't already have a pending event, go grab one.
259 if (! mPendingEvent) {
260 if (mInboundQueue.isEmpty()) {
261 if (isAppSwitchDue) {
262 // The inbound queue is empty so the app switch key we were waiting
263 // for will never arrive. Stop waiting for it.
264 resetPendingAppSwitchLocked(false);
265 isAppSwitchDue = false;
266 }
267
268 // Synthesize a key repeat if appropriate.
269 if (mKeyRepeatState.lastKeyEntry) {
270 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
271 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
272 } else {
273 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
274 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
275 }
276 }
277 }
278 if (! mPendingEvent) {
279 return;
280 }
281 } else {
282 // Inbound queue has at least one entry.
283 EventEntry* entry = mInboundQueue.headSentinel.next;
284
285 // Throttle the entry if it is a move event and there are no
286 // other events behind it in the queue. Due to movement batching, additional
287 // samples may be appended to this event by the time the throttling timeout
288 // expires.
289 // TODO Make this smarter and consider throttling per device independently.
Jeff Brownb6997262010-10-08 22:31:17 -0700290 if (entry->type == EventEntry::TYPE_MOTION
291 && !isAppSwitchDue
292 && mDispatchEnabled
293 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
294 && !entry->isInjected()) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700295 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
296 int32_t deviceId = motionEntry->deviceId;
297 uint32_t source = motionEntry->source;
298 if (! isAppSwitchDue
299 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
300 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
301 && deviceId == mThrottleState.lastDeviceId
302 && source == mThrottleState.lastSource) {
303 nsecs_t nextTime = mThrottleState.lastEventTime
304 + mThrottleState.minTimeBetweenEvents;
305 if (currentTime < nextTime) {
306 // Throttle it!
307#if DEBUG_THROTTLING
308 LOGD("Throttling - Delaying motion event for "
309 "device 0x%x, source 0x%08x by up to %0.3fms.",
310 deviceId, source, (nextTime - currentTime) * 0.000001);
311#endif
312 if (nextTime < *nextWakeupTime) {
313 *nextWakeupTime = nextTime;
314 }
315 if (mThrottleState.originalSampleCount == 0) {
316 mThrottleState.originalSampleCount =
317 motionEntry->countSamples();
318 }
319 return;
320 }
321 }
322
323#if DEBUG_THROTTLING
324 if (mThrottleState.originalSampleCount != 0) {
325 uint32_t count = motionEntry->countSamples();
326 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
327 count - mThrottleState.originalSampleCount,
328 mThrottleState.originalSampleCount, count);
329 mThrottleState.originalSampleCount = 0;
330 }
331#endif
332
333 mThrottleState.lastEventTime = entry->eventTime < currentTime
334 ? entry->eventTime : currentTime;
335 mThrottleState.lastDeviceId = deviceId;
336 mThrottleState.lastSource = source;
337 }
338
339 mInboundQueue.dequeue(entry);
340 mPendingEvent = entry;
341 }
342 }
343
344 // Now we have an event to dispatch.
345 assert(mPendingEvent != NULL);
Jeff Brown54a18252010-09-16 14:07:33 -0700346 bool done = false;
Jeff Brownb6997262010-10-08 22:31:17 -0700347 DropReason dropReason = DROP_REASON_NOT_DROPPED;
348 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
349 dropReason = DROP_REASON_POLICY;
350 } else if (!mDispatchEnabled) {
351 dropReason = DROP_REASON_DISABLED;
352 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700353 switch (mPendingEvent->type) {
354 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
355 ConfigurationChangedEntry* typedEntry =
356 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700357 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brownb6997262010-10-08 22:31:17 -0700358 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Brownb88102f2010-09-08 11:49:43 -0700359 break;
360 }
361
362 case EventEntry::TYPE_KEY: {
363 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700364 if (isAppSwitchDue) {
365 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700366 resetPendingAppSwitchLocked(true);
Jeff Brownb6997262010-10-08 22:31:17 -0700367 isAppSwitchDue = false;
368 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
369 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700370 }
371 }
Jeff Brownb6997262010-10-08 22:31:17 -0700372 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Browne20c9e02010-10-11 14:20:19 -0700373 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700374 break;
375 }
376
377 case EventEntry::TYPE_MOTION: {
378 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700379 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
380 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700381 }
Jeff Brownb6997262010-10-08 22:31:17 -0700382 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Browne20c9e02010-10-11 14:20:19 -0700383 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700384 break;
385 }
386
387 default:
388 assert(false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700389 break;
390 }
391
Jeff Brown54a18252010-09-16 14:07:33 -0700392 if (done) {
Jeff Brownb6997262010-10-08 22:31:17 -0700393 if (dropReason != DROP_REASON_NOT_DROPPED) {
394 dropInboundEventLocked(mPendingEvent, dropReason);
395 }
396
Jeff Brown54a18252010-09-16 14:07:33 -0700397 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700398 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
399 }
400}
401
402bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
403 bool needWake = mInboundQueue.isEmpty();
404 mInboundQueue.enqueueAtTail(entry);
405
406 switch (entry->type) {
Jeff Brownb6997262010-10-08 22:31:17 -0700407 case EventEntry::TYPE_KEY: {
408 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
409 if (isAppSwitchKeyEventLocked(keyEntry)) {
410 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
411 mAppSwitchSawKeyDown = true;
412 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
413 if (mAppSwitchSawKeyDown) {
414#if DEBUG_APP_SWITCH
415 LOGD("App switch is pending!");
416#endif
417 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
418 mAppSwitchSawKeyDown = false;
419 needWake = true;
420 }
421 }
422 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700423 break;
424 }
Jeff Brownb6997262010-10-08 22:31:17 -0700425 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700426
427 return needWake;
428}
429
Jeff Brownb6997262010-10-08 22:31:17 -0700430void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
431 const char* reason;
432 switch (dropReason) {
433 case DROP_REASON_POLICY:
Jeff Browne20c9e02010-10-11 14:20:19 -0700434#if DEBUG_INBOUND_EVENT_DETAILS
435 LOGD("Dropped event because policy requested that it not be delivered to the application.");
436#endif
Jeff Brownb6997262010-10-08 22:31:17 -0700437 reason = "inbound event was dropped because the policy requested that it not be "
438 "delivered to the application";
439 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 Brownb88102f2010-09-08 11:49:43 -0700473 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
474}
475
Jeff Brownb6997262010-10-08 22:31:17 -0700476bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
477 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
478 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Browne20c9e02010-10-11 14:20:19 -0700479 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brownb6997262010-10-08 22:31:17 -0700480 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
481}
482
Jeff Brownb88102f2010-09-08 11:49:43 -0700483bool InputDispatcher::isAppSwitchPendingLocked() {
484 return mAppSwitchDueTime != LONG_LONG_MAX;
485}
486
Jeff Brownb88102f2010-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 Brown46b9ac02010-04-22 18:58:52 -0700497}
498
Jeff Brown9c3cda02010-06-15 01:31:58 -0700499bool InputDispatcher::runCommandsLockedInterruptible() {
500 if (mCommandQueue.isEmpty()) {
501 return false;
502 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700503
Jeff Brown9c3cda02010-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 Brown7fbdc842010-06-17 20:52:56 -0700510 commandEntry->connection.clear();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700511 mAllocator.releaseCommandEntry(commandEntry);
512 } while (! mCommandQueue.isEmpty());
513 return true;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700514}
515
Jeff Brown9c3cda02010-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 Brownb88102f2010-09-08 11:49:43 -0700522void InputDispatcher::drainInboundQueueLocked() {
523 while (! mInboundQueue.isEmpty()) {
524 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700525 releaseInboundEventLocked(entry);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700526 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700527}
528
Jeff Brown54a18252010-09-16 14:07:33 -0700529void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700530 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700531 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700532 mPendingEvent = NULL;
533 }
534}
535
Jeff Brown54a18252010-09-16 14:07:33 -0700536void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700537 InjectionState* injectionState = entry->injectionState;
538 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700539#if DEBUG_DISPATCH_CYCLE
Jeff Brown01ce2e92010-09-26 22:20:12 -0700540 LOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700541#endif
542 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
543 }
544 mAllocator.releaseEventEntry(entry);
545}
546
Jeff Brownb88102f2010-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 Brownb21fb102010-09-07 10:44:57 -0700555 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown349703e2010-06-22 01:27:15 -0700556 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
557
Jeff Brown349703e2010-06-22 01:27:15 -0700558 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Browne20c9e02010-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 Brown46b9ac02010-04-22 18:58:52 -0700561 if (entry->refCount == 1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700562 mAllocator.recycleKeyEntry(entry);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700563 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700564 entry->policyFlags = policyFlags;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700565 entry->repeatCount += 1;
566 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700567 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700568 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700569 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700570 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700571
572 mKeyRepeatState.lastKeyEntry = newEntry;
573 mAllocator.releaseKeyEntry(entry);
574
575 entry = newEntry;
576 }
Jeff Brownb88102f2010-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 Brown46b9ac02010-04-22 18:58:52 -0700582
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700583 if (entry->repeatCount == 1) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700584 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700585 }
586
Jeff Brownb21fb102010-09-07 10:44:57 -0700587 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700588 return entry;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700589}
590
Jeff Brownb88102f2010-09-08 11:49:43 -0700591bool InputDispatcher::dispatchConfigurationChangedLocked(
592 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700593#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownb88102f2010-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 Browne20c9e02010-10-11 14:20:19 -0700609 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brown54a18252010-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 Browne20c9e02010-10-11 14:20:19 -0700612 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brown54a18252010-09-16 14:07:33 -0700613 CommandEntry* commandEntry = postCommandLocked(
614 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Browne20c9e02010-10-11 14:20:19 -0700615 if (mFocusedWindow) {
Jeff Brown54a18252010-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 Browne20c9e02010-10-11 14:20:19 -0700625 if (*dropReason == DROP_REASON_NOT_DROPPED) {
626 *dropReason = DROP_REASON_POLICY;
627 }
Jeff Brown54a18252010-09-16 14:07:33 -0700628 resetTargetsLocked();
629 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
630 return true;
631 }
632
633 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700634 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700635 resetTargetsLocked();
636 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
637 return true;
638 }
639
Jeff Brownb88102f2010-09-08 11:49:43 -0700640 // Preprocessing.
641 if (! entry->dispatchInProgress) {
642 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
643
644 if (entry->repeatCount == 0
645 && entry->action == AKEY_EVENT_ACTION_DOWN
Jeff Browne20c9e02010-10-11 14:20:19 -0700646 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
647 && !entry->isInjected()) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700648 if (mKeyRepeatState.lastKeyEntry
649 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
650 // We have seen two identical key downs in a row which indicates that the device
651 // driver is automatically generating key repeats itself. We take note of the
652 // repeat here, but we disable our own next key repeat timer since it is clear that
653 // we will not need to synthesize key repeats ourselves.
654 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
655 resetKeyRepeatLocked();
656 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
657 } else {
658 // Not a repeat. Save key down state in case we do see a repeat later.
659 resetKeyRepeatLocked();
660 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
661 }
662 mKeyRepeatState.lastKeyEntry = entry;
663 entry->refCount += 1;
664 } else if (! entry->syntheticRepeat) {
665 resetKeyRepeatLocked();
666 }
667
668 entry->dispatchInProgress = true;
Jeff Brown54a18252010-09-16 14:07:33 -0700669 resetTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700670 }
671
672 // Identify targets.
673 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700674 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
675 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700676 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
677 return false;
678 }
679
680 setInjectionResultLocked(entry, injectionResult);
681 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
682 return true;
683 }
684
685 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700686 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700687 }
688
689 // Dispatch the key.
690 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
691
692 // Poke user activity.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700693 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
694 pokeUserActivityLocked(entry->eventTime, POWER_MANAGER_BUTTON_EVENT);
695 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700696 return true;
697}
698
699void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
700#if DEBUG_OUTBOUND_EVENT_DETAILS
701 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
702 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
703 "downTime=%lld",
704 prefix,
705 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
706 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
707 entry->downTime);
708#endif
709}
710
711bool InputDispatcher::dispatchMotionLocked(
Jeff Browne20c9e02010-10-11 14:20:19 -0700712 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brown54a18252010-09-16 14:07:33 -0700713 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700714 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700715 resetTargetsLocked();
716 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
717 return true;
718 }
719
Jeff Brownb88102f2010-09-08 11:49:43 -0700720 // Preprocessing.
721 if (! entry->dispatchInProgress) {
722 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
723
724 entry->dispatchInProgress = true;
Jeff Brown54a18252010-09-16 14:07:33 -0700725 resetTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700726 }
727
728 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
729
730 // Identify targets.
731 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700732 int32_t injectionResult;
733 if (isPointerEvent) {
734 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700735 injectionResult = findTouchedWindowTargetsLocked(currentTime,
736 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700737 } else {
738 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700739 injectionResult = findFocusedWindowTargetsLocked(currentTime,
740 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700741 }
742 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
743 return false;
744 }
745
746 setInjectionResultLocked(entry, injectionResult);
747 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
748 return true;
749 }
750
751 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700752 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700753 }
754
755 // Dispatch the motion.
756 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
757
758 // Poke user activity.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700759 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
760 int32_t eventType;
761 if (isPointerEvent) {
762 switch (entry->action) {
763 case AMOTION_EVENT_ACTION_DOWN:
Jeff Brownb88102f2010-09-08 11:49:43 -0700764 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700765 break;
766 case AMOTION_EVENT_ACTION_UP:
767 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
768 break;
769 default:
770 if (entry->eventTime - entry->downTime >= EVENT_IGNORE_DURATION) {
771 eventType = POWER_MANAGER_TOUCH_EVENT;
772 } else {
773 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
774 }
775 break;
Jeff Brownb88102f2010-09-08 11:49:43 -0700776 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700777 } else {
778 eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brownb88102f2010-09-08 11:49:43 -0700779 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700780 pokeUserActivityLocked(entry->eventTime, eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700781 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700782 return true;
783}
784
785
786void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
787#if DEBUG_OUTBOUND_EVENT_DETAILS
788 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700789 "action=0x%x, flags=0x%x, "
Jeff Brown46b9ac02010-04-22 18:58:52 -0700790 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700791 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700792 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
793 entry->action, entry->flags,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700794 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
795 entry->downTime);
796
797 // Print the most recent sample that we have available, this may change due to batching.
798 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700799 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700800 for (; sample->next != NULL; sample = sample->next) {
801 sampleCount += 1;
802 }
803 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -0700804 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700805 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700806 "orientation=%f",
Jeff Brown46b9ac02010-04-22 18:58:52 -0700807 i, entry->pointerIds[i],
Jeff Brown8d608662010-08-30 03:02:23 -0700808 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
809 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
810 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
811 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
812 sample->pointerCoords[i].orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700813 }
814
815 // Keep in mind that due to batching, it is possible for the number of samples actually
816 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700817 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700818 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
819 }
820#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -0700821}
822
823void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
824 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
825#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -0700826 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac02010-04-22 18:58:52 -0700827 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700828 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac02010-04-22 18:58:52 -0700829#endif
830
Jeff Brown9c3cda02010-06-15 01:31:58 -0700831 assert(eventEntry->dispatchInProgress); // should already have been set to true
832
Jeff Brown46b9ac02010-04-22 18:58:52 -0700833 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
834 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
835
Jeff Brown519e0242010-09-15 15:18:56 -0700836 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700837 if (connectionIndex >= 0) {
838 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700839 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700840 resumeWithAppendedMotionSample);
841 } else {
Jeff Brownb6997262010-10-08 22:31:17 -0700842#if DEBUG_FOCUS
843 LOGD("Dropping event delivery to target with channel '%s' because it "
844 "is no longer registered with the input dispatcher.",
Jeff Brown46b9ac02010-04-22 18:58:52 -0700845 inputTarget.inputChannel->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -0700846#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -0700847 }
848 }
849}
850
Jeff Brown54a18252010-09-16 14:07:33 -0700851void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700852 mCurrentInputTargetsValid = false;
853 mCurrentInputTargets.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700854 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
855}
856
Jeff Brown01ce2e92010-09-26 22:20:12 -0700857void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700858 mCurrentInputTargetsValid = true;
859}
860
861int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
862 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
863 nsecs_t* nextWakeupTime) {
864 if (application == NULL && window == NULL) {
865 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
866#if DEBUG_FOCUS
867 LOGD("Waiting for system to become ready for input.");
868#endif
869 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
870 mInputTargetWaitStartTime = currentTime;
871 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
872 mInputTargetWaitTimeoutExpired = false;
873 }
874 } else {
875 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
876#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700877 LOGD("Waiting for application to become ready for input: %s",
878 getApplicationWindowLabelLocked(application, window).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700879#endif
880 nsecs_t timeout = window ? window->dispatchingTimeout :
881 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
882
883 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
884 mInputTargetWaitStartTime = currentTime;
885 mInputTargetWaitTimeoutTime = currentTime + timeout;
886 mInputTargetWaitTimeoutExpired = false;
887 }
888 }
889
890 if (mInputTargetWaitTimeoutExpired) {
891 return INPUT_EVENT_INJECTION_TIMED_OUT;
892 }
893
894 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown519e0242010-09-15 15:18:56 -0700895 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700896
897 // Force poll loop to wake up immediately on next iteration once we get the
898 // ANR response back from the policy.
899 *nextWakeupTime = LONG_LONG_MIN;
900 return INPUT_EVENT_INJECTION_PENDING;
901 } else {
902 // Force poll loop to wake up when timeout is due.
903 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
904 *nextWakeupTime = mInputTargetWaitTimeoutTime;
905 }
906 return INPUT_EVENT_INJECTION_PENDING;
907 }
908}
909
Jeff Brown519e0242010-09-15 15:18:56 -0700910void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
911 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700912 if (newTimeout > 0) {
913 // Extend the timeout.
914 mInputTargetWaitTimeoutTime = now() + newTimeout;
915 } else {
916 // Give up.
917 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -0700918
Jeff Brown01ce2e92010-09-26 22:20:12 -0700919 // Release the touch targets.
920 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -0700921
Jeff Brown519e0242010-09-15 15:18:56 -0700922 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -0700923 if (inputChannel.get()) {
924 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
925 if (connectionIndex >= 0) {
926 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brownb6997262010-10-08 22:31:17 -0700927 synthesizeCancelationEventsForConnectionLocked(
928 connection, InputState::CANCEL_ALL_EVENTS,
929 "application not responding");
Jeff Browndc3e0052010-09-16 11:02:16 -0700930 }
Jeff Brown519e0242010-09-15 15:18:56 -0700931 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700932 }
933}
934
Jeff Brown519e0242010-09-15 15:18:56 -0700935nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -0700936 nsecs_t currentTime) {
937 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
938 return currentTime - mInputTargetWaitStartTime;
939 }
940 return 0;
941}
942
943void InputDispatcher::resetANRTimeoutsLocked() {
944#if DEBUG_FOCUS
945 LOGD("Resetting ANR timeouts.");
946#endif
947
Jeff Brownb88102f2010-09-08 11:49:43 -0700948 // Reset input target wait timeout.
949 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
950}
951
Jeff Brown01ce2e92010-09-26 22:20:12 -0700952int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
953 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700954 mCurrentInputTargets.clear();
955
956 int32_t injectionResult;
957
958 // If there is no currently focused window and no focused application
959 // then drop the event.
960 if (! mFocusedWindow) {
961 if (mFocusedApplication) {
962#if DEBUG_FOCUS
963 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -0700964 "focused application that may eventually add a window: %s.",
965 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700966#endif
967 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
968 mFocusedApplication, NULL, nextWakeupTime);
969 goto Unresponsive;
970 }
971
972 LOGI("Dropping event because there is no focused window or focused application.");
973 injectionResult = INPUT_EVENT_INJECTION_FAILED;
974 goto Failed;
975 }
976
977 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700978 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700979 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
980 goto Failed;
981 }
982
983 // If the currently focused window is paused then keep waiting.
984 if (mFocusedWindow->paused) {
985#if DEBUG_FOCUS
986 LOGD("Waiting because focused window is paused.");
987#endif
988 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
989 mFocusedApplication, mFocusedWindow, nextWakeupTime);
990 goto Unresponsive;
991 }
992
Jeff Brown519e0242010-09-15 15:18:56 -0700993 // If the currently focused window is still working on previous events then keep waiting.
994 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
995#if DEBUG_FOCUS
996 LOGD("Waiting because focused window still processing previous input.");
997#endif
998 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
999 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1000 goto Unresponsive;
1001 }
1002
Jeff Brownb88102f2010-09-08 11:49:43 -07001003 // Success! Output targets.
1004 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001005 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001006
1007 // Done.
1008Failed:
1009Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001010 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1011 updateDispatchStatisticsLocked(currentTime, entry,
1012 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001013#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -07001014 LOGD("findFocusedWindow finished: injectionResult=%d, "
1015 "timeSpendWaitingForApplication=%0.1fms",
1016 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001017#endif
1018 return injectionResult;
1019}
1020
Jeff Brown01ce2e92010-09-26 22:20:12 -07001021int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1022 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001023 enum InjectionPermission {
1024 INJECTION_PERMISSION_UNKNOWN,
1025 INJECTION_PERMISSION_GRANTED,
1026 INJECTION_PERMISSION_DENIED
1027 };
1028
Jeff Brownb88102f2010-09-08 11:49:43 -07001029 mCurrentInputTargets.clear();
1030
1031 nsecs_t startTime = now();
1032
1033 // For security reasons, we defer updating the touch state until we are sure that
1034 // event injection will be allowed.
1035 //
1036 // FIXME In the original code, screenWasOff could never be set to true.
1037 // The reason is that the POLICY_FLAG_WOKE_HERE
1038 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1039 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1040 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1041 // events upon which no preprocessing took place. So policyFlags was always 0.
1042 // In the new native input dispatcher we're a bit more careful about event
1043 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1044 // Unfortunately we obtain undesirable behavior.
1045 //
1046 // Here's what happens:
1047 //
1048 // When the device dims in anticipation of going to sleep, touches
1049 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1050 // the device to brighten and reset the user activity timer.
1051 // Touches on other windows (such as the launcher window)
1052 // are dropped. Then after a moment, the device goes to sleep. Oops.
1053 //
1054 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1055 // instead of POLICY_FLAG_WOKE_HERE...
1056 //
1057 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1058
1059 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001060 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001061
1062 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001063 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1064 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1065 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1066 mTempTouchState.reset();
1067 mTempTouchState.down = true;
1068 } else {
1069 mTempTouchState.copyFrom(mTouchState);
1070 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001071
Jeff Brown01ce2e92010-09-26 22:20:12 -07001072 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1073 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1074 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1075 /* Case 1: New splittable pointer going down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001076
Jeff Brown01ce2e92010-09-26 22:20:12 -07001077 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1078 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1079 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1080 const InputWindow* newTouchedWindow = NULL;
1081 const InputWindow* topErrorWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07001082
1083 // Traverse windows from front to back to find touched window and outside targets.
1084 size_t numWindows = mWindows.size();
1085 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001086 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001087 int32_t flags = window->layoutParamsFlags;
1088
1089 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1090 if (! topErrorWindow) {
1091 topErrorWindow = window;
1092 }
1093 }
1094
1095 if (window->visible) {
1096 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1097 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1098 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1099 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1100 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1101 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001102 }
1103 break; // found touched window, exit window loop
1104 }
1105 }
1106
Jeff Brown01ce2e92010-09-26 22:20:12 -07001107 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1108 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001109 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1110 if (isWindowObscuredAtPointLocked(window, x, y)) {
1111 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1112 }
1113
1114 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001115 }
1116 }
1117 }
1118
1119 // If there is an error window but it is not taking focus (typically because
1120 // it is invisible) then wait for it. Any other focused window may in
1121 // fact be in ANR state.
1122 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1123#if DEBUG_FOCUS
1124 LOGD("Waiting because system error window is pending.");
1125#endif
1126 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1127 NULL, NULL, nextWakeupTime);
1128 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1129 goto Unresponsive;
1130 }
1131
Jeff Brown01ce2e92010-09-26 22:20:12 -07001132 // Figure out whether splitting will be allowed for this window.
Jeff Brown0c1f7562010-09-28 13:24:41 -07001133 if (newTouchedWindow
1134 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001135 // New window supports splitting.
1136 isSplit = true;
1137 } else if (isSplit) {
1138 // New window does not support splitting but we have already split events.
1139 // Assign the pointer to the first foreground window we find.
1140 // (May be NULL which is why we put this code block before the next check.)
1141 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1142 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001143
Jeff Brownb88102f2010-09-08 11:49:43 -07001144 // If we did not find a touched window then fail.
1145 if (! newTouchedWindow) {
1146 if (mFocusedApplication) {
1147#if DEBUG_FOCUS
1148 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001149 "focused application that may eventually add a new window: %s.",
1150 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001151#endif
1152 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1153 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001154 goto Unresponsive;
1155 }
1156
1157 LOGI("Dropping event because there is no touched window or focused application.");
1158 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001159 goto Failed;
1160 }
1161
Jeff Brown19dfc832010-10-05 12:26:23 -07001162 // Set target flags.
1163 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1164 if (isSplit) {
1165 targetFlags |= InputTarget::FLAG_SPLIT;
1166 }
1167 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1168 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1169 }
1170
Jeff Brown01ce2e92010-09-26 22:20:12 -07001171 // Update the temporary touch state.
1172 BitSet32 pointerIds;
1173 if (isSplit) {
1174 uint32_t pointerId = entry->pointerIds[pointerIndex];
1175 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001176 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001177 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001178 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001179 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001180
1181 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001182 if (! mTempTouchState.down) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001183 LOGI("Dropping event because the pointer is not down.");
1184 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001185 goto Failed;
1186 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001187 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001188
Jeff Brown01ce2e92010-09-26 22:20:12 -07001189 // Check permission to inject into all touched foreground windows and ensure there
1190 // is at least one touched foreground window.
1191 {
1192 bool haveForegroundWindow = false;
1193 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1194 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1195 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1196 haveForegroundWindow = true;
1197 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1198 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1199 injectionPermission = INJECTION_PERMISSION_DENIED;
1200 goto Failed;
1201 }
1202 }
1203 }
1204 if (! haveForegroundWindow) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001205#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown01ce2e92010-09-26 22:20:12 -07001206 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001207#endif
1208 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001209 goto Failed;
1210 }
1211
Jeff Brown01ce2e92010-09-26 22:20:12 -07001212 // Permission granted to injection into all touched foreground windows.
1213 injectionPermission = INJECTION_PERMISSION_GRANTED;
1214 }
Jeff Brown519e0242010-09-15 15:18:56 -07001215
Jeff Brown01ce2e92010-09-26 22:20:12 -07001216 // Ensure all touched foreground windows are ready for new input.
1217 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1218 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1219 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1220 // If the touched window is paused then keep waiting.
1221 if (touchedWindow.window->paused) {
1222#if DEBUG_INPUT_DISPATCHER_POLICY
1223 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001224#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001225 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1226 NULL, touchedWindow.window, nextWakeupTime);
1227 goto Unresponsive;
1228 }
1229
1230 // If the touched window is still working on previous events then keep waiting.
1231 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1232#if DEBUG_FOCUS
1233 LOGD("Waiting because touched window still processing previous input.");
1234#endif
1235 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1236 NULL, touchedWindow.window, nextWakeupTime);
1237 goto Unresponsive;
1238 }
1239 }
1240 }
1241
1242 // If this is the first pointer going down and the touched window has a wallpaper
1243 // then also add the touched wallpaper windows so they are locked in for the duration
1244 // of the touch gesture.
1245 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1246 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1247 if (foregroundWindow->hasWallpaper) {
1248 for (size_t i = 0; i < mWindows.size(); i++) {
1249 const InputWindow* window = & mWindows[i];
1250 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001251 mTempTouchState.addOrUpdateWindow(window,
1252 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001253 }
1254 }
1255 }
1256 }
1257
Jeff Brownb88102f2010-09-08 11:49:43 -07001258 // Success! Output targets.
1259 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001260
Jeff Brown01ce2e92010-09-26 22:20:12 -07001261 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1262 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1263 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1264 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001265 }
1266
Jeff Brown01ce2e92010-09-26 22:20:12 -07001267 // Drop the outside touch window since we will not care about them in the next iteration.
1268 mTempTouchState.removeOutsideTouchWindows();
1269
Jeff Brownb88102f2010-09-08 11:49:43 -07001270Failed:
1271 // Check injection permission once and for all.
1272 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001273 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001274 injectionPermission = INJECTION_PERMISSION_GRANTED;
1275 } else {
1276 injectionPermission = INJECTION_PERMISSION_DENIED;
1277 }
1278 }
1279
1280 // Update final pieces of touch state if the injector had permission.
1281 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001282 if (maskedAction == AMOTION_EVENT_ACTION_UP
1283 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1284 // All pointers up or canceled.
1285 mTempTouchState.reset();
1286 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1287 // First pointer went down.
1288 if (mTouchState.down) {
Jeff Brownb6997262010-10-08 22:31:17 -07001289#if DEBUG_FOCUS
1290 LOGD("Pointer down received while already down.");
1291#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001292 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001293 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1294 // One pointer went up.
1295 if (isSplit) {
1296 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1297 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001298
Jeff Brown01ce2e92010-09-26 22:20:12 -07001299 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1300 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1301 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1302 touchedWindow.pointerIds.clearBit(pointerId);
1303 if (touchedWindow.pointerIds.isEmpty()) {
1304 mTempTouchState.windows.removeAt(i);
1305 continue;
1306 }
1307 }
1308 i += 1;
1309 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001310 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001311 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001312
1313 // Save changes to touch state.
1314 mTouchState.copyFrom(mTempTouchState);
Jeff Brownb88102f2010-09-08 11:49:43 -07001315 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001316#if DEBUG_FOCUS
1317 LOGD("Not updating touch focus because injection was denied.");
1318#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001319 }
1320
1321Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001322 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1323 updateDispatchStatisticsLocked(currentTime, entry,
1324 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001325#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001326 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1327 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001328 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001329#endif
1330 return injectionResult;
1331}
1332
Jeff Brown01ce2e92010-09-26 22:20:12 -07001333void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1334 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001335 mCurrentInputTargets.push();
1336
1337 InputTarget& target = mCurrentInputTargets.editTop();
1338 target.inputChannel = window->inputChannel;
1339 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001340 target.xOffset = - window->frameLeft;
1341 target.yOffset = - window->frameTop;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001342 target.windowType = window->layoutParamsType;
1343 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001344}
1345
1346void InputDispatcher::addMonitoringTargetsLocked() {
1347 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1348 mCurrentInputTargets.push();
1349
1350 InputTarget& target = mCurrentInputTargets.editTop();
1351 target.inputChannel = mMonitoringChannels[i];
1352 target.flags = 0;
Jeff Brownb88102f2010-09-08 11:49:43 -07001353 target.xOffset = 0;
1354 target.yOffset = 0;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001355 target.windowType = InputWindow::TYPE_SYSTEM_OVERLAY;
Jeff Brownb88102f2010-09-08 11:49:43 -07001356 }
1357}
1358
1359bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001360 const InjectionState* injectionState) {
1361 if (injectionState
Jeff Brownb6997262010-10-08 22:31:17 -07001362 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1363 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1364 if (window) {
1365 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1366 "with input channel %s owned by uid %d",
1367 injectionState->injectorPid, injectionState->injectorUid,
1368 window->inputChannel->getName().string(),
1369 window->ownerUid);
1370 } else {
1371 LOGW("Permission denied: injecting event from pid %d uid %d",
1372 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001373 }
Jeff Brownb6997262010-10-08 22:31:17 -07001374 return false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001375 }
1376 return true;
1377}
1378
Jeff Brown19dfc832010-10-05 12:26:23 -07001379bool InputDispatcher::isWindowObscuredAtPointLocked(
1380 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07001381 size_t numWindows = mWindows.size();
1382 for (size_t i = 0; i < numWindows; i++) {
1383 const InputWindow* other = & mWindows.itemAt(i);
1384 if (other == window) {
1385 break;
1386 }
Jeff Brown19dfc832010-10-05 12:26:23 -07001387 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001388 return true;
1389 }
1390 }
1391 return false;
1392}
1393
Jeff Brown519e0242010-09-15 15:18:56 -07001394bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1395 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1396 if (connectionIndex >= 0) {
1397 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1398 return connection->outboundQueue.isEmpty();
1399 } else {
1400 return true;
1401 }
1402}
1403
1404String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1405 const InputWindow* window) {
1406 if (application) {
1407 if (window) {
1408 String8 label(application->name);
1409 label.append(" - ");
1410 label.append(window->name);
1411 return label;
1412 } else {
1413 return application->name;
1414 }
1415 } else if (window) {
1416 return window->name;
1417 } else {
1418 return String8("<unknown application or window>");
1419 }
1420}
1421
Jeff Brown01ce2e92010-09-26 22:20:12 -07001422bool InputDispatcher::shouldPokeUserActivityForCurrentInputTargetsLocked() {
1423 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
1424 if (mCurrentInputTargets[i].windowType == InputWindow::TYPE_KEYGUARD) {
1425 return false;
1426 }
1427 }
1428 return true;
1429}
1430
1431void InputDispatcher::pokeUserActivityLocked(nsecs_t eventTime, int32_t eventType) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001432 CommandEntry* commandEntry = postCommandLocked(
1433 & InputDispatcher::doPokeUserActivityLockedInterruptible);
1434 commandEntry->eventTime = eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001435 commandEntry->userActivityEventType = eventType;
1436}
1437
Jeff Brown7fbdc842010-06-17 20:52:56 -07001438void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1439 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001440 bool resumeWithAppendedMotionSample) {
1441#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001442 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001443 "xOffset=%f, yOffset=%f, "
1444 "windowType=%d, pointerIds=0x%x, "
1445 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001446 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001447 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001448 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001449 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac02010-04-22 18:58:52 -07001450#endif
1451
Jeff Brown01ce2e92010-09-26 22:20:12 -07001452 // Make sure we are never called for streaming when splitting across multiple windows.
1453 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1454 assert(! (resumeWithAppendedMotionSample && isSplit));
1455
Jeff Brown46b9ac02010-04-22 18:58:52 -07001456 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001457 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac02010-04-22 18:58:52 -07001458 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb6997262010-10-08 22:31:17 -07001459#if DEBUG_DISPATCH_CYCLE
1460 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001461 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brownb6997262010-10-08 22:31:17 -07001462#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -07001463 return;
1464 }
1465
Jeff Brown01ce2e92010-09-26 22:20:12 -07001466 // Split a motion event if needed.
1467 if (isSplit) {
1468 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1469
1470 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1471 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1472 MotionEntry* splitMotionEntry = splitMotionEvent(
1473 originalMotionEntry, inputTarget->pointerIds);
1474#if DEBUG_FOCUS
1475 LOGD("channel '%s' ~ Split motion event.",
1476 connection->getInputChannelName());
1477 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1478#endif
1479 eventEntry = splitMotionEntry;
1480 }
1481 }
1482
Jeff Brown46b9ac02010-04-22 18:58:52 -07001483 // Resume the dispatch cycle with a freshly appended motion sample.
1484 // First we check that the last dispatch entry in the outbound queue is for the same
1485 // motion event to which we appended the motion sample. If we find such a dispatch
1486 // entry, and if it is currently in progress then we try to stream the new sample.
1487 bool wasEmpty = connection->outboundQueue.isEmpty();
1488
1489 if (! wasEmpty && resumeWithAppendedMotionSample) {
1490 DispatchEntry* motionEventDispatchEntry =
1491 connection->findQueuedDispatchEntryForEvent(eventEntry);
1492 if (motionEventDispatchEntry) {
1493 // If the dispatch entry is not in progress, then we must be busy dispatching an
1494 // earlier event. Not a problem, the motion event is on the outbound queue and will
1495 // be dispatched later.
1496 if (! motionEventDispatchEntry->inProgress) {
1497#if DEBUG_BATCHING
1498 LOGD("channel '%s' ~ Not streaming because the motion event has "
1499 "not yet been dispatched. "
1500 "(Waiting for earlier events to be consumed.)",
1501 connection->getInputChannelName());
1502#endif
1503 return;
1504 }
1505
1506 // If the dispatch entry is in progress but it already has a tail of pending
1507 // motion samples, then it must mean that the shared memory buffer filled up.
1508 // Not a problem, when this dispatch cycle is finished, we will eventually start
1509 // a new dispatch cycle to process the tail and that tail includes the newly
1510 // appended motion sample.
1511 if (motionEventDispatchEntry->tailMotionSample) {
1512#if DEBUG_BATCHING
1513 LOGD("channel '%s' ~ Not streaming because no new samples can "
1514 "be appended to the motion event in this dispatch cycle. "
1515 "(Waiting for next dispatch cycle to start.)",
1516 connection->getInputChannelName());
1517#endif
1518 return;
1519 }
1520
1521 // The dispatch entry is in progress and is still potentially open for streaming.
1522 // Try to stream the new motion sample. This might fail if the consumer has already
1523 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001524 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1525 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001526 status_t status = connection->inputPublisher.appendMotionSample(
1527 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1528 if (status == OK) {
1529#if DEBUG_BATCHING
1530 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1531 connection->getInputChannelName());
1532#endif
1533 return;
1534 }
1535
1536#if DEBUG_BATCHING
1537 if (status == NO_MEMORY) {
1538 LOGD("channel '%s' ~ Could not append motion sample to currently "
1539 "dispatched move event because the shared memory buffer is full. "
1540 "(Waiting for next dispatch cycle to start.)",
1541 connection->getInputChannelName());
1542 } else if (status == status_t(FAILED_TRANSACTION)) {
1543 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001544 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac02010-04-22 18:58:52 -07001545 "(Waiting for next dispatch cycle to start.)",
1546 connection->getInputChannelName());
1547 } else {
1548 LOGD("channel '%s' ~ Could not append motion sample to currently "
1549 "dispatched move event due to an error, status=%d. "
1550 "(Waiting for next dispatch cycle to start.)",
1551 connection->getInputChannelName(), status);
1552 }
1553#endif
1554 // Failed to stream. Start a new tail of pending motion samples to dispatch
1555 // in the next cycle.
1556 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1557 return;
1558 }
1559 }
1560
1561 // This is a new event.
1562 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001563 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown519e0242010-09-15 15:18:56 -07001564 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1565 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001566 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001567 }
1568
Jeff Brown46b9ac02010-04-22 18:58:52 -07001569 // Handle the case where we could not stream a new motion sample because the consumer has
1570 // already consumed the motion event (otherwise the corresponding dispatch entry would
1571 // still be in the outbound queue for this connection). We set the head motion sample
1572 // to the list starting with the newly appended motion sample.
1573 if (resumeWithAppendedMotionSample) {
1574#if DEBUG_BATCHING
1575 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1576 "that cannot be streamed because the motion event has already been consumed.",
1577 connection->getInputChannelName());
1578#endif
1579 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1580 dispatchEntry->headMotionSample = appendedMotionSample;
1581 }
1582
1583 // Enqueue the dispatch entry.
1584 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1585
1586 // If the outbound queue was previously empty, start the dispatch cycle going.
1587 if (wasEmpty) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001588 activateConnectionLocked(connection.get());
Jeff Brown519e0242010-09-15 15:18:56 -07001589 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001590 }
1591}
1592
Jeff Brown7fbdc842010-06-17 20:52:56 -07001593void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001594 const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001595#if DEBUG_DISPATCH_CYCLE
1596 LOGD("channel '%s' ~ startDispatchCycle",
1597 connection->getInputChannelName());
1598#endif
1599
1600 assert(connection->status == Connection::STATUS_NORMAL);
1601 assert(! connection->outboundQueue.isEmpty());
1602
Jeff Brownb88102f2010-09-08 11:49:43 -07001603 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001604 assert(! dispatchEntry->inProgress);
1605
Jeff Brownb88102f2010-09-08 11:49:43 -07001606 // Mark the dispatch entry as in progress.
1607 dispatchEntry->inProgress = true;
1608
1609 // Update the connection's input state.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001610 EventEntry* eventEntry = dispatchEntry->eventEntry;
1611 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001612
1613#if FILTER_INPUT_EVENTS
1614 // Filter out inconsistent sequences of input events.
1615 // The input system may drop or inject events in a way that could violate implicit
1616 // invariants on input state and potentially cause an application to crash
1617 // or think that a key or pointer is stuck down. Technically we make no guarantees
1618 // of consistency but it would be nice to improve on this where possible.
1619 // XXX: This code is a proof of concept only. Not ready for prime time.
1620 if (consistency == InputState::TOLERABLE) {
1621#if DEBUG_DISPATCH_CYCLE
1622 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1623 "current input state but that is likely to be tolerated by the application.",
1624 connection->getInputChannelName());
1625#endif
1626 } else if (consistency == InputState::BROKEN) {
1627 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1628 "current input state and that is likely to cause the application to crash.",
1629 connection->getInputChannelName());
1630 startNextDispatchCycleLocked(currentTime, connection);
1631 return;
1632 }
1633#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -07001634
1635 // Publish the event.
1636 status_t status;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001637 switch (eventEntry->type) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001638 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001639 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001640
1641 // Apply target flags.
1642 int32_t action = keyEntry->action;
1643 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001644
1645 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001646 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001647 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1648 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1649 keyEntry->eventTime);
1650
1651 if (status) {
1652 LOGE("channel '%s' ~ Could not publish key event, "
1653 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001654 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001655 return;
1656 }
1657 break;
1658 }
1659
1660 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001661 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001662
1663 // Apply target flags.
1664 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001665 int32_t flags = motionEntry->flags;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001666 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001667 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001668 }
Jeff Brown85a31762010-09-01 17:01:00 -07001669 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1670 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1671 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001672
1673 // If headMotionSample is non-NULL, then it points to the first new sample that we
1674 // were unable to dispatch during the previous cycle so we resume dispatching from
1675 // that point in the list of motion samples.
1676 // Otherwise, we just start from the first sample of the motion event.
1677 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1678 if (! firstMotionSample) {
1679 firstMotionSample = & motionEntry->firstSample;
1680 }
1681
Jeff Brownd3616592010-07-16 17:21:06 -07001682 // Set the X and Y offset depending on the input source.
1683 float xOffset, yOffset;
1684 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1685 xOffset = dispatchEntry->xOffset;
1686 yOffset = dispatchEntry->yOffset;
1687 } else {
1688 xOffset = 0.0f;
1689 yOffset = 0.0f;
1690 }
1691
Jeff Brown46b9ac02010-04-22 18:58:52 -07001692 // Publish the motion event and the first motion sample.
1693 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07001694 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownd3616592010-07-16 17:21:06 -07001695 xOffset, yOffset,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001696 motionEntry->xPrecision, motionEntry->yPrecision,
1697 motionEntry->downTime, firstMotionSample->eventTime,
1698 motionEntry->pointerCount, motionEntry->pointerIds,
1699 firstMotionSample->pointerCoords);
1700
1701 if (status) {
1702 LOGE("channel '%s' ~ Could not publish motion event, "
1703 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001704 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001705 return;
1706 }
1707
1708 // Append additional motion samples.
1709 MotionSample* nextMotionSample = firstMotionSample->next;
1710 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1711 status = connection->inputPublisher.appendMotionSample(
1712 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1713 if (status == NO_MEMORY) {
1714#if DEBUG_DISPATCH_CYCLE
1715 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1716 "be sent in the next dispatch cycle.",
1717 connection->getInputChannelName());
1718#endif
1719 break;
1720 }
1721 if (status != OK) {
1722 LOGE("channel '%s' ~ Could not append motion sample "
1723 "for a reason other than out of memory, status=%d",
1724 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001725 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001726 return;
1727 }
1728 }
1729
1730 // Remember the next motion sample that we could not dispatch, in case we ran out
1731 // of space in the shared memory buffer.
1732 dispatchEntry->tailMotionSample = nextMotionSample;
1733 break;
1734 }
1735
1736 default: {
1737 assert(false);
1738 }
1739 }
1740
1741 // Send the dispatch signal.
1742 status = connection->inputPublisher.sendDispatchSignal();
1743 if (status) {
1744 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1745 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001746 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001747 return;
1748 }
1749
1750 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001751 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001752 connection->lastDispatchTime = currentTime;
1753
Jeff Brown46b9ac02010-04-22 18:58:52 -07001754 // Notify other system components.
1755 onDispatchCycleStartedLocked(currentTime, connection);
1756}
1757
Jeff Brown7fbdc842010-06-17 20:52:56 -07001758void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1759 const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001760#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001761 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown46b9ac02010-04-22 18:58:52 -07001762 "%01.1fms since dispatch",
1763 connection->getInputChannelName(),
1764 connection->getEventLatencyMillis(currentTime),
1765 connection->getDispatchLatencyMillis(currentTime));
1766#endif
1767
Jeff Brown9c3cda02010-06-15 01:31:58 -07001768 if (connection->status == Connection::STATUS_BROKEN
1769 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001770 return;
1771 }
1772
Jeff Brown519e0242010-09-15 15:18:56 -07001773 // Notify other system components.
1774 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001775
1776 // Reset the publisher since the event has been consumed.
1777 // We do this now so that the publisher can release some of its internal resources
1778 // while waiting for the next dispatch cycle to begin.
1779 status_t status = connection->inputPublisher.reset();
1780 if (status) {
1781 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1782 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001783 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001784 return;
1785 }
1786
Jeff Brownb88102f2010-09-08 11:49:43 -07001787 startNextDispatchCycleLocked(currentTime, connection);
1788}
1789
1790void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1791 const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001792 // Start the next dispatch cycle for this connection.
1793 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001794 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001795 if (dispatchEntry->inProgress) {
1796 // Finish or resume current event in progress.
1797 if (dispatchEntry->tailMotionSample) {
1798 // We have a tail of undispatched motion samples.
1799 // Reuse the same DispatchEntry and start a new cycle.
1800 dispatchEntry->inProgress = false;
1801 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1802 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07001803 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001804 return;
1805 }
1806 // Finished.
1807 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07001808 if (dispatchEntry->hasForegroundTarget()) {
1809 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001810 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001811 mAllocator.releaseDispatchEntry(dispatchEntry);
1812 } else {
1813 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07001814 // progress event, which means we actually aborted it.
Jeff Brown46b9ac02010-04-22 18:58:52 -07001815 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07001816 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001817 return;
1818 }
1819 }
1820
1821 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07001822 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac02010-04-22 18:58:52 -07001823}
1824
Jeff Brownb6997262010-10-08 22:31:17 -07001825void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1826 const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001827#if DEBUG_DISPATCH_CYCLE
Jeff Brownb6997262010-10-08 22:31:17 -07001828 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001829 connection->getInputChannelName(), toString(broken));
Jeff Brown46b9ac02010-04-22 18:58:52 -07001830#endif
1831
Jeff Brownb88102f2010-09-08 11:49:43 -07001832 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07001833 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac02010-04-22 18:58:52 -07001834
Jeff Brownb6997262010-10-08 22:31:17 -07001835 // The connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07001836 // Ignore already broken or zombie connections.
Jeff Brownb6997262010-10-08 22:31:17 -07001837 if (connection->status == Connection::STATUS_NORMAL) {
1838 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001839
Jeff Brownb6997262010-10-08 22:31:17 -07001840 // Notify other system components.
1841 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001842 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001843}
1844
Jeff Brown519e0242010-09-15 15:18:56 -07001845void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1846 while (! connection->outboundQueue.isEmpty()) {
1847 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1848 if (dispatchEntry->hasForegroundTarget()) {
1849 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001850 }
1851 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001852 }
1853
Jeff Brown519e0242010-09-15 15:18:56 -07001854 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07001855}
1856
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001857int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001858 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1859
1860 { // acquire lock
1861 AutoMutex _l(d->mLock);
1862
1863 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1864 if (connectionIndex < 0) {
1865 LOGE("Received spurious receive callback for unknown input channel. "
1866 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001867 return 0; // remove the callback
Jeff Brown46b9ac02010-04-22 18:58:52 -07001868 }
1869
Jeff Brown7fbdc842010-06-17 20:52:56 -07001870 nsecs_t currentTime = now();
Jeff Brown46b9ac02010-04-22 18:58:52 -07001871
1872 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001873 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001874 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1875 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brownb6997262010-10-08 22:31:17 -07001876 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001877 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001878 return 0; // remove the callback
Jeff Brown46b9ac02010-04-22 18:58:52 -07001879 }
1880
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001881 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001882 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1883 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001884 return 1;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001885 }
1886
1887 status_t status = connection->inputPublisher.receiveFinishedSignal();
1888 if (status) {
1889 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1890 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001891 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001892 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001893 return 0; // remove the callback
Jeff Brown46b9ac02010-04-22 18:58:52 -07001894 }
1895
Jeff Brown7fbdc842010-06-17 20:52:56 -07001896 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001897 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001898 return 1;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001899 } // release lock
1900}
1901
Jeff Brownb6997262010-10-08 22:31:17 -07001902void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1903 InputState::CancelationOptions options, const char* reason) {
1904 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1905 synthesizeCancelationEventsForConnectionLocked(
1906 mConnectionsByReceiveFd.valueAt(i), options, reason);
1907 }
1908}
1909
1910void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1911 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1912 const char* reason) {
1913 ssize_t index = getConnectionIndexLocked(channel);
1914 if (index >= 0) {
1915 synthesizeCancelationEventsForConnectionLocked(
1916 mConnectionsByReceiveFd.valueAt(index), options, reason);
1917 }
1918}
1919
1920void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1921 const sp<Connection>& connection, InputState::CancelationOptions options,
1922 const char* reason) {
1923 nsecs_t currentTime = now();
1924
1925 mTempCancelationEvents.clear();
1926 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1927 mTempCancelationEvents, options);
1928
1929 if (! mTempCancelationEvents.isEmpty()
1930 && connection->status != Connection::STATUS_BROKEN) {
1931#if DEBUG_OUTBOUND_EVENT_DETAILS
1932 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1933 "with reality: %s, options=%d.",
1934 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1935#endif
1936 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1937 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1938 switch (cancelationEventEntry->type) {
1939 case EventEntry::TYPE_KEY:
1940 logOutboundKeyDetailsLocked("cancel - ",
1941 static_cast<KeyEntry*>(cancelationEventEntry));
1942 break;
1943 case EventEntry::TYPE_MOTION:
1944 logOutboundMotionDetailsLocked("cancel - ",
1945 static_cast<MotionEntry*>(cancelationEventEntry));
1946 break;
1947 }
1948
1949 int32_t xOffset, yOffset;
1950 const InputWindow* window = getWindowLocked(connection->inputChannel);
1951 if (window) {
1952 xOffset = -window->frameLeft;
1953 yOffset = -window->frameTop;
1954 } else {
1955 xOffset = 0;
1956 yOffset = 0;
1957 }
1958
1959 DispatchEntry* cancelationDispatchEntry =
1960 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1961 0, xOffset, yOffset);
1962 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1963
1964 mAllocator.releaseEventEntry(cancelationEventEntry);
1965 }
1966
1967 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1968 startDispatchCycleLocked(currentTime, connection);
1969 }
1970 }
1971}
1972
Jeff Brown01ce2e92010-09-26 22:20:12 -07001973InputDispatcher::MotionEntry*
1974InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1975 assert(pointerIds.value != 0);
1976
1977 uint32_t splitPointerIndexMap[MAX_POINTERS];
1978 int32_t splitPointerIds[MAX_POINTERS];
1979 PointerCoords splitPointerCoords[MAX_POINTERS];
1980
1981 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1982 uint32_t splitPointerCount = 0;
1983
1984 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1985 originalPointerIndex++) {
1986 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1987 if (pointerIds.hasBit(pointerId)) {
1988 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1989 splitPointerIds[splitPointerCount] = pointerId;
1990 splitPointerCoords[splitPointerCount] =
1991 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1992 splitPointerCount += 1;
1993 }
1994 }
1995 assert(splitPointerCount == pointerIds.count());
1996
1997 int32_t action = originalMotionEntry->action;
1998 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1999 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2000 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2001 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2002 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2003 if (pointerIds.hasBit(pointerId)) {
2004 if (pointerIds.count() == 1) {
2005 // The first/last pointer went down/up.
2006 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2007 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07002008 } else {
2009 // A secondary pointer went down/up.
2010 uint32_t splitPointerIndex = 0;
2011 while (pointerId != splitPointerIds[splitPointerIndex]) {
2012 splitPointerIndex += 1;
2013 }
2014 action = maskedAction | (splitPointerIndex
2015 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002016 }
2017 } else {
2018 // An unrelated pointer changed.
2019 action = AMOTION_EVENT_ACTION_MOVE;
2020 }
2021 }
2022
2023 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2024 originalMotionEntry->eventTime,
2025 originalMotionEntry->deviceId,
2026 originalMotionEntry->source,
2027 originalMotionEntry->policyFlags,
2028 action,
2029 originalMotionEntry->flags,
2030 originalMotionEntry->metaState,
2031 originalMotionEntry->edgeFlags,
2032 originalMotionEntry->xPrecision,
2033 originalMotionEntry->yPrecision,
2034 originalMotionEntry->downTime,
2035 splitPointerCount, splitPointerIds, splitPointerCoords);
2036
2037 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2038 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2039 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2040 splitPointerIndex++) {
2041 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2042 splitPointerCoords[splitPointerIndex] =
2043 originalMotionSample->pointerCoords[originalPointerIndex];
2044 }
2045
2046 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2047 splitPointerCoords);
2048 }
2049
2050 return splitMotionEntry;
2051}
2052
Jeff Brown9c3cda02010-06-15 01:31:58 -07002053void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002054#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07002055 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002056#endif
2057
Jeff Brownb88102f2010-09-08 11:49:43 -07002058 bool needWake;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002059 { // acquire lock
2060 AutoMutex _l(mLock);
2061
Jeff Brown7fbdc842010-06-17 20:52:56 -07002062 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07002063 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002064 } // release lock
2065
Jeff Brownb88102f2010-09-08 11:49:43 -07002066 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002067 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002068 }
2069}
2070
Jeff Brownc5ed5912010-07-14 18:48:53 -07002071void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002072 uint32_t policyFlags, int32_t action, int32_t flags,
2073 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2074#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brownc5ed5912010-07-14 18:48:53 -07002075 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac02010-04-22 18:58:52 -07002076 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07002077 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002078 keyCode, scanCode, metaState, downTime);
2079#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002080 if (! validateKeyEvent(action)) {
2081 return;
2082 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002083
Jeff Browne20c9e02010-10-11 14:20:19 -07002084 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002085 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2086 keyCode, scanCode, /*byref*/ policyFlags);
2087
Jeff Brownb88102f2010-09-08 11:49:43 -07002088 bool needWake;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002089 { // acquire lock
2090 AutoMutex _l(mLock);
2091
Jeff Brown7fbdc842010-06-17 20:52:56 -07002092 int32_t repeatCount = 0;
2093 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002094 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002095 metaState, repeatCount, downTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002096
Jeff Brownb88102f2010-09-08 11:49:43 -07002097 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002098 } // release lock
2099
Jeff Brownb88102f2010-09-08 11:49:43 -07002100 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002101 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002102 }
2103}
2104
Jeff Brownc5ed5912010-07-14 18:48:53 -07002105void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002106 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002107 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2108 float xPrecision, float yPrecision, nsecs_t downTime) {
2109#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brownc5ed5912010-07-14 18:48:53 -07002110 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002111 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2112 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2113 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002114 xPrecision, yPrecision, downTime);
2115 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002116 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002117 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002118 "orientation=%f",
Jeff Brown46b9ac02010-04-22 18:58:52 -07002119 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown8d608662010-08-30 03:02:23 -07002120 pointerCoords[i].pressure, pointerCoords[i].size,
2121 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2122 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2123 pointerCoords[i].orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002124 }
2125#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002126 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2127 return;
2128 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002129
Jeff Browne20c9e02010-10-11 14:20:19 -07002130 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002131 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2132
Jeff Brownb88102f2010-09-08 11:49:43 -07002133 bool needWake;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002134 { // acquire lock
2135 AutoMutex _l(mLock);
2136
2137 // Attempt batching and streaming of move events.
Jeff Brownc5ed5912010-07-14 18:48:53 -07002138 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002139 // BATCHING CASE
2140 //
2141 // Try to append a move sample to the tail of the inbound queue for this device.
2142 // Give up if we encounter a non-move motion event for this device since that
2143 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002144 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2145 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002146 if (entry->type != EventEntry::TYPE_MOTION) {
2147 // Keep looking for motion events.
2148 continue;
2149 }
2150
2151 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2152 if (motionEntry->deviceId != deviceId) {
2153 // Keep looking for this device.
2154 continue;
2155 }
2156
Jeff Brownc5ed5912010-07-14 18:48:53 -07002157 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown7fbdc842010-06-17 20:52:56 -07002158 || motionEntry->pointerCount != pointerCount
2159 || motionEntry->isInjected()) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002160 // Last motion event in the queue for this device is not compatible for
2161 // appending new samples. Stop here.
2162 goto NoBatchingOrStreaming;
2163 }
2164
2165 // The last motion event is a move and is compatible for appending.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002166 // Do the batching magic.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002167 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002168#if DEBUG_BATCHING
2169 LOGD("Appended motion sample onto batch for most recent "
2170 "motion event for this device in the inbound queue.");
2171#endif
Jeff Brown9c3cda02010-06-15 01:31:58 -07002172 return; // done!
Jeff Brown46b9ac02010-04-22 18:58:52 -07002173 }
2174
2175 // STREAMING CASE
2176 //
2177 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002178 // Search the outbound queue for the current foreground targets to find a dispatched
2179 // motion event that is still in progress. If found, then, appen the new sample to
2180 // that event and push it out to all current targets. The logic in
2181 // prepareDispatchCycleLocked takes care of the case where some targets may
2182 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002183 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002184 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2185 const InputTarget& inputTarget = mCurrentInputTargets[i];
2186 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2187 // Skip non-foreground targets. We only want to stream if there is at
2188 // least one foreground target whose dispatch is still in progress.
2189 continue;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002190 }
Jeff Brown519e0242010-09-15 15:18:56 -07002191
2192 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2193 if (connectionIndex < 0) {
2194 // Connection must no longer be valid.
2195 continue;
2196 }
2197
2198 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2199 if (connection->outboundQueue.isEmpty()) {
2200 // This foreground target has an empty outbound queue.
2201 continue;
2202 }
2203
2204 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2205 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002206 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2207 || dispatchEntry->isSplit()) {
2208 // No motion event is being dispatched, or it is being split across
2209 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002210 continue;
2211 }
2212
2213 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2214 dispatchEntry->eventEntry);
2215 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2216 || motionEntry->deviceId != deviceId
2217 || motionEntry->pointerCount != pointerCount
2218 || motionEntry->isInjected()) {
2219 // The motion event is not compatible with this move.
2220 continue;
2221 }
2222
2223 // Hurray! This foreground target is currently dispatching a move event
2224 // that we can stream onto. Append the motion sample and resume dispatch.
2225 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2226#if DEBUG_BATCHING
2227 LOGD("Appended motion sample onto batch for most recently dispatched "
2228 "motion event for this device in the outbound queues. "
2229 "Attempting to stream the motion sample.");
2230#endif
2231 nsecs_t currentTime = now();
2232 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2233 true /*resumeWithAppendedMotionSample*/);
2234
2235 runCommandsLockedInterruptible();
2236 return; // done!
Jeff Brown46b9ac02010-04-22 18:58:52 -07002237 }
2238 }
2239
2240NoBatchingOrStreaming:;
2241 }
2242
2243 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002244 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002245 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002246 xPrecision, yPrecision, downTime,
2247 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002248
Jeff Brownb88102f2010-09-08 11:49:43 -07002249 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002250 } // release lock
2251
Jeff Brownb88102f2010-09-08 11:49:43 -07002252 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002253 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002254 }
2255}
2256
Jeff Brownb6997262010-10-08 22:31:17 -07002257void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2258 uint32_t policyFlags) {
2259#if DEBUG_INBOUND_EVENT_DETAILS
2260 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2261 switchCode, switchValue, policyFlags);
2262#endif
2263
Jeff Browne20c9e02010-10-11 14:20:19 -07002264 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002265 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2266}
2267
Jeff Brown7fbdc842010-06-17 20:52:56 -07002268int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002269 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002270#if DEBUG_INBOUND_EVENT_DETAILS
2271 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002272 "syncMode=%d, timeoutMillis=%d",
2273 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002274#endif
2275
2276 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Browne20c9e02010-10-11 14:20:19 -07002277
2278 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2279 if (hasInjectionPermission(injectorPid, injectorUid)) {
2280 policyFlags |= POLICY_FLAG_TRUSTED;
2281 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002282
Jeff Brownb6997262010-10-08 22:31:17 -07002283 EventEntry* injectedEntry;
2284 switch (event->getType()) {
2285 case AINPUT_EVENT_TYPE_KEY: {
2286 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2287 int32_t action = keyEvent->getAction();
2288 if (! validateKeyEvent(action)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002289 return INPUT_EVENT_INJECTION_FAILED;
2290 }
2291
Jeff Brownb6997262010-10-08 22:31:17 -07002292 nsecs_t eventTime = keyEvent->getEventTime();
2293 int32_t deviceId = keyEvent->getDeviceId();
2294 int32_t flags = keyEvent->getFlags();
2295 int32_t keyCode = keyEvent->getKeyCode();
2296 int32_t scanCode = keyEvent->getScanCode();
Jeff Browne20c9e02010-10-11 14:20:19 -07002297 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2298 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002299
Jeff Brownb6997262010-10-08 22:31:17 -07002300 mLock.lock();
2301 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2302 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2303 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2304 break;
2305 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002306
Jeff Brownb6997262010-10-08 22:31:17 -07002307 case AINPUT_EVENT_TYPE_MOTION: {
2308 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2309 int32_t action = motionEvent->getAction();
2310 size_t pointerCount = motionEvent->getPointerCount();
2311 const int32_t* pointerIds = motionEvent->getPointerIds();
2312 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2313 return INPUT_EVENT_INJECTION_FAILED;
2314 }
2315
2316 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Browne20c9e02010-10-11 14:20:19 -07002317 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002318
2319 mLock.lock();
2320 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2321 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2322 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2323 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2324 action, motionEvent->getFlags(),
2325 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2326 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2327 motionEvent->getDownTime(), uint32_t(pointerCount),
2328 pointerIds, samplePointerCoords);
2329 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2330 sampleEventTimes += 1;
2331 samplePointerCoords += pointerCount;
2332 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2333 }
2334 injectedEntry = motionEntry;
2335 break;
2336 }
2337
2338 default:
2339 LOGW("Cannot inject event of type %d", event->getType());
2340 return INPUT_EVENT_INJECTION_FAILED;
2341 }
2342
2343 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2344 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2345 injectionState->injectionIsAsync = true;
2346 }
2347
2348 injectionState->refCount += 1;
2349 injectedEntry->injectionState = injectionState;
2350
2351 bool needWake = enqueueInboundEventLocked(injectedEntry);
2352 mLock.unlock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002353
Jeff Brownb88102f2010-09-08 11:49:43 -07002354 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002355 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002356 }
2357
2358 int32_t injectionResult;
2359 { // acquire lock
2360 AutoMutex _l(mLock);
2361
Jeff Brown6ec402b2010-07-28 15:48:59 -07002362 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2363 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2364 } else {
2365 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002366 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002367 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2368 break;
2369 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002370
Jeff Brown7fbdc842010-06-17 20:52:56 -07002371 nsecs_t remainingTimeout = endTime - now();
2372 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002373#if DEBUG_INJECTION
2374 LOGD("injectInputEvent - Timed out waiting for injection result "
2375 "to become available.");
2376#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002377 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2378 break;
2379 }
2380
Jeff Brown6ec402b2010-07-28 15:48:59 -07002381 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2382 }
2383
2384 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2385 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002386 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002387#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002388 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002389 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002390#endif
2391 nsecs_t remainingTimeout = endTime - now();
2392 if (remainingTimeout <= 0) {
2393#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002394 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002395 "dispatches to finish.");
2396#endif
2397 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2398 break;
2399 }
2400
2401 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2402 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002403 }
2404 }
2405
Jeff Brown01ce2e92010-09-26 22:20:12 -07002406 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002407 } // release lock
2408
Jeff Brown6ec402b2010-07-28 15:48:59 -07002409#if DEBUG_INJECTION
2410 LOGD("injectInputEvent - Finished with result %d. "
2411 "injectorPid=%d, injectorUid=%d",
2412 injectionResult, injectorPid, injectorUid);
2413#endif
2414
Jeff Brown7fbdc842010-06-17 20:52:56 -07002415 return injectionResult;
2416}
2417
Jeff Brownb6997262010-10-08 22:31:17 -07002418bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2419 return injectorUid == 0
2420 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2421}
2422
Jeff Brown7fbdc842010-06-17 20:52:56 -07002423void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002424 InjectionState* injectionState = entry->injectionState;
2425 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002426#if DEBUG_INJECTION
2427 LOGD("Setting input event injection result to %d. "
2428 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002429 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002430#endif
2431
Jeff Brown01ce2e92010-09-26 22:20:12 -07002432 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002433 // Log the outcome since the injector did not wait for the injection result.
2434 switch (injectionResult) {
2435 case INPUT_EVENT_INJECTION_SUCCEEDED:
2436 LOGV("Asynchronous input event injection succeeded.");
2437 break;
2438 case INPUT_EVENT_INJECTION_FAILED:
2439 LOGW("Asynchronous input event injection failed.");
2440 break;
2441 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2442 LOGW("Asynchronous input event injection permission denied.");
2443 break;
2444 case INPUT_EVENT_INJECTION_TIMED_OUT:
2445 LOGW("Asynchronous input event injection timed out.");
2446 break;
2447 }
2448 }
2449
Jeff Brown01ce2e92010-09-26 22:20:12 -07002450 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002451 mInjectionResultAvailableCondition.broadcast();
2452 }
2453}
2454
Jeff Brown01ce2e92010-09-26 22:20:12 -07002455void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2456 InjectionState* injectionState = entry->injectionState;
2457 if (injectionState) {
2458 injectionState->pendingForegroundDispatches += 1;
2459 }
2460}
2461
Jeff Brown519e0242010-09-15 15:18:56 -07002462void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002463 InjectionState* injectionState = entry->injectionState;
2464 if (injectionState) {
2465 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002466
Jeff Brown01ce2e92010-09-26 22:20:12 -07002467 if (injectionState->pendingForegroundDispatches == 0) {
2468 mInjectionSyncFinishedCondition.broadcast();
2469 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002470 }
2471}
2472
Jeff Brown01ce2e92010-09-26 22:20:12 -07002473const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2474 for (size_t i = 0; i < mWindows.size(); i++) {
2475 const InputWindow* window = & mWindows[i];
2476 if (window->inputChannel == inputChannel) {
2477 return window;
2478 }
2479 }
2480 return NULL;
2481}
2482
Jeff Brownb88102f2010-09-08 11:49:43 -07002483void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2484#if DEBUG_FOCUS
2485 LOGD("setInputWindows");
2486#endif
2487 { // acquire lock
2488 AutoMutex _l(mLock);
2489
Jeff Brown01ce2e92010-09-26 22:20:12 -07002490 // Clear old window pointers.
Jeff Brownb6997262010-10-08 22:31:17 -07002491 sp<InputChannel> oldFocusedWindowChannel;
2492 if (mFocusedWindow) {
2493 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2494 mFocusedWindow = NULL;
2495 }
2496
Jeff Brownb88102f2010-09-08 11:49:43 -07002497 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002498
2499 // Loop over new windows and rebuild the necessary window pointers for
2500 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002501 mWindows.appendVector(inputWindows);
2502
2503 size_t numWindows = mWindows.size();
2504 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002505 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002506 if (window->hasFocus) {
2507 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002508 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002509 }
2510 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002511
Jeff Brownb6997262010-10-08 22:31:17 -07002512 if (oldFocusedWindowChannel != NULL) {
2513 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2514#if DEBUG_FOCUS
2515 LOGD("Focus left window: %s",
2516 oldFocusedWindowChannel->getName().string());
2517#endif
2518 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2519 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2520 oldFocusedWindowChannel.clear();
2521 }
2522 }
2523 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2524#if DEBUG_FOCUS
2525 LOGD("Focus entered window: %s",
2526 mFocusedWindow->inputChannel->getName().string());
2527#endif
2528 }
2529
Jeff Brown01ce2e92010-09-26 22:20:12 -07002530 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2531 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2532 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2533 if (window) {
2534 touchedWindow.window = window;
2535 i += 1;
2536 } else {
Jeff Brownb6997262010-10-08 22:31:17 -07002537#if DEBUG_FOCUS
2538 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2539#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002540 mTouchState.windows.removeAt(i);
Jeff Brownb6997262010-10-08 22:31:17 -07002541 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2542 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brown01ce2e92010-09-26 22:20:12 -07002543 }
2544 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002545
Jeff Brownb88102f2010-09-08 11:49:43 -07002546#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002547 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002548#endif
2549 } // release lock
2550
2551 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002552 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002553}
2554
2555void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2556#if DEBUG_FOCUS
2557 LOGD("setFocusedApplication");
2558#endif
2559 { // acquire lock
2560 AutoMutex _l(mLock);
2561
2562 releaseFocusedApplicationLocked();
2563
2564 if (inputApplication) {
2565 mFocusedApplicationStorage = *inputApplication;
2566 mFocusedApplication = & mFocusedApplicationStorage;
2567 }
2568
2569#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002570 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002571#endif
2572 } // release lock
2573
2574 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002575 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002576}
2577
2578void InputDispatcher::releaseFocusedApplicationLocked() {
2579 if (mFocusedApplication) {
2580 mFocusedApplication = NULL;
2581 mFocusedApplicationStorage.handle.clear();
2582 }
2583}
2584
2585void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2586#if DEBUG_FOCUS
2587 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2588#endif
2589
2590 bool changed;
2591 { // acquire lock
2592 AutoMutex _l(mLock);
2593
2594 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2595 if (mDispatchFrozen && ! frozen) {
2596 resetANRTimeoutsLocked();
2597 }
2598
2599 mDispatchEnabled = enabled;
2600 mDispatchFrozen = frozen;
2601 changed = true;
2602 } else {
2603 changed = false;
2604 }
2605
2606#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002607 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002608#endif
2609 } // release lock
2610
2611 if (changed) {
2612 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002613 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002614 }
2615}
2616
Jeff Browne6504122010-09-27 14:52:15 -07002617bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2618 const sp<InputChannel>& toChannel) {
2619#if DEBUG_FOCUS
2620 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2621 fromChannel->getName().string(), toChannel->getName().string());
2622#endif
2623 { // acquire lock
2624 AutoMutex _l(mLock);
2625
2626 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2627 const InputWindow* toWindow = getWindowLocked(toChannel);
2628 if (! fromWindow || ! toWindow) {
2629#if DEBUG_FOCUS
2630 LOGD("Cannot transfer focus because from or to window not found.");
2631#endif
2632 return false;
2633 }
2634 if (fromWindow == toWindow) {
2635#if DEBUG_FOCUS
2636 LOGD("Trivial transfer to same window.");
2637#endif
2638 return true;
2639 }
2640
2641 bool found = false;
2642 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2643 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2644 if (touchedWindow.window == fromWindow) {
2645 int32_t oldTargetFlags = touchedWindow.targetFlags;
2646 BitSet32 pointerIds = touchedWindow.pointerIds;
2647
2648 mTouchState.windows.removeAt(i);
2649
2650 int32_t newTargetFlags = 0;
2651 if (oldTargetFlags & InputTarget::FLAG_FOREGROUND) {
2652 newTargetFlags |= InputTarget::FLAG_FOREGROUND;
2653 if (toWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) {
2654 newTargetFlags |= InputTarget::FLAG_SPLIT;
2655 }
2656 }
2657 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2658
2659 found = true;
2660 break;
2661 }
2662 }
2663
2664 if (! found) {
2665#if DEBUG_FOCUS
2666 LOGD("Focus transfer failed because from window did not have focus.");
2667#endif
2668 return false;
2669 }
2670
Jeff Brown9c9f1a32010-10-11 18:32:20 -07002671 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2672 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2673 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2674 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2675 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2676
2677 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2678 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2679 InputState::CANCEL_POINTER_EVENTS,
2680 "transferring touch focus from this window to another window");
2681 }
2682
Jeff Browne6504122010-09-27 14:52:15 -07002683#if DEBUG_FOCUS
2684 logDispatchStateLocked();
2685#endif
2686 } // release lock
2687
2688 // Wake up poll loop since it may need to make new input dispatching choices.
2689 mLooper->wake();
2690 return true;
2691}
2692
Jeff Brownb88102f2010-09-08 11:49:43 -07002693void InputDispatcher::logDispatchStateLocked() {
2694 String8 dump;
2695 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002696
2697 char* text = dump.lockBuffer(dump.size());
2698 char* start = text;
2699 while (*start != '\0') {
2700 char* end = strchr(start, '\n');
2701 if (*end == '\n') {
2702 *(end++) = '\0';
2703 }
2704 LOGD("%s", start);
2705 start = end;
2706 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002707}
2708
2709void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f48712010-10-01 17:46:21 -07002710 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2711 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07002712
2713 if (mFocusedApplication) {
Jeff Brownf2f48712010-10-01 17:46:21 -07002714 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002715 mFocusedApplication->name.string(),
2716 mFocusedApplication->dispatchingTimeout / 1000000.0);
2717 } else {
Jeff Brownf2f48712010-10-01 17:46:21 -07002718 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002719 }
Jeff Brownf2f48712010-10-01 17:46:21 -07002720 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002721 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f48712010-10-01 17:46:21 -07002722
2723 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2724 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2725 if (!mTouchState.windows.isEmpty()) {
2726 dump.append(INDENT "TouchedWindows:\n");
2727 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2728 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2729 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2730 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2731 touchedWindow.targetFlags);
2732 }
2733 } else {
2734 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002735 }
2736
Jeff Brownf2f48712010-10-01 17:46:21 -07002737 if (!mWindows.isEmpty()) {
2738 dump.append(INDENT "Windows:\n");
2739 for (size_t i = 0; i < mWindows.size(); i++) {
2740 const InputWindow& window = mWindows[i];
2741 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2742 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2743 "frame=[%d,%d][%d,%d], "
2744 "visibleFrame=[%d,%d][%d,%d], "
2745 "touchableArea=[%d,%d][%d,%d], "
2746 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2747 i, window.name.string(),
2748 toString(window.paused),
2749 toString(window.hasFocus),
2750 toString(window.hasWallpaper),
2751 toString(window.visible),
2752 toString(window.canReceiveKeys),
2753 window.layoutParamsFlags, window.layoutParamsType,
2754 window.layer,
2755 window.frameLeft, window.frameTop,
2756 window.frameRight, window.frameBottom,
2757 window.visibleFrameLeft, window.visibleFrameTop,
2758 window.visibleFrameRight, window.visibleFrameBottom,
2759 window.touchableAreaLeft, window.touchableAreaTop,
2760 window.touchableAreaRight, window.touchableAreaBottom,
2761 window.ownerPid, window.ownerUid,
2762 window.dispatchingTimeout / 1000000.0);
2763 }
2764 } else {
2765 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002766 }
2767
Jeff Brownf2f48712010-10-01 17:46:21 -07002768 if (!mMonitoringChannels.isEmpty()) {
2769 dump.append(INDENT "MonitoringChannels:\n");
2770 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2771 const sp<InputChannel>& channel = mMonitoringChannels[i];
2772 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2773 }
2774 } else {
2775 dump.append(INDENT "MonitoringChannels: <none>\n");
2776 }
Jeff Brown519e0242010-09-15 15:18:56 -07002777
Jeff Brownf2f48712010-10-01 17:46:21 -07002778 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2779
2780 if (!mActiveConnections.isEmpty()) {
2781 dump.append(INDENT "ActiveConnections:\n");
2782 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2783 const Connection* connection = mActiveConnections[i];
2784 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
Jeff Brownb6997262010-10-08 22:31:17 -07002785 "inputState.isNeutral=%s\n",
Jeff Brownf2f48712010-10-01 17:46:21 -07002786 i, connection->getInputChannelName(), connection->getStatusLabel(),
2787 connection->outboundQueue.count(),
Jeff Brownb6997262010-10-08 22:31:17 -07002788 toString(connection->inputState.isNeutral()));
Jeff Brownf2f48712010-10-01 17:46:21 -07002789 }
2790 } else {
2791 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002792 }
2793
2794 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f48712010-10-01 17:46:21 -07002795 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002796 (mAppSwitchDueTime - now()) / 1000000.0);
2797 } else {
Jeff Brownf2f48712010-10-01 17:46:21 -07002798 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002799 }
2800}
2801
2802status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002803#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07002804 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2805 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07002806#endif
2807
Jeff Brown46b9ac02010-04-22 18:58:52 -07002808 { // acquire lock
2809 AutoMutex _l(mLock);
2810
Jeff Brown519e0242010-09-15 15:18:56 -07002811 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002812 LOGW("Attempted to register already registered input channel '%s'",
2813 inputChannel->getName().string());
2814 return BAD_VALUE;
2815 }
2816
2817 sp<Connection> connection = new Connection(inputChannel);
2818 status_t status = connection->initialize();
2819 if (status) {
2820 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2821 inputChannel->getName().string(), status);
2822 return status;
2823 }
2824
Jeff Brown2cbecea2010-08-17 15:59:26 -07002825 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002826 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002827
Jeff Brownb88102f2010-09-08 11:49:43 -07002828 if (monitor) {
2829 mMonitoringChannels.push(inputChannel);
2830 }
2831
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002832 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07002833
Jeff Brown9c3cda02010-06-15 01:31:58 -07002834 runCommandsLockedInterruptible();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002835 } // release lock
Jeff Brown46b9ac02010-04-22 18:58:52 -07002836 return OK;
2837}
2838
2839status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002840#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07002841 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07002842#endif
2843
Jeff Brown46b9ac02010-04-22 18:58:52 -07002844 { // acquire lock
2845 AutoMutex _l(mLock);
2846
Jeff Brown519e0242010-09-15 15:18:56 -07002847 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002848 if (connectionIndex < 0) {
2849 LOGW("Attempted to unregister already unregistered input channel '%s'",
2850 inputChannel->getName().string());
2851 return BAD_VALUE;
2852 }
2853
2854 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2855 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2856
2857 connection->status = Connection::STATUS_ZOMBIE;
2858
Jeff Brownb88102f2010-09-08 11:49:43 -07002859 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2860 if (mMonitoringChannels[i] == inputChannel) {
2861 mMonitoringChannels.removeAt(i);
2862 break;
2863 }
2864 }
2865
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002866 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07002867
Jeff Brown7fbdc842010-06-17 20:52:56 -07002868 nsecs_t currentTime = now();
Jeff Brownb6997262010-10-08 22:31:17 -07002869 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002870
2871 runCommandsLockedInterruptible();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002872 } // release lock
2873
Jeff Brown46b9ac02010-04-22 18:58:52 -07002874 // Wake the poll loop because removing the connection may have changed the current
2875 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002876 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002877 return OK;
2878}
2879
Jeff Brown519e0242010-09-15 15:18:56 -07002880ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07002881 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2882 if (connectionIndex >= 0) {
2883 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2884 if (connection->inputChannel.get() == inputChannel.get()) {
2885 return connectionIndex;
2886 }
2887 }
2888
2889 return -1;
2890}
2891
Jeff Brown46b9ac02010-04-22 18:58:52 -07002892void InputDispatcher::activateConnectionLocked(Connection* connection) {
2893 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2894 if (mActiveConnections.itemAt(i) == connection) {
2895 return;
2896 }
2897 }
2898 mActiveConnections.add(connection);
2899}
2900
2901void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2902 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2903 if (mActiveConnections.itemAt(i) == connection) {
2904 mActiveConnections.removeAt(i);
2905 return;
2906 }
2907 }
2908}
2909
Jeff Brown9c3cda02010-06-15 01:31:58 -07002910void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002911 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002912}
2913
Jeff Brown9c3cda02010-06-15 01:31:58 -07002914void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002915 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002916}
2917
Jeff Brown9c3cda02010-06-15 01:31:58 -07002918void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002919 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002920 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2921 connection->getInputChannelName());
2922
Jeff Brown9c3cda02010-06-15 01:31:58 -07002923 CommandEntry* commandEntry = postCommandLocked(
2924 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002925 commandEntry->connection = connection;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002926}
2927
Jeff Brown519e0242010-09-15 15:18:56 -07002928void InputDispatcher::onANRLocked(
2929 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2930 nsecs_t eventTime, nsecs_t waitStartTime) {
2931 LOGI("Application is not responding: %s. "
2932 "%01.1fms since event, %01.1fms since wait started",
2933 getApplicationWindowLabelLocked(application, window).string(),
2934 (currentTime - eventTime) / 1000000.0,
2935 (currentTime - waitStartTime) / 1000000.0);
2936
2937 CommandEntry* commandEntry = postCommandLocked(
2938 & InputDispatcher::doNotifyANRLockedInterruptible);
2939 if (application) {
2940 commandEntry->inputApplicationHandle = application->handle;
2941 }
2942 if (window) {
2943 commandEntry->inputChannel = window->inputChannel;
2944 }
2945}
2946
Jeff Brownb88102f2010-09-08 11:49:43 -07002947void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2948 CommandEntry* commandEntry) {
2949 mLock.unlock();
2950
2951 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2952
2953 mLock.lock();
2954}
2955
Jeff Brown9c3cda02010-06-15 01:31:58 -07002956void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2957 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002958 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07002959
Jeff Brown7fbdc842010-06-17 20:52:56 -07002960 if (connection->status != Connection::STATUS_ZOMBIE) {
2961 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002962
Jeff Brown7fbdc842010-06-17 20:52:56 -07002963 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2964
2965 mLock.lock();
2966 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07002967}
2968
Jeff Brown519e0242010-09-15 15:18:56 -07002969void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07002970 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07002971 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002972
Jeff Brown519e0242010-09-15 15:18:56 -07002973 nsecs_t newTimeout = mPolicy->notifyANR(
2974 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002975
Jeff Brown519e0242010-09-15 15:18:56 -07002976 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002977
Jeff Brown519e0242010-09-15 15:18:56 -07002978 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002979}
2980
Jeff Brownb88102f2010-09-08 11:49:43 -07002981void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2982 CommandEntry* commandEntry) {
2983 KeyEntry* entry = commandEntry->keyEntry;
2984 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2985 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2986 entry->downTime, entry->eventTime);
2987
2988 mLock.unlock();
2989
2990 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2991 & mReusableKeyEvent, entry->policyFlags);
2992
2993 mLock.lock();
2994
2995 entry->interceptKeyResult = consumed
2996 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2997 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2998 mAllocator.releaseKeyEntry(entry);
2999}
3000
3001void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3002 mLock.unlock();
3003
Jeff Brown01ce2e92010-09-26 22:20:12 -07003004 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07003005
3006 mLock.lock();
3007}
3008
Jeff Brown519e0242010-09-15 15:18:56 -07003009void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3010 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3011 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07003012}
3013
3014void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f48712010-10-01 17:46:21 -07003015 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003016 dumpDispatchStateLocked(dump);
3017}
3018
Jeff Brown9c3cda02010-06-15 01:31:58 -07003019
Jeff Brown519e0242010-09-15 15:18:56 -07003020// --- InputDispatcher::Queue ---
3021
3022template <typename T>
3023uint32_t InputDispatcher::Queue<T>::count() const {
3024 uint32_t result = 0;
3025 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3026 result += 1;
3027 }
3028 return result;
3029}
3030
3031
Jeff Brown46b9ac02010-04-22 18:58:52 -07003032// --- InputDispatcher::Allocator ---
3033
3034InputDispatcher::Allocator::Allocator() {
3035}
3036
Jeff Brown01ce2e92010-09-26 22:20:12 -07003037InputDispatcher::InjectionState*
3038InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3039 InjectionState* injectionState = mInjectionStatePool.alloc();
3040 injectionState->refCount = 1;
3041 injectionState->injectorPid = injectorPid;
3042 injectionState->injectorUid = injectorUid;
3043 injectionState->injectionIsAsync = false;
3044 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3045 injectionState->pendingForegroundDispatches = 0;
3046 return injectionState;
3047}
3048
Jeff Brown7fbdc842010-06-17 20:52:56 -07003049void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brownb6997262010-10-08 22:31:17 -07003050 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003051 entry->type = type;
3052 entry->refCount = 1;
3053 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07003054 entry->eventTime = eventTime;
Jeff Brownb6997262010-10-08 22:31:17 -07003055 entry->policyFlags = policyFlags;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003056 entry->injectionState = NULL;
3057}
3058
3059void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3060 if (entry->injectionState) {
3061 releaseInjectionState(entry->injectionState);
3062 entry->injectionState = NULL;
3063 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07003064}
3065
Jeff Brown46b9ac02010-04-22 18:58:52 -07003066InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07003067InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003068 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003069 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003070 return entry;
3071}
3072
Jeff Brown7fbdc842010-06-17 20:52:56 -07003073InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07003074 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003075 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3076 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003077 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003078 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003079
3080 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003081 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003082 entry->action = action;
3083 entry->flags = flags;
3084 entry->keyCode = keyCode;
3085 entry->scanCode = scanCode;
3086 entry->metaState = metaState;
3087 entry->repeatCount = repeatCount;
3088 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003089 entry->syntheticRepeat = false;
3090 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003091 return entry;
3092}
3093
Jeff Brown7fbdc842010-06-17 20:52:56 -07003094InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07003095 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003096 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3097 nsecs_t downTime, uint32_t pointerCount,
3098 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003099 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003100 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003101
3102 entry->eventTime = eventTime;
3103 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003104 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003105 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07003106 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003107 entry->metaState = metaState;
3108 entry->edgeFlags = edgeFlags;
3109 entry->xPrecision = xPrecision;
3110 entry->yPrecision = yPrecision;
3111 entry->downTime = downTime;
3112 entry->pointerCount = pointerCount;
3113 entry->firstSample.eventTime = eventTime;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003114 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003115 entry->lastSample = & entry->firstSample;
3116 for (uint32_t i = 0; i < pointerCount; i++) {
3117 entry->pointerIds[i] = pointerIds[i];
3118 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3119 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07003120 return entry;
3121}
3122
3123InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07003124 EventEntry* eventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07003125 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003126 DispatchEntry* entry = mDispatchEntryPool.alloc();
3127 entry->eventEntry = eventEntry;
3128 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07003129 entry->targetFlags = targetFlags;
3130 entry->xOffset = xOffset;
3131 entry->yOffset = yOffset;
Jeff Brownb88102f2010-09-08 11:49:43 -07003132 entry->inProgress = false;
3133 entry->headMotionSample = NULL;
3134 entry->tailMotionSample = NULL;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003135 return entry;
3136}
3137
Jeff Brown9c3cda02010-06-15 01:31:58 -07003138InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3139 CommandEntry* entry = mCommandEntryPool.alloc();
3140 entry->command = command;
3141 return entry;
3142}
3143
Jeff Brown01ce2e92010-09-26 22:20:12 -07003144void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3145 injectionState->refCount -= 1;
3146 if (injectionState->refCount == 0) {
3147 mInjectionStatePool.free(injectionState);
3148 } else {
3149 assert(injectionState->refCount > 0);
3150 }
3151}
3152
Jeff Brown46b9ac02010-04-22 18:58:52 -07003153void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3154 switch (entry->type) {
3155 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3156 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3157 break;
3158 case EventEntry::TYPE_KEY:
3159 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3160 break;
3161 case EventEntry::TYPE_MOTION:
3162 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3163 break;
3164 default:
3165 assert(false);
3166 break;
3167 }
3168}
3169
3170void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3171 ConfigurationChangedEntry* entry) {
3172 entry->refCount -= 1;
3173 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003174 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003175 mConfigurationChangeEntryPool.free(entry);
3176 } else {
3177 assert(entry->refCount > 0);
3178 }
3179}
3180
3181void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3182 entry->refCount -= 1;
3183 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003184 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003185 mKeyEntryPool.free(entry);
3186 } else {
3187 assert(entry->refCount > 0);
3188 }
3189}
3190
3191void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3192 entry->refCount -= 1;
3193 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003194 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003195 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3196 MotionSample* next = sample->next;
3197 mMotionSamplePool.free(sample);
3198 sample = next;
3199 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07003200 mMotionEntryPool.free(entry);
3201 } else {
3202 assert(entry->refCount > 0);
3203 }
3204}
3205
3206void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3207 releaseEventEntry(entry->eventEntry);
3208 mDispatchEntryPool.free(entry);
3209}
3210
Jeff Brown9c3cda02010-06-15 01:31:58 -07003211void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3212 mCommandEntryPool.free(entry);
3213}
3214
Jeff Brown46b9ac02010-04-22 18:58:52 -07003215void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003216 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003217 MotionSample* sample = mMotionSamplePool.alloc();
3218 sample->eventTime = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003219 uint32_t pointerCount = motionEntry->pointerCount;
3220 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003221 sample->pointerCoords[i] = pointerCoords[i];
3222 }
3223
3224 sample->next = NULL;
3225 motionEntry->lastSample->next = sample;
3226 motionEntry->lastSample = sample;
3227}
3228
Jeff Brown01ce2e92010-09-26 22:20:12 -07003229void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3230 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003231
Jeff Brown01ce2e92010-09-26 22:20:12 -07003232 keyEntry->dispatchInProgress = false;
3233 keyEntry->syntheticRepeat = false;
3234 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003235}
3236
3237
Jeff Brownae9fc032010-08-18 15:51:08 -07003238// --- InputDispatcher::MotionEntry ---
3239
3240uint32_t InputDispatcher::MotionEntry::countSamples() const {
3241 uint32_t count = 1;
3242 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3243 count += 1;
3244 }
3245 return count;
3246}
3247
Jeff Brownb88102f2010-09-08 11:49:43 -07003248
3249// --- InputDispatcher::InputState ---
3250
Jeff Brownb6997262010-10-08 22:31:17 -07003251InputDispatcher::InputState::InputState() {
Jeff Brownb88102f2010-09-08 11:49:43 -07003252}
3253
3254InputDispatcher::InputState::~InputState() {
3255}
3256
3257bool InputDispatcher::InputState::isNeutral() const {
3258 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3259}
3260
Jeff Brownb88102f2010-09-08 11:49:43 -07003261InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3262 const EventEntry* entry) {
3263 switch (entry->type) {
3264 case EventEntry::TYPE_KEY:
3265 return trackKey(static_cast<const KeyEntry*>(entry));
3266
3267 case EventEntry::TYPE_MOTION:
3268 return trackMotion(static_cast<const MotionEntry*>(entry));
3269
3270 default:
3271 return CONSISTENT;
3272 }
3273}
3274
3275InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3276 const KeyEntry* entry) {
3277 int32_t action = entry->action;
3278 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3279 KeyMemento& memento = mKeyMementos.editItemAt(i);
3280 if (memento.deviceId == entry->deviceId
3281 && memento.source == entry->source
3282 && memento.keyCode == entry->keyCode
3283 && memento.scanCode == entry->scanCode) {
3284 switch (action) {
3285 case AKEY_EVENT_ACTION_UP:
3286 mKeyMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003287 return CONSISTENT;
3288
3289 case AKEY_EVENT_ACTION_DOWN:
3290 return TOLERABLE;
3291
3292 default:
3293 return BROKEN;
3294 }
3295 }
3296 }
3297
3298 switch (action) {
3299 case AKEY_EVENT_ACTION_DOWN: {
3300 mKeyMementos.push();
3301 KeyMemento& memento = mKeyMementos.editTop();
3302 memento.deviceId = entry->deviceId;
3303 memento.source = entry->source;
3304 memento.keyCode = entry->keyCode;
3305 memento.scanCode = entry->scanCode;
3306 memento.downTime = entry->downTime;
3307 return CONSISTENT;
3308 }
3309
3310 default:
3311 return BROKEN;
3312 }
3313}
3314
3315InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3316 const MotionEntry* entry) {
3317 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3318 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3319 MotionMemento& memento = mMotionMementos.editItemAt(i);
3320 if (memento.deviceId == entry->deviceId
3321 && memento.source == entry->source) {
3322 switch (action) {
3323 case AMOTION_EVENT_ACTION_UP:
3324 case AMOTION_EVENT_ACTION_CANCEL:
3325 mMotionMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003326 return CONSISTENT;
3327
3328 case AMOTION_EVENT_ACTION_DOWN:
3329 return TOLERABLE;
3330
3331 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3332 if (entry->pointerCount == memento.pointerCount + 1) {
3333 memento.setPointers(entry);
3334 return CONSISTENT;
3335 }
3336 return BROKEN;
3337
3338 case AMOTION_EVENT_ACTION_POINTER_UP:
3339 if (entry->pointerCount == memento.pointerCount - 1) {
3340 memento.setPointers(entry);
3341 return CONSISTENT;
3342 }
3343 return BROKEN;
3344
3345 case AMOTION_EVENT_ACTION_MOVE:
3346 if (entry->pointerCount == memento.pointerCount) {
3347 return CONSISTENT;
3348 }
3349 return BROKEN;
3350
3351 default:
3352 return BROKEN;
3353 }
3354 }
3355 }
3356
3357 switch (action) {
3358 case AMOTION_EVENT_ACTION_DOWN: {
3359 mMotionMementos.push();
3360 MotionMemento& memento = mMotionMementos.editTop();
3361 memento.deviceId = entry->deviceId;
3362 memento.source = entry->source;
3363 memento.xPrecision = entry->xPrecision;
3364 memento.yPrecision = entry->yPrecision;
3365 memento.downTime = entry->downTime;
3366 memento.setPointers(entry);
3367 return CONSISTENT;
3368 }
3369
3370 default:
3371 return BROKEN;
3372 }
3373}
3374
3375void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3376 pointerCount = entry->pointerCount;
3377 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3378 pointerIds[i] = entry->pointerIds[i];
3379 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3380 }
3381}
3382
Jeff Brownb6997262010-10-08 22:31:17 -07003383void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3384 Allocator* allocator, Vector<EventEntry*>& outEvents,
3385 CancelationOptions options) {
3386 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003387 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brownb6997262010-10-08 22:31:17 -07003388 if (shouldCancelEvent(memento.source, options)) {
3389 outEvents.push(allocator->obtainKeyEntry(currentTime,
3390 memento.deviceId, memento.source, 0,
3391 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3392 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3393 mKeyMementos.removeAt(i);
3394 } else {
3395 i += 1;
3396 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003397 }
3398
3399 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3400 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brownb6997262010-10-08 22:31:17 -07003401 if (shouldCancelEvent(memento.source, options)) {
3402 outEvents.push(allocator->obtainMotionEntry(currentTime,
3403 memento.deviceId, memento.source, 0,
3404 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3405 memento.xPrecision, memento.yPrecision, memento.downTime,
3406 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3407 mMotionMementos.removeAt(i);
3408 } else {
3409 i += 1;
3410 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003411 }
3412}
3413
3414void InputDispatcher::InputState::clear() {
3415 mKeyMementos.clear();
3416 mMotionMementos.clear();
Jeff Brownb6997262010-10-08 22:31:17 -07003417}
3418
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003419void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3420 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3421 const MotionMemento& memento = mMotionMementos.itemAt(i);
3422 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3423 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3424 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3425 if (memento.deviceId == otherMemento.deviceId
3426 && memento.source == otherMemento.source) {
3427 other.mMotionMementos.removeAt(j);
3428 } else {
3429 j += 1;
3430 }
3431 }
3432 other.mMotionMementos.push(memento);
3433 }
3434 }
3435}
3436
Jeff Brownb6997262010-10-08 22:31:17 -07003437bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3438 CancelationOptions options) {
3439 switch (options) {
3440 case CANCEL_POINTER_EVENTS:
3441 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3442 case CANCEL_NON_POINTER_EVENTS:
3443 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3444 default:
3445 return true;
3446 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003447}
3448
3449
Jeff Brown46b9ac02010-04-22 18:58:52 -07003450// --- InputDispatcher::Connection ---
3451
3452InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3453 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown519e0242010-09-15 15:18:56 -07003454 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003455}
3456
3457InputDispatcher::Connection::~Connection() {
3458}
3459
3460status_t InputDispatcher::Connection::initialize() {
3461 return inputPublisher.initialize();
3462}
3463
Jeff Brown9c3cda02010-06-15 01:31:58 -07003464const char* InputDispatcher::Connection::getStatusLabel() const {
3465 switch (status) {
3466 case STATUS_NORMAL:
3467 return "NORMAL";
3468
3469 case STATUS_BROKEN:
3470 return "BROKEN";
3471
Jeff Brown9c3cda02010-06-15 01:31:58 -07003472 case STATUS_ZOMBIE:
3473 return "ZOMBIE";
3474
3475 default:
3476 return "UNKNOWN";
3477 }
3478}
3479
Jeff Brown46b9ac02010-04-22 18:58:52 -07003480InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3481 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07003482 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3483 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003484 if (dispatchEntry->eventEntry == eventEntry) {
3485 return dispatchEntry;
3486 }
3487 }
3488 return NULL;
3489}
3490
Jeff Brownb88102f2010-09-08 11:49:43 -07003491
Jeff Brown9c3cda02010-06-15 01:31:58 -07003492// --- InputDispatcher::CommandEntry ---
3493
Jeff Brownb88102f2010-09-08 11:49:43 -07003494InputDispatcher::CommandEntry::CommandEntry() :
3495 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003496}
3497
3498InputDispatcher::CommandEntry::~CommandEntry() {
3499}
3500
Jeff Brown46b9ac02010-04-22 18:58:52 -07003501
Jeff Brown01ce2e92010-09-26 22:20:12 -07003502// --- InputDispatcher::TouchState ---
3503
3504InputDispatcher::TouchState::TouchState() :
3505 down(false), split(false) {
3506}
3507
3508InputDispatcher::TouchState::~TouchState() {
3509}
3510
3511void InputDispatcher::TouchState::reset() {
3512 down = false;
3513 split = false;
3514 windows.clear();
3515}
3516
3517void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3518 down = other.down;
3519 split = other.split;
3520 windows.clear();
3521 windows.appendVector(other.windows);
3522}
3523
3524void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3525 int32_t targetFlags, BitSet32 pointerIds) {
3526 if (targetFlags & InputTarget::FLAG_SPLIT) {
3527 split = true;
3528 }
3529
3530 for (size_t i = 0; i < windows.size(); i++) {
3531 TouchedWindow& touchedWindow = windows.editItemAt(i);
3532 if (touchedWindow.window == window) {
3533 touchedWindow.targetFlags |= targetFlags;
3534 touchedWindow.pointerIds.value |= pointerIds.value;
3535 return;
3536 }
3537 }
3538
3539 windows.push();
3540
3541 TouchedWindow& touchedWindow = windows.editTop();
3542 touchedWindow.window = window;
3543 touchedWindow.targetFlags = targetFlags;
3544 touchedWindow.pointerIds = pointerIds;
3545 touchedWindow.channel = window->inputChannel;
3546}
3547
3548void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3549 for (size_t i = 0 ; i < windows.size(); ) {
3550 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3551 windows.removeAt(i);
3552 } else {
3553 i += 1;
3554 }
3555 }
3556}
3557
3558const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3559 for (size_t i = 0; i < windows.size(); i++) {
3560 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3561 return windows[i].window;
3562 }
3563 }
3564 return NULL;
3565}
3566
3567
Jeff Brown46b9ac02010-04-22 18:58:52 -07003568// --- InputDispatcherThread ---
3569
3570InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3571 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3572}
3573
3574InputDispatcherThread::~InputDispatcherThread() {
3575}
3576
3577bool InputDispatcherThread::threadLoop() {
3578 mDispatcher->dispatchOnce();
3579 return true;
3580}
3581
3582} // namespace android