blob: 6ba19d79f929805c737cc0dad6f8c4a4355d7e8f [file] [log] [blame]
Jeff Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-04-22 18:58:52 -070043
44#include <stddef.h>
45#include <unistd.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070046#include <errno.h>
47#include <limits.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070048
Jeff Brownf2f487182010-10-01 17:46:21 -070049#define INDENT " "
50#define INDENT2 " "
51
Jeff Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-04-22 18:58:52 -0700196
197 while (mConnectionsByReceiveFd.size() != 0) {
198 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
199 }
Jeff Brown46b9ac0a2010-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 Brown46b9ac0a2010-04-22 18:58:52 -0700205
Jeff Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-04-22 18:58:52 -0700213 }
Jeff Brown46b9ac0a2010-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 Brownb931a1b2010-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 Brownb931a1b2010-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 Brownb931a1b2010-10-11 14:20:19 -0700434#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown3122e442010-10-11 23:32:49 -0700435 LOGD("Dropped event because policy consumed it.");
Jeff Brownb931a1b2010-10-11 14:20:19 -0700436#endif
Jeff Brown3122e442010-10-11 23:32:49 -0700437 reason = "inbound event was dropped because the policy consumed it";
Jeff Brownb6997262010-10-08 22:31:17 -0700438 break;
439 case DROP_REASON_DISABLED:
440 LOGI("Dropped event because input dispatch is disabled.");
441 reason = "inbound event was dropped because input dispatch is disabled";
442 break;
443 case DROP_REASON_APP_SWITCH:
444 LOGI("Dropped event because of pending overdue app switch.");
445 reason = "inbound event was dropped because of pending overdue app switch";
446 break;
447 default:
448 assert(false);
449 return;
450 }
451
452 switch (entry->type) {
453 case EventEntry::TYPE_KEY:
454 synthesizeCancelationEventsForAllConnectionsLocked(
455 InputState::CANCEL_NON_POINTER_EVENTS, reason);
456 break;
457 case EventEntry::TYPE_MOTION: {
458 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
459 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
460 synthesizeCancelationEventsForAllConnectionsLocked(
461 InputState::CANCEL_POINTER_EVENTS, reason);
462 } else {
463 synthesizeCancelationEventsForAllConnectionsLocked(
464 InputState::CANCEL_NON_POINTER_EVENTS, reason);
465 }
466 break;
467 }
468 }
469}
470
471bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700472 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
473}
474
Jeff Brownb6997262010-10-08 22:31:17 -0700475bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
476 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
477 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Brownb931a1b2010-10-11 14:20:19 -0700478 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brownb6997262010-10-08 22:31:17 -0700479 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
480}
481
Jeff Brownb88102f2010-09-08 11:49:43 -0700482bool InputDispatcher::isAppSwitchPendingLocked() {
483 return mAppSwitchDueTime != LONG_LONG_MAX;
484}
485
Jeff Brownb88102f2010-09-08 11:49:43 -0700486void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
487 mAppSwitchDueTime = LONG_LONG_MAX;
488
489#if DEBUG_APP_SWITCH
490 if (handled) {
491 LOGD("App switch has arrived.");
492 } else {
493 LOGD("App switch was abandoned.");
494 }
495#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700496}
497
Jeff Brown9c3cda02010-06-15 01:31:58 -0700498bool InputDispatcher::runCommandsLockedInterruptible() {
499 if (mCommandQueue.isEmpty()) {
500 return false;
501 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700502
Jeff Brown9c3cda02010-06-15 01:31:58 -0700503 do {
504 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
505
506 Command command = commandEntry->command;
507 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
508
Jeff Brown7fbdc842010-06-17 20:52:56 -0700509 commandEntry->connection.clear();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700510 mAllocator.releaseCommandEntry(commandEntry);
511 } while (! mCommandQueue.isEmpty());
512 return true;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700513}
514
Jeff Brown9c3cda02010-06-15 01:31:58 -0700515InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
516 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
517 mCommandQueue.enqueueAtTail(commandEntry);
518 return commandEntry;
519}
520
Jeff Brownb88102f2010-09-08 11:49:43 -0700521void InputDispatcher::drainInboundQueueLocked() {
522 while (! mInboundQueue.isEmpty()) {
523 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700524 releaseInboundEventLocked(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700525 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700526}
527
Jeff Brown54a18252010-09-16 14:07:33 -0700528void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700529 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700530 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700531 mPendingEvent = NULL;
532 }
533}
534
Jeff Brown54a18252010-09-16 14:07:33 -0700535void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700536 InjectionState* injectionState = entry->injectionState;
537 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700538#if DEBUG_DISPATCH_CYCLE
Jeff Brown01ce2e92010-09-26 22:20:12 -0700539 LOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700540#endif
541 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
542 }
543 mAllocator.releaseEventEntry(entry);
544}
545
Jeff Brownb88102f2010-09-08 11:49:43 -0700546void InputDispatcher::resetKeyRepeatLocked() {
547 if (mKeyRepeatState.lastKeyEntry) {
548 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
549 mKeyRepeatState.lastKeyEntry = NULL;
550 }
551}
552
553InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brownb21fb102010-09-07 10:44:57 -0700554 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown349703e2010-06-22 01:27:15 -0700555 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
556
Jeff Brown349703e2010-06-22 01:27:15 -0700557 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brownb931a1b2010-10-11 14:20:19 -0700558 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
559 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700560 if (entry->refCount == 1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700561 mAllocator.recycleKeyEntry(entry);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700562 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700563 entry->policyFlags = policyFlags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700564 entry->repeatCount += 1;
565 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700566 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700567 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700568 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700569 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700570
571 mKeyRepeatState.lastKeyEntry = newEntry;
572 mAllocator.releaseKeyEntry(entry);
573
574 entry = newEntry;
575 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700576 entry->syntheticRepeat = true;
577
578 // Increment reference count since we keep a reference to the event in
579 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
580 entry->refCount += 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700581
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700582 if (entry->repeatCount == 1) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700583 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700584 }
585
Jeff Brownb21fb102010-09-07 10:44:57 -0700586 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700587 return entry;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700588}
589
Jeff Brownb88102f2010-09-08 11:49:43 -0700590bool InputDispatcher::dispatchConfigurationChangedLocked(
591 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700592#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownb88102f2010-09-08 11:49:43 -0700593 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
594#endif
595
596 // Reset key repeating in case a keyboard device was added or removed or something.
597 resetKeyRepeatLocked();
598
599 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
600 CommandEntry* commandEntry = postCommandLocked(
601 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
602 commandEntry->eventTime = entry->eventTime;
603 return true;
604}
605
606bool InputDispatcher::dispatchKeyLocked(
607 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brownb931a1b2010-10-11 14:20:19 -0700608 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brown54a18252010-09-16 14:07:33 -0700609 // Give the policy a chance to intercept the key.
610 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Brownb931a1b2010-10-11 14:20:19 -0700611 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brown54a18252010-09-16 14:07:33 -0700612 CommandEntry* commandEntry = postCommandLocked(
613 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Brownb931a1b2010-10-11 14:20:19 -0700614 if (mFocusedWindow) {
Jeff Brown54a18252010-09-16 14:07:33 -0700615 commandEntry->inputChannel = mFocusedWindow->inputChannel;
616 }
617 commandEntry->keyEntry = entry;
618 entry->refCount += 1;
619 return false; // wait for the command to run
620 } else {
621 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
622 }
623 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Brownb931a1b2010-10-11 14:20:19 -0700624 if (*dropReason == DROP_REASON_NOT_DROPPED) {
625 *dropReason = DROP_REASON_POLICY;
626 }
Jeff Brown54a18252010-09-16 14:07:33 -0700627 }
628
629 // Clean up if dropping the event.
Jeff Brownb931a1b2010-10-11 14:20:19 -0700630 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700631 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700632 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
633 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700634 return true;
635 }
636
Jeff Brownb88102f2010-09-08 11:49:43 -0700637 // Preprocessing.
638 if (! entry->dispatchInProgress) {
639 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
640
641 if (entry->repeatCount == 0
642 && entry->action == AKEY_EVENT_ACTION_DOWN
Jeff Brownb931a1b2010-10-11 14:20:19 -0700643 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
644 && !entry->isInjected()) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700645 if (mKeyRepeatState.lastKeyEntry
646 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
647 // We have seen two identical key downs in a row which indicates that the device
648 // driver is automatically generating key repeats itself. We take note of the
649 // repeat here, but we disable our own next key repeat timer since it is clear that
650 // we will not need to synthesize key repeats ourselves.
651 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
652 resetKeyRepeatLocked();
653 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
654 } else {
655 // Not a repeat. Save key down state in case we do see a repeat later.
656 resetKeyRepeatLocked();
657 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
658 }
659 mKeyRepeatState.lastKeyEntry = entry;
660 entry->refCount += 1;
661 } else if (! entry->syntheticRepeat) {
662 resetKeyRepeatLocked();
663 }
664
665 entry->dispatchInProgress = true;
Jeff Brown54a18252010-09-16 14:07:33 -0700666 resetTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700667 }
668
669 // Identify targets.
670 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700671 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
672 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700673 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
674 return false;
675 }
676
677 setInjectionResultLocked(entry, injectionResult);
678 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
679 return true;
680 }
681
682 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700683 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700684 }
685
686 // Dispatch the key.
687 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
688
689 // Poke user activity.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700690 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
691 pokeUserActivityLocked(entry->eventTime, POWER_MANAGER_BUTTON_EVENT);
692 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700693 return true;
694}
695
696void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
697#if DEBUG_OUTBOUND_EVENT_DETAILS
698 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
699 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
700 "downTime=%lld",
701 prefix,
702 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
703 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
704 entry->downTime);
705#endif
706}
707
708bool InputDispatcher::dispatchMotionLocked(
Jeff Brownb931a1b2010-10-11 14:20:19 -0700709 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brown54a18252010-09-16 14:07:33 -0700710 // Clean up if dropping the event.
Jeff Brownb931a1b2010-10-11 14:20:19 -0700711 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700712 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700713 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
714 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700715 return true;
716 }
717
Jeff Brownb88102f2010-09-08 11:49:43 -0700718 // Preprocessing.
719 if (! entry->dispatchInProgress) {
720 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
721
722 entry->dispatchInProgress = true;
Jeff Brown54a18252010-09-16 14:07:33 -0700723 resetTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700724 }
725
726 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
727
728 // Identify targets.
729 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700730 int32_t injectionResult;
731 if (isPointerEvent) {
732 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700733 injectionResult = findTouchedWindowTargetsLocked(currentTime,
734 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700735 } else {
736 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700737 injectionResult = findFocusedWindowTargetsLocked(currentTime,
738 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700739 }
740 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
741 return false;
742 }
743
744 setInjectionResultLocked(entry, injectionResult);
745 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
746 return true;
747 }
748
749 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700750 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700751 }
752
753 // Dispatch the motion.
754 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
755
756 // Poke user activity.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700757 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
758 int32_t eventType;
759 if (isPointerEvent) {
760 switch (entry->action) {
761 case AMOTION_EVENT_ACTION_DOWN:
Jeff Brownb88102f2010-09-08 11:49:43 -0700762 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700763 break;
764 case AMOTION_EVENT_ACTION_UP:
765 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
766 break;
767 default:
768 if (entry->eventTime - entry->downTime >= EVENT_IGNORE_DURATION) {
769 eventType = POWER_MANAGER_TOUCH_EVENT;
770 } else {
771 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
772 }
773 break;
Jeff Brownb88102f2010-09-08 11:49:43 -0700774 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700775 } else {
776 eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brownb88102f2010-09-08 11:49:43 -0700777 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700778 pokeUserActivityLocked(entry->eventTime, eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700779 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700780 return true;
781}
782
783
784void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
785#if DEBUG_OUTBOUND_EVENT_DETAILS
786 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700787 "action=0x%x, flags=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700788 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700789 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700790 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
791 entry->action, entry->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700792 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
793 entry->downTime);
794
795 // Print the most recent sample that we have available, this may change due to batching.
796 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700797 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700798 for (; sample->next != NULL; sample = sample->next) {
799 sampleCount += 1;
800 }
801 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -0700802 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700803 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700804 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700805 i, entry->pointerIds[i],
Jeff Brown8d608662010-08-30 03:02:23 -0700806 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
807 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
808 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
809 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
810 sample->pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700811 }
812
813 // Keep in mind that due to batching, it is possible for the number of samples actually
814 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700815 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700816 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
817 }
818#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700819}
820
821void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
822 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
823#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -0700824 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700825 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700826 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700827#endif
828
Jeff Brown9c3cda02010-06-15 01:31:58 -0700829 assert(eventEntry->dispatchInProgress); // should already have been set to true
830
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700831 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
832 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
833
Jeff Brown519e0242010-09-15 15:18:56 -0700834 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700835 if (connectionIndex >= 0) {
836 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700837 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700838 resumeWithAppendedMotionSample);
839 } else {
Jeff Brownb6997262010-10-08 22:31:17 -0700840#if DEBUG_FOCUS
841 LOGD("Dropping event delivery to target with channel '%s' because it "
842 "is no longer registered with the input dispatcher.",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700843 inputTarget.inputChannel->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -0700844#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700845 }
846 }
847}
848
Jeff Brown54a18252010-09-16 14:07:33 -0700849void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700850 mCurrentInputTargetsValid = false;
851 mCurrentInputTargets.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700852 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
853}
854
Jeff Brown01ce2e92010-09-26 22:20:12 -0700855void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700856 mCurrentInputTargetsValid = true;
857}
858
859int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
860 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
861 nsecs_t* nextWakeupTime) {
862 if (application == NULL && window == NULL) {
863 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
864#if DEBUG_FOCUS
865 LOGD("Waiting for system to become ready for input.");
866#endif
867 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
868 mInputTargetWaitStartTime = currentTime;
869 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
870 mInputTargetWaitTimeoutExpired = false;
871 }
872 } else {
873 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
874#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700875 LOGD("Waiting for application to become ready for input: %s",
876 getApplicationWindowLabelLocked(application, window).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700877#endif
878 nsecs_t timeout = window ? window->dispatchingTimeout :
879 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
880
881 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
882 mInputTargetWaitStartTime = currentTime;
883 mInputTargetWaitTimeoutTime = currentTime + timeout;
884 mInputTargetWaitTimeoutExpired = false;
885 }
886 }
887
888 if (mInputTargetWaitTimeoutExpired) {
889 return INPUT_EVENT_INJECTION_TIMED_OUT;
890 }
891
892 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown519e0242010-09-15 15:18:56 -0700893 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700894
895 // Force poll loop to wake up immediately on next iteration once we get the
896 // ANR response back from the policy.
897 *nextWakeupTime = LONG_LONG_MIN;
898 return INPUT_EVENT_INJECTION_PENDING;
899 } else {
900 // Force poll loop to wake up when timeout is due.
901 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
902 *nextWakeupTime = mInputTargetWaitTimeoutTime;
903 }
904 return INPUT_EVENT_INJECTION_PENDING;
905 }
906}
907
Jeff Brown519e0242010-09-15 15:18:56 -0700908void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
909 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700910 if (newTimeout > 0) {
911 // Extend the timeout.
912 mInputTargetWaitTimeoutTime = now() + newTimeout;
913 } else {
914 // Give up.
915 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -0700916
Jeff Brown01ce2e92010-09-26 22:20:12 -0700917 // Release the touch targets.
918 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -0700919
Jeff Brown519e0242010-09-15 15:18:56 -0700920 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -0700921 if (inputChannel.get()) {
922 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
923 if (connectionIndex >= 0) {
924 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brownb6997262010-10-08 22:31:17 -0700925 synthesizeCancelationEventsForConnectionLocked(
926 connection, InputState::CANCEL_ALL_EVENTS,
927 "application not responding");
Jeff Browndc3e0052010-09-16 11:02:16 -0700928 }
Jeff Brown519e0242010-09-15 15:18:56 -0700929 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700930 }
931}
932
Jeff Brown519e0242010-09-15 15:18:56 -0700933nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -0700934 nsecs_t currentTime) {
935 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
936 return currentTime - mInputTargetWaitStartTime;
937 }
938 return 0;
939}
940
941void InputDispatcher::resetANRTimeoutsLocked() {
942#if DEBUG_FOCUS
943 LOGD("Resetting ANR timeouts.");
944#endif
945
Jeff Brownb88102f2010-09-08 11:49:43 -0700946 // Reset input target wait timeout.
947 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
948}
949
Jeff Brown01ce2e92010-09-26 22:20:12 -0700950int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
951 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700952 mCurrentInputTargets.clear();
953
954 int32_t injectionResult;
955
956 // If there is no currently focused window and no focused application
957 // then drop the event.
958 if (! mFocusedWindow) {
959 if (mFocusedApplication) {
960#if DEBUG_FOCUS
961 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -0700962 "focused application that may eventually add a window: %s.",
963 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700964#endif
965 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
966 mFocusedApplication, NULL, nextWakeupTime);
967 goto Unresponsive;
968 }
969
970 LOGI("Dropping event because there is no focused window or focused application.");
971 injectionResult = INPUT_EVENT_INJECTION_FAILED;
972 goto Failed;
973 }
974
975 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700976 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700977 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
978 goto Failed;
979 }
980
981 // If the currently focused window is paused then keep waiting.
982 if (mFocusedWindow->paused) {
983#if DEBUG_FOCUS
984 LOGD("Waiting because focused window is paused.");
985#endif
986 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
987 mFocusedApplication, mFocusedWindow, nextWakeupTime);
988 goto Unresponsive;
989 }
990
Jeff Brown519e0242010-09-15 15:18:56 -0700991 // If the currently focused window is still working on previous events then keep waiting.
992 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
993#if DEBUG_FOCUS
994 LOGD("Waiting because focused window still processing previous input.");
995#endif
996 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
997 mFocusedApplication, mFocusedWindow, nextWakeupTime);
998 goto Unresponsive;
999 }
1000
Jeff Brownb88102f2010-09-08 11:49:43 -07001001 // Success! Output targets.
1002 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001003 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001004
1005 // Done.
1006Failed:
1007Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001008 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1009 updateDispatchStatisticsLocked(currentTime, entry,
1010 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001011#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -07001012 LOGD("findFocusedWindow finished: injectionResult=%d, "
1013 "timeSpendWaitingForApplication=%0.1fms",
1014 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001015#endif
1016 return injectionResult;
1017}
1018
Jeff Brown01ce2e92010-09-26 22:20:12 -07001019int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1020 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001021 enum InjectionPermission {
1022 INJECTION_PERMISSION_UNKNOWN,
1023 INJECTION_PERMISSION_GRANTED,
1024 INJECTION_PERMISSION_DENIED
1025 };
1026
Jeff Brownb88102f2010-09-08 11:49:43 -07001027 mCurrentInputTargets.clear();
1028
1029 nsecs_t startTime = now();
1030
1031 // For security reasons, we defer updating the touch state until we are sure that
1032 // event injection will be allowed.
1033 //
1034 // FIXME In the original code, screenWasOff could never be set to true.
1035 // The reason is that the POLICY_FLAG_WOKE_HERE
1036 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1037 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1038 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1039 // events upon which no preprocessing took place. So policyFlags was always 0.
1040 // In the new native input dispatcher we're a bit more careful about event
1041 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1042 // Unfortunately we obtain undesirable behavior.
1043 //
1044 // Here's what happens:
1045 //
1046 // When the device dims in anticipation of going to sleep, touches
1047 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1048 // the device to brighten and reset the user activity timer.
1049 // Touches on other windows (such as the launcher window)
1050 // are dropped. Then after a moment, the device goes to sleep. Oops.
1051 //
1052 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1053 // instead of POLICY_FLAG_WOKE_HERE...
1054 //
1055 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1056
1057 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001058 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001059
1060 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001061 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1062 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1063 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1064 mTempTouchState.reset();
1065 mTempTouchState.down = true;
1066 } else {
1067 mTempTouchState.copyFrom(mTouchState);
1068 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001069
Jeff Brown01ce2e92010-09-26 22:20:12 -07001070 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1071 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1072 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1073 /* Case 1: New splittable pointer going down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001074
Jeff Brown01ce2e92010-09-26 22:20:12 -07001075 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1076 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1077 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1078 const InputWindow* newTouchedWindow = NULL;
1079 const InputWindow* topErrorWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07001080
1081 // Traverse windows from front to back to find touched window and outside targets.
1082 size_t numWindows = mWindows.size();
1083 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001084 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001085 int32_t flags = window->layoutParamsFlags;
1086
1087 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1088 if (! topErrorWindow) {
1089 topErrorWindow = window;
1090 }
1091 }
1092
1093 if (window->visible) {
1094 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1095 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1096 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1097 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1098 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1099 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001100 }
1101 break; // found touched window, exit window loop
1102 }
1103 }
1104
Jeff Brown01ce2e92010-09-26 22:20:12 -07001105 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1106 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001107 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1108 if (isWindowObscuredAtPointLocked(window, x, y)) {
1109 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1110 }
1111
1112 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001113 }
1114 }
1115 }
1116
1117 // If there is an error window but it is not taking focus (typically because
1118 // it is invisible) then wait for it. Any other focused window may in
1119 // fact be in ANR state.
1120 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1121#if DEBUG_FOCUS
1122 LOGD("Waiting because system error window is pending.");
1123#endif
1124 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1125 NULL, NULL, nextWakeupTime);
1126 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1127 goto Unresponsive;
1128 }
1129
Jeff Brown01ce2e92010-09-26 22:20:12 -07001130 // Figure out whether splitting will be allowed for this window.
Jeff Brownaeec2bf2010-09-28 13:24:41 -07001131 if (newTouchedWindow
1132 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001133 // New window supports splitting.
1134 isSplit = true;
1135 } else if (isSplit) {
1136 // New window does not support splitting but we have already split events.
1137 // Assign the pointer to the first foreground window we find.
1138 // (May be NULL which is why we put this code block before the next check.)
1139 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1140 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001141
Jeff Brownb88102f2010-09-08 11:49:43 -07001142 // If we did not find a touched window then fail.
1143 if (! newTouchedWindow) {
1144 if (mFocusedApplication) {
1145#if DEBUG_FOCUS
1146 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001147 "focused application that may eventually add a new window: %s.",
1148 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001149#endif
1150 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1151 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001152 goto Unresponsive;
1153 }
1154
1155 LOGI("Dropping event because there is no touched window or focused application.");
1156 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001157 goto Failed;
1158 }
1159
Jeff Brown19dfc832010-10-05 12:26:23 -07001160 // Set target flags.
1161 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1162 if (isSplit) {
1163 targetFlags |= InputTarget::FLAG_SPLIT;
1164 }
1165 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1166 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1167 }
1168
Jeff Brown01ce2e92010-09-26 22:20:12 -07001169 // Update the temporary touch state.
1170 BitSet32 pointerIds;
1171 if (isSplit) {
1172 uint32_t pointerId = entry->pointerIds[pointerIndex];
1173 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001174 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001175 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001176 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001177 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001178
1179 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001180 if (! mTempTouchState.down) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001181 LOGI("Dropping event because the pointer is not down.");
1182 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001183 goto Failed;
1184 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001185 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001186
Jeff Brown01ce2e92010-09-26 22:20:12 -07001187 // Check permission to inject into all touched foreground windows and ensure there
1188 // is at least one touched foreground window.
1189 {
1190 bool haveForegroundWindow = false;
1191 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1192 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1193 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1194 haveForegroundWindow = true;
1195 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1196 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1197 injectionPermission = INJECTION_PERMISSION_DENIED;
1198 goto Failed;
1199 }
1200 }
1201 }
1202 if (! haveForegroundWindow) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001203#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown01ce2e92010-09-26 22:20:12 -07001204 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001205#endif
1206 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001207 goto Failed;
1208 }
1209
Jeff Brown01ce2e92010-09-26 22:20:12 -07001210 // Permission granted to injection into all touched foreground windows.
1211 injectionPermission = INJECTION_PERMISSION_GRANTED;
1212 }
Jeff Brown519e0242010-09-15 15:18:56 -07001213
Jeff Brown01ce2e92010-09-26 22:20:12 -07001214 // Ensure all touched foreground windows are ready for new input.
1215 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1216 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1217 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1218 // If the touched window is paused then keep waiting.
1219 if (touchedWindow.window->paused) {
1220#if DEBUG_INPUT_DISPATCHER_POLICY
1221 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001222#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001223 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1224 NULL, touchedWindow.window, nextWakeupTime);
1225 goto Unresponsive;
1226 }
1227
1228 // If the touched window is still working on previous events then keep waiting.
1229 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1230#if DEBUG_FOCUS
1231 LOGD("Waiting because touched window still processing previous input.");
1232#endif
1233 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1234 NULL, touchedWindow.window, nextWakeupTime);
1235 goto Unresponsive;
1236 }
1237 }
1238 }
1239
1240 // If this is the first pointer going down and the touched window has a wallpaper
1241 // then also add the touched wallpaper windows so they are locked in for the duration
1242 // of the touch gesture.
1243 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1244 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1245 if (foregroundWindow->hasWallpaper) {
1246 for (size_t i = 0; i < mWindows.size(); i++) {
1247 const InputWindow* window = & mWindows[i];
1248 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001249 mTempTouchState.addOrUpdateWindow(window,
1250 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001251 }
1252 }
1253 }
1254 }
1255
Jeff Brownb88102f2010-09-08 11:49:43 -07001256 // Success! Output targets.
1257 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001258
Jeff Brown01ce2e92010-09-26 22:20:12 -07001259 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1260 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1261 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1262 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001263 }
1264
Jeff Brown01ce2e92010-09-26 22:20:12 -07001265 // Drop the outside touch window since we will not care about them in the next iteration.
1266 mTempTouchState.removeOutsideTouchWindows();
1267
Jeff Brownb88102f2010-09-08 11:49:43 -07001268Failed:
1269 // Check injection permission once and for all.
1270 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001271 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001272 injectionPermission = INJECTION_PERMISSION_GRANTED;
1273 } else {
1274 injectionPermission = INJECTION_PERMISSION_DENIED;
1275 }
1276 }
1277
1278 // Update final pieces of touch state if the injector had permission.
1279 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001280 if (maskedAction == AMOTION_EVENT_ACTION_UP
1281 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1282 // All pointers up or canceled.
1283 mTempTouchState.reset();
1284 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1285 // First pointer went down.
1286 if (mTouchState.down) {
Jeff Brownb6997262010-10-08 22:31:17 -07001287#if DEBUG_FOCUS
1288 LOGD("Pointer down received while already down.");
1289#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001290 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001291 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1292 // One pointer went up.
1293 if (isSplit) {
1294 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1295 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001296
Jeff Brown01ce2e92010-09-26 22:20:12 -07001297 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1298 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1299 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1300 touchedWindow.pointerIds.clearBit(pointerId);
1301 if (touchedWindow.pointerIds.isEmpty()) {
1302 mTempTouchState.windows.removeAt(i);
1303 continue;
1304 }
1305 }
1306 i += 1;
1307 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001308 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001309 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001310
1311 // Save changes to touch state.
1312 mTouchState.copyFrom(mTempTouchState);
Jeff Brownb88102f2010-09-08 11:49:43 -07001313 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001314#if DEBUG_FOCUS
1315 LOGD("Not updating touch focus because injection was denied.");
1316#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001317 }
1318
1319Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001320 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1321 updateDispatchStatisticsLocked(currentTime, entry,
1322 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001323#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001324 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1325 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001326 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001327#endif
1328 return injectionResult;
1329}
1330
Jeff Brown01ce2e92010-09-26 22:20:12 -07001331void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1332 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001333 mCurrentInputTargets.push();
1334
1335 InputTarget& target = mCurrentInputTargets.editTop();
1336 target.inputChannel = window->inputChannel;
1337 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001338 target.xOffset = - window->frameLeft;
1339 target.yOffset = - window->frameTop;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001340 target.windowType = window->layoutParamsType;
1341 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001342}
1343
1344void InputDispatcher::addMonitoringTargetsLocked() {
1345 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1346 mCurrentInputTargets.push();
1347
1348 InputTarget& target = mCurrentInputTargets.editTop();
1349 target.inputChannel = mMonitoringChannels[i];
1350 target.flags = 0;
Jeff Brownb88102f2010-09-08 11:49:43 -07001351 target.xOffset = 0;
1352 target.yOffset = 0;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001353 target.windowType = InputWindow::TYPE_SYSTEM_OVERLAY;
Jeff Brownb88102f2010-09-08 11:49:43 -07001354 }
1355}
1356
1357bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001358 const InjectionState* injectionState) {
1359 if (injectionState
Jeff Brownb6997262010-10-08 22:31:17 -07001360 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1361 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1362 if (window) {
1363 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1364 "with input channel %s owned by uid %d",
1365 injectionState->injectorPid, injectionState->injectorUid,
1366 window->inputChannel->getName().string(),
1367 window->ownerUid);
1368 } else {
1369 LOGW("Permission denied: injecting event from pid %d uid %d",
1370 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001371 }
Jeff Brownb6997262010-10-08 22:31:17 -07001372 return false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001373 }
1374 return true;
1375}
1376
Jeff Brown19dfc832010-10-05 12:26:23 -07001377bool InputDispatcher::isWindowObscuredAtPointLocked(
1378 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07001379 size_t numWindows = mWindows.size();
1380 for (size_t i = 0; i < numWindows; i++) {
1381 const InputWindow* other = & mWindows.itemAt(i);
1382 if (other == window) {
1383 break;
1384 }
Jeff Brown19dfc832010-10-05 12:26:23 -07001385 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001386 return true;
1387 }
1388 }
1389 return false;
1390}
1391
Jeff Brown519e0242010-09-15 15:18:56 -07001392bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1393 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1394 if (connectionIndex >= 0) {
1395 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1396 return connection->outboundQueue.isEmpty();
1397 } else {
1398 return true;
1399 }
1400}
1401
1402String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1403 const InputWindow* window) {
1404 if (application) {
1405 if (window) {
1406 String8 label(application->name);
1407 label.append(" - ");
1408 label.append(window->name);
1409 return label;
1410 } else {
1411 return application->name;
1412 }
1413 } else if (window) {
1414 return window->name;
1415 } else {
1416 return String8("<unknown application or window>");
1417 }
1418}
1419
Jeff Brown01ce2e92010-09-26 22:20:12 -07001420bool InputDispatcher::shouldPokeUserActivityForCurrentInputTargetsLocked() {
1421 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
1422 if (mCurrentInputTargets[i].windowType == InputWindow::TYPE_KEYGUARD) {
1423 return false;
1424 }
1425 }
1426 return true;
1427}
1428
1429void InputDispatcher::pokeUserActivityLocked(nsecs_t eventTime, int32_t eventType) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001430 CommandEntry* commandEntry = postCommandLocked(
1431 & InputDispatcher::doPokeUserActivityLockedInterruptible);
1432 commandEntry->eventTime = eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001433 commandEntry->userActivityEventType = eventType;
1434}
1435
Jeff Brown7fbdc842010-06-17 20:52:56 -07001436void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1437 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001438 bool resumeWithAppendedMotionSample) {
1439#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001440 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001441 "xOffset=%f, yOffset=%f, "
1442 "windowType=%d, pointerIds=0x%x, "
1443 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001444 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001445 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001446 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001447 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001448#endif
1449
Jeff Brown01ce2e92010-09-26 22:20:12 -07001450 // Make sure we are never called for streaming when splitting across multiple windows.
1451 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1452 assert(! (resumeWithAppendedMotionSample && isSplit));
1453
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001454 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001455 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001456 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb6997262010-10-08 22:31:17 -07001457#if DEBUG_DISPATCH_CYCLE
1458 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001459 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brownb6997262010-10-08 22:31:17 -07001460#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001461 return;
1462 }
1463
Jeff Brown01ce2e92010-09-26 22:20:12 -07001464 // Split a motion event if needed.
1465 if (isSplit) {
1466 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1467
1468 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1469 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1470 MotionEntry* splitMotionEntry = splitMotionEvent(
1471 originalMotionEntry, inputTarget->pointerIds);
1472#if DEBUG_FOCUS
1473 LOGD("channel '%s' ~ Split motion event.",
1474 connection->getInputChannelName());
1475 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1476#endif
1477 eventEntry = splitMotionEntry;
1478 }
1479 }
1480
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001481 // Resume the dispatch cycle with a freshly appended motion sample.
1482 // First we check that the last dispatch entry in the outbound queue is for the same
1483 // motion event to which we appended the motion sample. If we find such a dispatch
1484 // entry, and if it is currently in progress then we try to stream the new sample.
1485 bool wasEmpty = connection->outboundQueue.isEmpty();
1486
1487 if (! wasEmpty && resumeWithAppendedMotionSample) {
1488 DispatchEntry* motionEventDispatchEntry =
1489 connection->findQueuedDispatchEntryForEvent(eventEntry);
1490 if (motionEventDispatchEntry) {
1491 // If the dispatch entry is not in progress, then we must be busy dispatching an
1492 // earlier event. Not a problem, the motion event is on the outbound queue and will
1493 // be dispatched later.
1494 if (! motionEventDispatchEntry->inProgress) {
1495#if DEBUG_BATCHING
1496 LOGD("channel '%s' ~ Not streaming because the motion event has "
1497 "not yet been dispatched. "
1498 "(Waiting for earlier events to be consumed.)",
1499 connection->getInputChannelName());
1500#endif
1501 return;
1502 }
1503
1504 // If the dispatch entry is in progress but it already has a tail of pending
1505 // motion samples, then it must mean that the shared memory buffer filled up.
1506 // Not a problem, when this dispatch cycle is finished, we will eventually start
1507 // a new dispatch cycle to process the tail and that tail includes the newly
1508 // appended motion sample.
1509 if (motionEventDispatchEntry->tailMotionSample) {
1510#if DEBUG_BATCHING
1511 LOGD("channel '%s' ~ Not streaming because no new samples can "
1512 "be appended to the motion event in this dispatch cycle. "
1513 "(Waiting for next dispatch cycle to start.)",
1514 connection->getInputChannelName());
1515#endif
1516 return;
1517 }
1518
1519 // The dispatch entry is in progress and is still potentially open for streaming.
1520 // Try to stream the new motion sample. This might fail if the consumer has already
1521 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001522 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1523 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001524 status_t status = connection->inputPublisher.appendMotionSample(
1525 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1526 if (status == OK) {
1527#if DEBUG_BATCHING
1528 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1529 connection->getInputChannelName());
1530#endif
1531 return;
1532 }
1533
1534#if DEBUG_BATCHING
1535 if (status == NO_MEMORY) {
1536 LOGD("channel '%s' ~ Could not append motion sample to currently "
1537 "dispatched move event because the shared memory buffer is full. "
1538 "(Waiting for next dispatch cycle to start.)",
1539 connection->getInputChannelName());
1540 } else if (status == status_t(FAILED_TRANSACTION)) {
1541 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001542 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001543 "(Waiting for next dispatch cycle to start.)",
1544 connection->getInputChannelName());
1545 } else {
1546 LOGD("channel '%s' ~ Could not append motion sample to currently "
1547 "dispatched move event due to an error, status=%d. "
1548 "(Waiting for next dispatch cycle to start.)",
1549 connection->getInputChannelName(), status);
1550 }
1551#endif
1552 // Failed to stream. Start a new tail of pending motion samples to dispatch
1553 // in the next cycle.
1554 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1555 return;
1556 }
1557 }
1558
1559 // This is a new event.
1560 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001561 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown519e0242010-09-15 15:18:56 -07001562 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1563 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001564 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001565 }
1566
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001567 // Handle the case where we could not stream a new motion sample because the consumer has
1568 // already consumed the motion event (otherwise the corresponding dispatch entry would
1569 // still be in the outbound queue for this connection). We set the head motion sample
1570 // to the list starting with the newly appended motion sample.
1571 if (resumeWithAppendedMotionSample) {
1572#if DEBUG_BATCHING
1573 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1574 "that cannot be streamed because the motion event has already been consumed.",
1575 connection->getInputChannelName());
1576#endif
1577 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1578 dispatchEntry->headMotionSample = appendedMotionSample;
1579 }
1580
1581 // Enqueue the dispatch entry.
1582 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1583
1584 // If the outbound queue was previously empty, start the dispatch cycle going.
1585 if (wasEmpty) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001586 activateConnectionLocked(connection.get());
Jeff Brown519e0242010-09-15 15:18:56 -07001587 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001588 }
1589}
1590
Jeff Brown7fbdc842010-06-17 20:52:56 -07001591void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001592 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001593#if DEBUG_DISPATCH_CYCLE
1594 LOGD("channel '%s' ~ startDispatchCycle",
1595 connection->getInputChannelName());
1596#endif
1597
1598 assert(connection->status == Connection::STATUS_NORMAL);
1599 assert(! connection->outboundQueue.isEmpty());
1600
Jeff Brownb88102f2010-09-08 11:49:43 -07001601 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001602 assert(! dispatchEntry->inProgress);
1603
Jeff Brownb88102f2010-09-08 11:49:43 -07001604 // Mark the dispatch entry as in progress.
1605 dispatchEntry->inProgress = true;
1606
1607 // Update the connection's input state.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001608 EventEntry* eventEntry = dispatchEntry->eventEntry;
1609 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001610
1611#if FILTER_INPUT_EVENTS
1612 // Filter out inconsistent sequences of input events.
1613 // The input system may drop or inject events in a way that could violate implicit
1614 // invariants on input state and potentially cause an application to crash
1615 // or think that a key or pointer is stuck down. Technically we make no guarantees
1616 // of consistency but it would be nice to improve on this where possible.
1617 // XXX: This code is a proof of concept only. Not ready for prime time.
1618 if (consistency == InputState::TOLERABLE) {
1619#if DEBUG_DISPATCH_CYCLE
1620 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1621 "current input state but that is likely to be tolerated by the application.",
1622 connection->getInputChannelName());
1623#endif
1624 } else if (consistency == InputState::BROKEN) {
1625 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1626 "current input state and that is likely to cause the application to crash.",
1627 connection->getInputChannelName());
1628 startNextDispatchCycleLocked(currentTime, connection);
1629 return;
1630 }
1631#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001632
1633 // Publish the event.
1634 status_t status;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001635 switch (eventEntry->type) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001636 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001637 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001638
1639 // Apply target flags.
1640 int32_t action = keyEntry->action;
1641 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001642
1643 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001644 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001645 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1646 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1647 keyEntry->eventTime);
1648
1649 if (status) {
1650 LOGE("channel '%s' ~ Could not publish key event, "
1651 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001652 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001653 return;
1654 }
1655 break;
1656 }
1657
1658 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001659 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001660
1661 // Apply target flags.
1662 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001663 int32_t flags = motionEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001664 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001665 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001666 }
Jeff Brown85a31762010-09-01 17:01:00 -07001667 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1668 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1669 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001670
1671 // If headMotionSample is non-NULL, then it points to the first new sample that we
1672 // were unable to dispatch during the previous cycle so we resume dispatching from
1673 // that point in the list of motion samples.
1674 // Otherwise, we just start from the first sample of the motion event.
1675 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1676 if (! firstMotionSample) {
1677 firstMotionSample = & motionEntry->firstSample;
1678 }
1679
Jeff Brownd3616592010-07-16 17:21:06 -07001680 // Set the X and Y offset depending on the input source.
1681 float xOffset, yOffset;
1682 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1683 xOffset = dispatchEntry->xOffset;
1684 yOffset = dispatchEntry->yOffset;
1685 } else {
1686 xOffset = 0.0f;
1687 yOffset = 0.0f;
1688 }
1689
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001690 // Publish the motion event and the first motion sample.
1691 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07001692 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownd3616592010-07-16 17:21:06 -07001693 xOffset, yOffset,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001694 motionEntry->xPrecision, motionEntry->yPrecision,
1695 motionEntry->downTime, firstMotionSample->eventTime,
1696 motionEntry->pointerCount, motionEntry->pointerIds,
1697 firstMotionSample->pointerCoords);
1698
1699 if (status) {
1700 LOGE("channel '%s' ~ Could not publish motion event, "
1701 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001702 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001703 return;
1704 }
1705
1706 // Append additional motion samples.
1707 MotionSample* nextMotionSample = firstMotionSample->next;
1708 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1709 status = connection->inputPublisher.appendMotionSample(
1710 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1711 if (status == NO_MEMORY) {
1712#if DEBUG_DISPATCH_CYCLE
1713 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1714 "be sent in the next dispatch cycle.",
1715 connection->getInputChannelName());
1716#endif
1717 break;
1718 }
1719 if (status != OK) {
1720 LOGE("channel '%s' ~ Could not append motion sample "
1721 "for a reason other than out of memory, status=%d",
1722 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001723 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001724 return;
1725 }
1726 }
1727
1728 // Remember the next motion sample that we could not dispatch, in case we ran out
1729 // of space in the shared memory buffer.
1730 dispatchEntry->tailMotionSample = nextMotionSample;
1731 break;
1732 }
1733
1734 default: {
1735 assert(false);
1736 }
1737 }
1738
1739 // Send the dispatch signal.
1740 status = connection->inputPublisher.sendDispatchSignal();
1741 if (status) {
1742 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1743 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001744 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001745 return;
1746 }
1747
1748 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001749 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001750 connection->lastDispatchTime = currentTime;
1751
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001752 // Notify other system components.
1753 onDispatchCycleStartedLocked(currentTime, connection);
1754}
1755
Jeff Brown7fbdc842010-06-17 20:52:56 -07001756void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1757 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001758#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001759 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001760 "%01.1fms since dispatch",
1761 connection->getInputChannelName(),
1762 connection->getEventLatencyMillis(currentTime),
1763 connection->getDispatchLatencyMillis(currentTime));
1764#endif
1765
Jeff Brown9c3cda02010-06-15 01:31:58 -07001766 if (connection->status == Connection::STATUS_BROKEN
1767 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001768 return;
1769 }
1770
Jeff Brown519e0242010-09-15 15:18:56 -07001771 // Notify other system components.
1772 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001773
1774 // Reset the publisher since the event has been consumed.
1775 // We do this now so that the publisher can release some of its internal resources
1776 // while waiting for the next dispatch cycle to begin.
1777 status_t status = connection->inputPublisher.reset();
1778 if (status) {
1779 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1780 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001781 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001782 return;
1783 }
1784
Jeff Brownb88102f2010-09-08 11:49:43 -07001785 startNextDispatchCycleLocked(currentTime, connection);
1786}
1787
1788void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1789 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001790 // Start the next dispatch cycle for this connection.
1791 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001792 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001793 if (dispatchEntry->inProgress) {
1794 // Finish or resume current event in progress.
1795 if (dispatchEntry->tailMotionSample) {
1796 // We have a tail of undispatched motion samples.
1797 // Reuse the same DispatchEntry and start a new cycle.
1798 dispatchEntry->inProgress = false;
1799 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1800 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07001801 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001802 return;
1803 }
1804 // Finished.
1805 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07001806 if (dispatchEntry->hasForegroundTarget()) {
1807 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001808 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001809 mAllocator.releaseDispatchEntry(dispatchEntry);
1810 } else {
1811 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07001812 // progress event, which means we actually aborted it.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001813 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07001814 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001815 return;
1816 }
1817 }
1818
1819 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07001820 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001821}
1822
Jeff Brownb6997262010-10-08 22:31:17 -07001823void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1824 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001825#if DEBUG_DISPATCH_CYCLE
Jeff Brownb6997262010-10-08 22:31:17 -07001826 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001827 connection->getInputChannelName(), toString(broken));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001828#endif
1829
Jeff Brownb88102f2010-09-08 11:49:43 -07001830 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07001831 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001832
Jeff Brownb6997262010-10-08 22:31:17 -07001833 // The connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07001834 // Ignore already broken or zombie connections.
Jeff Brownb6997262010-10-08 22:31:17 -07001835 if (connection->status == Connection::STATUS_NORMAL) {
1836 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001837
Jeff Brownb6997262010-10-08 22:31:17 -07001838 // Notify other system components.
1839 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001840 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001841}
1842
Jeff Brown519e0242010-09-15 15:18:56 -07001843void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1844 while (! connection->outboundQueue.isEmpty()) {
1845 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1846 if (dispatchEntry->hasForegroundTarget()) {
1847 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001848 }
1849 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001850 }
1851
Jeff Brown519e0242010-09-15 15:18:56 -07001852 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07001853}
1854
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001855int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001856 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1857
1858 { // acquire lock
1859 AutoMutex _l(d->mLock);
1860
1861 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1862 if (connectionIndex < 0) {
1863 LOGE("Received spurious receive callback for unknown input channel. "
1864 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001865 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001866 }
1867
Jeff Brown7fbdc842010-06-17 20:52:56 -07001868 nsecs_t currentTime = now();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001869
1870 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001871 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001872 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1873 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brownb6997262010-10-08 22:31:17 -07001874 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001875 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001876 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001877 }
1878
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001879 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001880 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1881 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001882 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001883 }
1884
1885 status_t status = connection->inputPublisher.receiveFinishedSignal();
1886 if (status) {
1887 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1888 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001889 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001890 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001891 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001892 }
1893
Jeff Brown7fbdc842010-06-17 20:52:56 -07001894 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001895 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001896 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001897 } // release lock
1898}
1899
Jeff Brownb6997262010-10-08 22:31:17 -07001900void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1901 InputState::CancelationOptions options, const char* reason) {
1902 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1903 synthesizeCancelationEventsForConnectionLocked(
1904 mConnectionsByReceiveFd.valueAt(i), options, reason);
1905 }
1906}
1907
1908void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1909 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1910 const char* reason) {
1911 ssize_t index = getConnectionIndexLocked(channel);
1912 if (index >= 0) {
1913 synthesizeCancelationEventsForConnectionLocked(
1914 mConnectionsByReceiveFd.valueAt(index), options, reason);
1915 }
1916}
1917
1918void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1919 const sp<Connection>& connection, InputState::CancelationOptions options,
1920 const char* reason) {
1921 nsecs_t currentTime = now();
1922
1923 mTempCancelationEvents.clear();
1924 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1925 mTempCancelationEvents, options);
1926
1927 if (! mTempCancelationEvents.isEmpty()
1928 && connection->status != Connection::STATUS_BROKEN) {
1929#if DEBUG_OUTBOUND_EVENT_DETAILS
1930 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1931 "with reality: %s, options=%d.",
1932 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1933#endif
1934 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1935 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1936 switch (cancelationEventEntry->type) {
1937 case EventEntry::TYPE_KEY:
1938 logOutboundKeyDetailsLocked("cancel - ",
1939 static_cast<KeyEntry*>(cancelationEventEntry));
1940 break;
1941 case EventEntry::TYPE_MOTION:
1942 logOutboundMotionDetailsLocked("cancel - ",
1943 static_cast<MotionEntry*>(cancelationEventEntry));
1944 break;
1945 }
1946
1947 int32_t xOffset, yOffset;
1948 const InputWindow* window = getWindowLocked(connection->inputChannel);
1949 if (window) {
1950 xOffset = -window->frameLeft;
1951 yOffset = -window->frameTop;
1952 } else {
1953 xOffset = 0;
1954 yOffset = 0;
1955 }
1956
1957 DispatchEntry* cancelationDispatchEntry =
1958 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1959 0, xOffset, yOffset);
1960 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1961
1962 mAllocator.releaseEventEntry(cancelationEventEntry);
1963 }
1964
1965 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1966 startDispatchCycleLocked(currentTime, connection);
1967 }
1968 }
1969}
1970
Jeff Brown01ce2e92010-09-26 22:20:12 -07001971InputDispatcher::MotionEntry*
1972InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1973 assert(pointerIds.value != 0);
1974
1975 uint32_t splitPointerIndexMap[MAX_POINTERS];
1976 int32_t splitPointerIds[MAX_POINTERS];
1977 PointerCoords splitPointerCoords[MAX_POINTERS];
1978
1979 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1980 uint32_t splitPointerCount = 0;
1981
1982 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1983 originalPointerIndex++) {
1984 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1985 if (pointerIds.hasBit(pointerId)) {
1986 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1987 splitPointerIds[splitPointerCount] = pointerId;
1988 splitPointerCoords[splitPointerCount] =
1989 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1990 splitPointerCount += 1;
1991 }
1992 }
1993 assert(splitPointerCount == pointerIds.count());
1994
1995 int32_t action = originalMotionEntry->action;
1996 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1997 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
1998 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1999 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2000 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2001 if (pointerIds.hasBit(pointerId)) {
2002 if (pointerIds.count() == 1) {
2003 // The first/last pointer went down/up.
2004 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2005 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07002006 } else {
2007 // A secondary pointer went down/up.
2008 uint32_t splitPointerIndex = 0;
2009 while (pointerId != splitPointerIds[splitPointerIndex]) {
2010 splitPointerIndex += 1;
2011 }
2012 action = maskedAction | (splitPointerIndex
2013 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002014 }
2015 } else {
2016 // An unrelated pointer changed.
2017 action = AMOTION_EVENT_ACTION_MOVE;
2018 }
2019 }
2020
2021 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2022 originalMotionEntry->eventTime,
2023 originalMotionEntry->deviceId,
2024 originalMotionEntry->source,
2025 originalMotionEntry->policyFlags,
2026 action,
2027 originalMotionEntry->flags,
2028 originalMotionEntry->metaState,
2029 originalMotionEntry->edgeFlags,
2030 originalMotionEntry->xPrecision,
2031 originalMotionEntry->yPrecision,
2032 originalMotionEntry->downTime,
2033 splitPointerCount, splitPointerIds, splitPointerCoords);
2034
2035 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2036 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2037 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2038 splitPointerIndex++) {
2039 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2040 splitPointerCoords[splitPointerIndex] =
2041 originalMotionSample->pointerCoords[originalPointerIndex];
2042 }
2043
2044 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2045 splitPointerCoords);
2046 }
2047
2048 return splitMotionEntry;
2049}
2050
Jeff Brown9c3cda02010-06-15 01:31:58 -07002051void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002052#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07002053 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002054#endif
2055
Jeff Brownb88102f2010-09-08 11:49:43 -07002056 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002057 { // acquire lock
2058 AutoMutex _l(mLock);
2059
Jeff Brown7fbdc842010-06-17 20:52:56 -07002060 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07002061 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002062 } // release lock
2063
Jeff Brownb88102f2010-09-08 11:49:43 -07002064 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002065 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002066 }
2067}
2068
Jeff Brownc5ed5912010-07-14 18:48:53 -07002069void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002070 uint32_t policyFlags, int32_t action, int32_t flags,
2071 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2072#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brownc5ed5912010-07-14 18:48:53 -07002073 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002074 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07002075 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002076 keyCode, scanCode, metaState, downTime);
2077#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002078 if (! validateKeyEvent(action)) {
2079 return;
2080 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002081
Jeff Brownb931a1b2010-10-11 14:20:19 -07002082 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002083 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2084 keyCode, scanCode, /*byref*/ policyFlags);
2085
Jeff Brownb88102f2010-09-08 11:49:43 -07002086 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002087 { // acquire lock
2088 AutoMutex _l(mLock);
2089
Jeff Brown7fbdc842010-06-17 20:52:56 -07002090 int32_t repeatCount = 0;
2091 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002092 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002093 metaState, repeatCount, downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002094
Jeff Brownb88102f2010-09-08 11:49:43 -07002095 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002096 } // release lock
2097
Jeff Brownb88102f2010-09-08 11:49:43 -07002098 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002099 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002100 }
2101}
2102
Jeff Brownc5ed5912010-07-14 18:48:53 -07002103void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002104 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002105 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2106 float xPrecision, float yPrecision, nsecs_t downTime) {
2107#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brownc5ed5912010-07-14 18:48:53 -07002108 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002109 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2110 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2111 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002112 xPrecision, yPrecision, downTime);
2113 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002114 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002115 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002116 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002117 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown8d608662010-08-30 03:02:23 -07002118 pointerCoords[i].pressure, pointerCoords[i].size,
2119 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2120 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2121 pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002122 }
2123#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002124 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2125 return;
2126 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002127
Jeff Brownb931a1b2010-10-11 14:20:19 -07002128 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002129 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2130
Jeff Brownb88102f2010-09-08 11:49:43 -07002131 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002132 { // acquire lock
2133 AutoMutex _l(mLock);
2134
2135 // Attempt batching and streaming of move events.
Jeff Brownc5ed5912010-07-14 18:48:53 -07002136 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002137 // BATCHING CASE
2138 //
2139 // Try to append a move sample to the tail of the inbound queue for this device.
2140 // Give up if we encounter a non-move motion event for this device since that
2141 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002142 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2143 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002144 if (entry->type != EventEntry::TYPE_MOTION) {
2145 // Keep looking for motion events.
2146 continue;
2147 }
2148
2149 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2150 if (motionEntry->deviceId != deviceId) {
2151 // Keep looking for this device.
2152 continue;
2153 }
2154
Jeff Brownc5ed5912010-07-14 18:48:53 -07002155 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown7fbdc842010-06-17 20:52:56 -07002156 || motionEntry->pointerCount != pointerCount
2157 || motionEntry->isInjected()) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002158 // Last motion event in the queue for this device is not compatible for
2159 // appending new samples. Stop here.
2160 goto NoBatchingOrStreaming;
2161 }
2162
2163 // The last motion event is a move and is compatible for appending.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002164 // Do the batching magic.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002165 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002166#if DEBUG_BATCHING
2167 LOGD("Appended motion sample onto batch for most recent "
2168 "motion event for this device in the inbound queue.");
2169#endif
Jeff Brown9c3cda02010-06-15 01:31:58 -07002170 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002171 }
2172
2173 // STREAMING CASE
2174 //
2175 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002176 // Search the outbound queue for the current foreground targets to find a dispatched
2177 // motion event that is still in progress. If found, then, appen the new sample to
2178 // that event and push it out to all current targets. The logic in
2179 // prepareDispatchCycleLocked takes care of the case where some targets may
2180 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002181 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002182 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2183 const InputTarget& inputTarget = mCurrentInputTargets[i];
2184 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2185 // Skip non-foreground targets. We only want to stream if there is at
2186 // least one foreground target whose dispatch is still in progress.
2187 continue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002188 }
Jeff Brown519e0242010-09-15 15:18:56 -07002189
2190 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2191 if (connectionIndex < 0) {
2192 // Connection must no longer be valid.
2193 continue;
2194 }
2195
2196 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2197 if (connection->outboundQueue.isEmpty()) {
2198 // This foreground target has an empty outbound queue.
2199 continue;
2200 }
2201
2202 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2203 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002204 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2205 || dispatchEntry->isSplit()) {
2206 // No motion event is being dispatched, or it is being split across
2207 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002208 continue;
2209 }
2210
2211 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2212 dispatchEntry->eventEntry);
2213 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2214 || motionEntry->deviceId != deviceId
2215 || motionEntry->pointerCount != pointerCount
2216 || motionEntry->isInjected()) {
2217 // The motion event is not compatible with this move.
2218 continue;
2219 }
2220
2221 // Hurray! This foreground target is currently dispatching a move event
2222 // that we can stream onto. Append the motion sample and resume dispatch.
2223 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2224#if DEBUG_BATCHING
2225 LOGD("Appended motion sample onto batch for most recently dispatched "
2226 "motion event for this device in the outbound queues. "
2227 "Attempting to stream the motion sample.");
2228#endif
2229 nsecs_t currentTime = now();
2230 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2231 true /*resumeWithAppendedMotionSample*/);
2232
2233 runCommandsLockedInterruptible();
2234 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002235 }
2236 }
2237
2238NoBatchingOrStreaming:;
2239 }
2240
2241 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002242 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002243 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002244 xPrecision, yPrecision, downTime,
2245 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002246
Jeff Brownb88102f2010-09-08 11:49:43 -07002247 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002248 } // release lock
2249
Jeff Brownb88102f2010-09-08 11:49:43 -07002250 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002251 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002252 }
2253}
2254
Jeff Brownb6997262010-10-08 22:31:17 -07002255void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2256 uint32_t policyFlags) {
2257#if DEBUG_INBOUND_EVENT_DETAILS
2258 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2259 switchCode, switchValue, policyFlags);
2260#endif
2261
Jeff Brownb931a1b2010-10-11 14:20:19 -07002262 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002263 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2264}
2265
Jeff Brown7fbdc842010-06-17 20:52:56 -07002266int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002267 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002268#if DEBUG_INBOUND_EVENT_DETAILS
2269 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002270 "syncMode=%d, timeoutMillis=%d",
2271 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002272#endif
2273
2274 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brownb931a1b2010-10-11 14:20:19 -07002275
2276 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2277 if (hasInjectionPermission(injectorPid, injectorUid)) {
2278 policyFlags |= POLICY_FLAG_TRUSTED;
2279 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002280
Jeff Brownb6997262010-10-08 22:31:17 -07002281 EventEntry* injectedEntry;
2282 switch (event->getType()) {
2283 case AINPUT_EVENT_TYPE_KEY: {
2284 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2285 int32_t action = keyEvent->getAction();
2286 if (! validateKeyEvent(action)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002287 return INPUT_EVENT_INJECTION_FAILED;
2288 }
2289
Jeff Brownb6997262010-10-08 22:31:17 -07002290 nsecs_t eventTime = keyEvent->getEventTime();
2291 int32_t deviceId = keyEvent->getDeviceId();
2292 int32_t flags = keyEvent->getFlags();
2293 int32_t keyCode = keyEvent->getKeyCode();
2294 int32_t scanCode = keyEvent->getScanCode();
Jeff Brownb931a1b2010-10-11 14:20:19 -07002295 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2296 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002297
Jeff Brownb6997262010-10-08 22:31:17 -07002298 mLock.lock();
2299 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2300 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2301 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2302 break;
2303 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002304
Jeff Brownb6997262010-10-08 22:31:17 -07002305 case AINPUT_EVENT_TYPE_MOTION: {
2306 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2307 int32_t action = motionEvent->getAction();
2308 size_t pointerCount = motionEvent->getPointerCount();
2309 const int32_t* pointerIds = motionEvent->getPointerIds();
2310 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2311 return INPUT_EVENT_INJECTION_FAILED;
2312 }
2313
2314 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brownb931a1b2010-10-11 14:20:19 -07002315 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002316
2317 mLock.lock();
2318 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2319 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2320 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2321 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2322 action, motionEvent->getFlags(),
2323 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2324 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2325 motionEvent->getDownTime(), uint32_t(pointerCount),
2326 pointerIds, samplePointerCoords);
2327 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2328 sampleEventTimes += 1;
2329 samplePointerCoords += pointerCount;
2330 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2331 }
2332 injectedEntry = motionEntry;
2333 break;
2334 }
2335
2336 default:
2337 LOGW("Cannot inject event of type %d", event->getType());
2338 return INPUT_EVENT_INJECTION_FAILED;
2339 }
2340
2341 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2342 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2343 injectionState->injectionIsAsync = true;
2344 }
2345
2346 injectionState->refCount += 1;
2347 injectedEntry->injectionState = injectionState;
2348
2349 bool needWake = enqueueInboundEventLocked(injectedEntry);
2350 mLock.unlock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002351
Jeff Brownb88102f2010-09-08 11:49:43 -07002352 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002353 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002354 }
2355
2356 int32_t injectionResult;
2357 { // acquire lock
2358 AutoMutex _l(mLock);
2359
Jeff Brown6ec402b2010-07-28 15:48:59 -07002360 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2361 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2362 } else {
2363 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002364 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002365 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2366 break;
2367 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002368
Jeff Brown7fbdc842010-06-17 20:52:56 -07002369 nsecs_t remainingTimeout = endTime - now();
2370 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002371#if DEBUG_INJECTION
2372 LOGD("injectInputEvent - Timed out waiting for injection result "
2373 "to become available.");
2374#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002375 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2376 break;
2377 }
2378
Jeff Brown6ec402b2010-07-28 15:48:59 -07002379 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2380 }
2381
2382 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2383 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002384 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002385#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002386 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002387 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002388#endif
2389 nsecs_t remainingTimeout = endTime - now();
2390 if (remainingTimeout <= 0) {
2391#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002392 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002393 "dispatches to finish.");
2394#endif
2395 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2396 break;
2397 }
2398
2399 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2400 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002401 }
2402 }
2403
Jeff Brown01ce2e92010-09-26 22:20:12 -07002404 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002405 } // release lock
2406
Jeff Brown6ec402b2010-07-28 15:48:59 -07002407#if DEBUG_INJECTION
2408 LOGD("injectInputEvent - Finished with result %d. "
2409 "injectorPid=%d, injectorUid=%d",
2410 injectionResult, injectorPid, injectorUid);
2411#endif
2412
Jeff Brown7fbdc842010-06-17 20:52:56 -07002413 return injectionResult;
2414}
2415
Jeff Brownb6997262010-10-08 22:31:17 -07002416bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2417 return injectorUid == 0
2418 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2419}
2420
Jeff Brown7fbdc842010-06-17 20:52:56 -07002421void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002422 InjectionState* injectionState = entry->injectionState;
2423 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002424#if DEBUG_INJECTION
2425 LOGD("Setting input event injection result to %d. "
2426 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002427 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002428#endif
2429
Jeff Brown01ce2e92010-09-26 22:20:12 -07002430 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002431 // Log the outcome since the injector did not wait for the injection result.
2432 switch (injectionResult) {
2433 case INPUT_EVENT_INJECTION_SUCCEEDED:
2434 LOGV("Asynchronous input event injection succeeded.");
2435 break;
2436 case INPUT_EVENT_INJECTION_FAILED:
2437 LOGW("Asynchronous input event injection failed.");
2438 break;
2439 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2440 LOGW("Asynchronous input event injection permission denied.");
2441 break;
2442 case INPUT_EVENT_INJECTION_TIMED_OUT:
2443 LOGW("Asynchronous input event injection timed out.");
2444 break;
2445 }
2446 }
2447
Jeff Brown01ce2e92010-09-26 22:20:12 -07002448 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002449 mInjectionResultAvailableCondition.broadcast();
2450 }
2451}
2452
Jeff Brown01ce2e92010-09-26 22:20:12 -07002453void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2454 InjectionState* injectionState = entry->injectionState;
2455 if (injectionState) {
2456 injectionState->pendingForegroundDispatches += 1;
2457 }
2458}
2459
Jeff Brown519e0242010-09-15 15:18:56 -07002460void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002461 InjectionState* injectionState = entry->injectionState;
2462 if (injectionState) {
2463 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002464
Jeff Brown01ce2e92010-09-26 22:20:12 -07002465 if (injectionState->pendingForegroundDispatches == 0) {
2466 mInjectionSyncFinishedCondition.broadcast();
2467 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002468 }
2469}
2470
Jeff Brown01ce2e92010-09-26 22:20:12 -07002471const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2472 for (size_t i = 0; i < mWindows.size(); i++) {
2473 const InputWindow* window = & mWindows[i];
2474 if (window->inputChannel == inputChannel) {
2475 return window;
2476 }
2477 }
2478 return NULL;
2479}
2480
Jeff Brownb88102f2010-09-08 11:49:43 -07002481void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2482#if DEBUG_FOCUS
2483 LOGD("setInputWindows");
2484#endif
2485 { // acquire lock
2486 AutoMutex _l(mLock);
2487
Jeff Brown01ce2e92010-09-26 22:20:12 -07002488 // Clear old window pointers.
Jeff Brownb6997262010-10-08 22:31:17 -07002489 sp<InputChannel> oldFocusedWindowChannel;
2490 if (mFocusedWindow) {
2491 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2492 mFocusedWindow = NULL;
2493 }
2494
Jeff Brownb88102f2010-09-08 11:49:43 -07002495 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002496
2497 // Loop over new windows and rebuild the necessary window pointers for
2498 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002499 mWindows.appendVector(inputWindows);
2500
2501 size_t numWindows = mWindows.size();
2502 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002503 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002504 if (window->hasFocus) {
2505 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002506 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002507 }
2508 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002509
Jeff Brownb6997262010-10-08 22:31:17 -07002510 if (oldFocusedWindowChannel != NULL) {
2511 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2512#if DEBUG_FOCUS
2513 LOGD("Focus left window: %s",
2514 oldFocusedWindowChannel->getName().string());
2515#endif
2516 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2517 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2518 oldFocusedWindowChannel.clear();
2519 }
2520 }
2521 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2522#if DEBUG_FOCUS
2523 LOGD("Focus entered window: %s",
2524 mFocusedWindow->inputChannel->getName().string());
2525#endif
2526 }
2527
Jeff Brown01ce2e92010-09-26 22:20:12 -07002528 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2529 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2530 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2531 if (window) {
2532 touchedWindow.window = window;
2533 i += 1;
2534 } else {
Jeff Brownb6997262010-10-08 22:31:17 -07002535#if DEBUG_FOCUS
2536 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2537#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002538 mTouchState.windows.removeAt(i);
Jeff Brownb6997262010-10-08 22:31:17 -07002539 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2540 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brown01ce2e92010-09-26 22:20:12 -07002541 }
2542 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002543
Jeff Brownb88102f2010-09-08 11:49:43 -07002544#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002545 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002546#endif
2547 } // release lock
2548
2549 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002550 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002551}
2552
2553void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2554#if DEBUG_FOCUS
2555 LOGD("setFocusedApplication");
2556#endif
2557 { // acquire lock
2558 AutoMutex _l(mLock);
2559
2560 releaseFocusedApplicationLocked();
2561
2562 if (inputApplication) {
2563 mFocusedApplicationStorage = *inputApplication;
2564 mFocusedApplication = & mFocusedApplicationStorage;
2565 }
2566
2567#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002568 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002569#endif
2570 } // release lock
2571
2572 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002573 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002574}
2575
2576void InputDispatcher::releaseFocusedApplicationLocked() {
2577 if (mFocusedApplication) {
2578 mFocusedApplication = NULL;
2579 mFocusedApplicationStorage.handle.clear();
2580 }
2581}
2582
2583void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2584#if DEBUG_FOCUS
2585 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2586#endif
2587
2588 bool changed;
2589 { // acquire lock
2590 AutoMutex _l(mLock);
2591
2592 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2593 if (mDispatchFrozen && ! frozen) {
2594 resetANRTimeoutsLocked();
2595 }
2596
2597 mDispatchEnabled = enabled;
2598 mDispatchFrozen = frozen;
2599 changed = true;
2600 } else {
2601 changed = false;
2602 }
2603
2604#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002605 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002606#endif
2607 } // release lock
2608
2609 if (changed) {
2610 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002611 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002612 }
2613}
2614
Jeff Brownb88102f2010-09-08 11:49:43 -07002615void InputDispatcher::logDispatchStateLocked() {
2616 String8 dump;
2617 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002618
2619 char* text = dump.lockBuffer(dump.size());
2620 char* start = text;
2621 while (*start != '\0') {
2622 char* end = strchr(start, '\n');
2623 if (*end == '\n') {
2624 *(end++) = '\0';
2625 }
2626 LOGD("%s", start);
2627 start = end;
2628 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002629}
2630
2631void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002632 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2633 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07002634
2635 if (mFocusedApplication) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002636 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002637 mFocusedApplication->name.string(),
2638 mFocusedApplication->dispatchingTimeout / 1000000.0);
2639 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002640 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002641 }
Jeff Brownf2f487182010-10-01 17:46:21 -07002642 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002643 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f487182010-10-01 17:46:21 -07002644
2645 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2646 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2647 if (!mTouchState.windows.isEmpty()) {
2648 dump.append(INDENT "TouchedWindows:\n");
2649 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2650 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2651 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2652 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2653 touchedWindow.targetFlags);
2654 }
2655 } else {
2656 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002657 }
2658
Jeff Brownf2f487182010-10-01 17:46:21 -07002659 if (!mWindows.isEmpty()) {
2660 dump.append(INDENT "Windows:\n");
2661 for (size_t i = 0; i < mWindows.size(); i++) {
2662 const InputWindow& window = mWindows[i];
2663 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2664 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2665 "frame=[%d,%d][%d,%d], "
2666 "visibleFrame=[%d,%d][%d,%d], "
2667 "touchableArea=[%d,%d][%d,%d], "
2668 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2669 i, window.name.string(),
2670 toString(window.paused),
2671 toString(window.hasFocus),
2672 toString(window.hasWallpaper),
2673 toString(window.visible),
2674 toString(window.canReceiveKeys),
2675 window.layoutParamsFlags, window.layoutParamsType,
2676 window.layer,
2677 window.frameLeft, window.frameTop,
2678 window.frameRight, window.frameBottom,
2679 window.visibleFrameLeft, window.visibleFrameTop,
2680 window.visibleFrameRight, window.visibleFrameBottom,
2681 window.touchableAreaLeft, window.touchableAreaTop,
2682 window.touchableAreaRight, window.touchableAreaBottom,
2683 window.ownerPid, window.ownerUid,
2684 window.dispatchingTimeout / 1000000.0);
2685 }
2686 } else {
2687 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002688 }
2689
Jeff Brownf2f487182010-10-01 17:46:21 -07002690 if (!mMonitoringChannels.isEmpty()) {
2691 dump.append(INDENT "MonitoringChannels:\n");
2692 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2693 const sp<InputChannel>& channel = mMonitoringChannels[i];
2694 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2695 }
2696 } else {
2697 dump.append(INDENT "MonitoringChannels: <none>\n");
2698 }
Jeff Brown519e0242010-09-15 15:18:56 -07002699
Jeff Brownf2f487182010-10-01 17:46:21 -07002700 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2701
2702 if (!mActiveConnections.isEmpty()) {
2703 dump.append(INDENT "ActiveConnections:\n");
2704 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2705 const Connection* connection = mActiveConnections[i];
2706 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
Jeff Brownb6997262010-10-08 22:31:17 -07002707 "inputState.isNeutral=%s\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07002708 i, connection->getInputChannelName(), connection->getStatusLabel(),
2709 connection->outboundQueue.count(),
Jeff Brownb6997262010-10-08 22:31:17 -07002710 toString(connection->inputState.isNeutral()));
Jeff Brownf2f487182010-10-01 17:46:21 -07002711 }
2712 } else {
2713 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002714 }
2715
2716 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002717 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002718 (mAppSwitchDueTime - now()) / 1000000.0);
2719 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002720 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002721 }
2722}
2723
2724status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002725#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07002726 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2727 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07002728#endif
2729
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002730 { // acquire lock
2731 AutoMutex _l(mLock);
2732
Jeff Brown519e0242010-09-15 15:18:56 -07002733 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002734 LOGW("Attempted to register already registered input channel '%s'",
2735 inputChannel->getName().string());
2736 return BAD_VALUE;
2737 }
2738
2739 sp<Connection> connection = new Connection(inputChannel);
2740 status_t status = connection->initialize();
2741 if (status) {
2742 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2743 inputChannel->getName().string(), status);
2744 return status;
2745 }
2746
Jeff Brown2cbecea2010-08-17 15:59:26 -07002747 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002748 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002749
Jeff Brownb88102f2010-09-08 11:49:43 -07002750 if (monitor) {
2751 mMonitoringChannels.push(inputChannel);
2752 }
2753
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002754 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07002755
Jeff Brown9c3cda02010-06-15 01:31:58 -07002756 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002757 } // release lock
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002758 return OK;
2759}
2760
2761status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002762#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07002763 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07002764#endif
2765
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002766 { // acquire lock
2767 AutoMutex _l(mLock);
2768
Jeff Brown519e0242010-09-15 15:18:56 -07002769 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002770 if (connectionIndex < 0) {
2771 LOGW("Attempted to unregister already unregistered input channel '%s'",
2772 inputChannel->getName().string());
2773 return BAD_VALUE;
2774 }
2775
2776 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2777 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2778
2779 connection->status = Connection::STATUS_ZOMBIE;
2780
Jeff Brownb88102f2010-09-08 11:49:43 -07002781 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2782 if (mMonitoringChannels[i] == inputChannel) {
2783 mMonitoringChannels.removeAt(i);
2784 break;
2785 }
2786 }
2787
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002788 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07002789
Jeff Brown7fbdc842010-06-17 20:52:56 -07002790 nsecs_t currentTime = now();
Jeff Brownb6997262010-10-08 22:31:17 -07002791 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002792
2793 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002794 } // release lock
2795
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002796 // Wake the poll loop because removing the connection may have changed the current
2797 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002798 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002799 return OK;
2800}
2801
Jeff Brown519e0242010-09-15 15:18:56 -07002802ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07002803 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2804 if (connectionIndex >= 0) {
2805 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2806 if (connection->inputChannel.get() == inputChannel.get()) {
2807 return connectionIndex;
2808 }
2809 }
2810
2811 return -1;
2812}
2813
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002814void InputDispatcher::activateConnectionLocked(Connection* connection) {
2815 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2816 if (mActiveConnections.itemAt(i) == connection) {
2817 return;
2818 }
2819 }
2820 mActiveConnections.add(connection);
2821}
2822
2823void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2824 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2825 if (mActiveConnections.itemAt(i) == connection) {
2826 mActiveConnections.removeAt(i);
2827 return;
2828 }
2829 }
2830}
2831
Jeff Brown9c3cda02010-06-15 01:31:58 -07002832void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002833 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002834}
2835
Jeff Brown9c3cda02010-06-15 01:31:58 -07002836void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002837 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002838}
2839
Jeff Brown9c3cda02010-06-15 01:31:58 -07002840void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002841 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002842 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2843 connection->getInputChannelName());
2844
Jeff Brown9c3cda02010-06-15 01:31:58 -07002845 CommandEntry* commandEntry = postCommandLocked(
2846 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002847 commandEntry->connection = connection;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002848}
2849
Jeff Brown519e0242010-09-15 15:18:56 -07002850void InputDispatcher::onANRLocked(
2851 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2852 nsecs_t eventTime, nsecs_t waitStartTime) {
2853 LOGI("Application is not responding: %s. "
2854 "%01.1fms since event, %01.1fms since wait started",
2855 getApplicationWindowLabelLocked(application, window).string(),
2856 (currentTime - eventTime) / 1000000.0,
2857 (currentTime - waitStartTime) / 1000000.0);
2858
2859 CommandEntry* commandEntry = postCommandLocked(
2860 & InputDispatcher::doNotifyANRLockedInterruptible);
2861 if (application) {
2862 commandEntry->inputApplicationHandle = application->handle;
2863 }
2864 if (window) {
2865 commandEntry->inputChannel = window->inputChannel;
2866 }
2867}
2868
Jeff Brownb88102f2010-09-08 11:49:43 -07002869void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2870 CommandEntry* commandEntry) {
2871 mLock.unlock();
2872
2873 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2874
2875 mLock.lock();
2876}
2877
Jeff Brown9c3cda02010-06-15 01:31:58 -07002878void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2879 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002880 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07002881
Jeff Brown7fbdc842010-06-17 20:52:56 -07002882 if (connection->status != Connection::STATUS_ZOMBIE) {
2883 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002884
Jeff Brown7fbdc842010-06-17 20:52:56 -07002885 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2886
2887 mLock.lock();
2888 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07002889}
2890
Jeff Brown519e0242010-09-15 15:18:56 -07002891void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07002892 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07002893 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002894
Jeff Brown519e0242010-09-15 15:18:56 -07002895 nsecs_t newTimeout = mPolicy->notifyANR(
2896 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002897
Jeff Brown519e0242010-09-15 15:18:56 -07002898 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002899
Jeff Brown519e0242010-09-15 15:18:56 -07002900 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002901}
2902
Jeff Brownb88102f2010-09-08 11:49:43 -07002903void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2904 CommandEntry* commandEntry) {
2905 KeyEntry* entry = commandEntry->keyEntry;
2906 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2907 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2908 entry->downTime, entry->eventTime);
2909
2910 mLock.unlock();
2911
2912 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2913 & mReusableKeyEvent, entry->policyFlags);
2914
2915 mLock.lock();
2916
2917 entry->interceptKeyResult = consumed
2918 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2919 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2920 mAllocator.releaseKeyEntry(entry);
2921}
2922
2923void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2924 mLock.unlock();
2925
Jeff Brown01ce2e92010-09-26 22:20:12 -07002926 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07002927
2928 mLock.lock();
2929}
2930
Jeff Brown519e0242010-09-15 15:18:56 -07002931void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
2932 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
2933 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07002934}
2935
2936void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002937 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002938 dumpDispatchStateLocked(dump);
2939}
2940
Jeff Brown9c3cda02010-06-15 01:31:58 -07002941
Jeff Brown519e0242010-09-15 15:18:56 -07002942// --- InputDispatcher::Queue ---
2943
2944template <typename T>
2945uint32_t InputDispatcher::Queue<T>::count() const {
2946 uint32_t result = 0;
2947 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
2948 result += 1;
2949 }
2950 return result;
2951}
2952
2953
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002954// --- InputDispatcher::Allocator ---
2955
2956InputDispatcher::Allocator::Allocator() {
2957}
2958
Jeff Brown01ce2e92010-09-26 22:20:12 -07002959InputDispatcher::InjectionState*
2960InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
2961 InjectionState* injectionState = mInjectionStatePool.alloc();
2962 injectionState->refCount = 1;
2963 injectionState->injectorPid = injectorPid;
2964 injectionState->injectorUid = injectorUid;
2965 injectionState->injectionIsAsync = false;
2966 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
2967 injectionState->pendingForegroundDispatches = 0;
2968 return injectionState;
2969}
2970
Jeff Brown7fbdc842010-06-17 20:52:56 -07002971void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brownb6997262010-10-08 22:31:17 -07002972 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002973 entry->type = type;
2974 entry->refCount = 1;
2975 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07002976 entry->eventTime = eventTime;
Jeff Brownb6997262010-10-08 22:31:17 -07002977 entry->policyFlags = policyFlags;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002978 entry->injectionState = NULL;
2979}
2980
2981void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
2982 if (entry->injectionState) {
2983 releaseInjectionState(entry->injectionState);
2984 entry->injectionState = NULL;
2985 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002986}
2987
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002988InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07002989InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002990 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07002991 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002992 return entry;
2993}
2994
Jeff Brown7fbdc842010-06-17 20:52:56 -07002995InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002996 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002997 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
2998 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002999 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003000 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003001
3002 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003003 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003004 entry->action = action;
3005 entry->flags = flags;
3006 entry->keyCode = keyCode;
3007 entry->scanCode = scanCode;
3008 entry->metaState = metaState;
3009 entry->repeatCount = repeatCount;
3010 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003011 entry->syntheticRepeat = false;
3012 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003013 return entry;
3014}
3015
Jeff Brown7fbdc842010-06-17 20:52:56 -07003016InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07003017 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003018 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3019 nsecs_t downTime, uint32_t pointerCount,
3020 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003021 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003022 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003023
3024 entry->eventTime = eventTime;
3025 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003026 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003027 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07003028 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003029 entry->metaState = metaState;
3030 entry->edgeFlags = edgeFlags;
3031 entry->xPrecision = xPrecision;
3032 entry->yPrecision = yPrecision;
3033 entry->downTime = downTime;
3034 entry->pointerCount = pointerCount;
3035 entry->firstSample.eventTime = eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003036 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003037 entry->lastSample = & entry->firstSample;
3038 for (uint32_t i = 0; i < pointerCount; i++) {
3039 entry->pointerIds[i] = pointerIds[i];
3040 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3041 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003042 return entry;
3043}
3044
3045InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07003046 EventEntry* eventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07003047 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003048 DispatchEntry* entry = mDispatchEntryPool.alloc();
3049 entry->eventEntry = eventEntry;
3050 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07003051 entry->targetFlags = targetFlags;
3052 entry->xOffset = xOffset;
3053 entry->yOffset = yOffset;
Jeff Brownb88102f2010-09-08 11:49:43 -07003054 entry->inProgress = false;
3055 entry->headMotionSample = NULL;
3056 entry->tailMotionSample = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003057 return entry;
3058}
3059
Jeff Brown9c3cda02010-06-15 01:31:58 -07003060InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3061 CommandEntry* entry = mCommandEntryPool.alloc();
3062 entry->command = command;
3063 return entry;
3064}
3065
Jeff Brown01ce2e92010-09-26 22:20:12 -07003066void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3067 injectionState->refCount -= 1;
3068 if (injectionState->refCount == 0) {
3069 mInjectionStatePool.free(injectionState);
3070 } else {
3071 assert(injectionState->refCount > 0);
3072 }
3073}
3074
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003075void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3076 switch (entry->type) {
3077 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3078 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3079 break;
3080 case EventEntry::TYPE_KEY:
3081 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3082 break;
3083 case EventEntry::TYPE_MOTION:
3084 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3085 break;
3086 default:
3087 assert(false);
3088 break;
3089 }
3090}
3091
3092void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3093 ConfigurationChangedEntry* entry) {
3094 entry->refCount -= 1;
3095 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003096 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003097 mConfigurationChangeEntryPool.free(entry);
3098 } else {
3099 assert(entry->refCount > 0);
3100 }
3101}
3102
3103void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3104 entry->refCount -= 1;
3105 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003106 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003107 mKeyEntryPool.free(entry);
3108 } else {
3109 assert(entry->refCount > 0);
3110 }
3111}
3112
3113void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3114 entry->refCount -= 1;
3115 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003116 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003117 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3118 MotionSample* next = sample->next;
3119 mMotionSamplePool.free(sample);
3120 sample = next;
3121 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003122 mMotionEntryPool.free(entry);
3123 } else {
3124 assert(entry->refCount > 0);
3125 }
3126}
3127
3128void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3129 releaseEventEntry(entry->eventEntry);
3130 mDispatchEntryPool.free(entry);
3131}
3132
Jeff Brown9c3cda02010-06-15 01:31:58 -07003133void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3134 mCommandEntryPool.free(entry);
3135}
3136
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003137void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003138 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003139 MotionSample* sample = mMotionSamplePool.alloc();
3140 sample->eventTime = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003141 uint32_t pointerCount = motionEntry->pointerCount;
3142 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003143 sample->pointerCoords[i] = pointerCoords[i];
3144 }
3145
3146 sample->next = NULL;
3147 motionEntry->lastSample->next = sample;
3148 motionEntry->lastSample = sample;
3149}
3150
Jeff Brown01ce2e92010-09-26 22:20:12 -07003151void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3152 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003153
Jeff Brown01ce2e92010-09-26 22:20:12 -07003154 keyEntry->dispatchInProgress = false;
3155 keyEntry->syntheticRepeat = false;
3156 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003157}
3158
3159
Jeff Brownae9fc032010-08-18 15:51:08 -07003160// --- InputDispatcher::MotionEntry ---
3161
3162uint32_t InputDispatcher::MotionEntry::countSamples() const {
3163 uint32_t count = 1;
3164 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3165 count += 1;
3166 }
3167 return count;
3168}
3169
Jeff Brownb88102f2010-09-08 11:49:43 -07003170
3171// --- InputDispatcher::InputState ---
3172
Jeff Brownb6997262010-10-08 22:31:17 -07003173InputDispatcher::InputState::InputState() {
Jeff Brownb88102f2010-09-08 11:49:43 -07003174}
3175
3176InputDispatcher::InputState::~InputState() {
3177}
3178
3179bool InputDispatcher::InputState::isNeutral() const {
3180 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3181}
3182
Jeff Brownb88102f2010-09-08 11:49:43 -07003183InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3184 const EventEntry* entry) {
3185 switch (entry->type) {
3186 case EventEntry::TYPE_KEY:
3187 return trackKey(static_cast<const KeyEntry*>(entry));
3188
3189 case EventEntry::TYPE_MOTION:
3190 return trackMotion(static_cast<const MotionEntry*>(entry));
3191
3192 default:
3193 return CONSISTENT;
3194 }
3195}
3196
3197InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3198 const KeyEntry* entry) {
3199 int32_t action = entry->action;
3200 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3201 KeyMemento& memento = mKeyMementos.editItemAt(i);
3202 if (memento.deviceId == entry->deviceId
3203 && memento.source == entry->source
3204 && memento.keyCode == entry->keyCode
3205 && memento.scanCode == entry->scanCode) {
3206 switch (action) {
3207 case AKEY_EVENT_ACTION_UP:
3208 mKeyMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003209 return CONSISTENT;
3210
3211 case AKEY_EVENT_ACTION_DOWN:
3212 return TOLERABLE;
3213
3214 default:
3215 return BROKEN;
3216 }
3217 }
3218 }
3219
3220 switch (action) {
3221 case AKEY_EVENT_ACTION_DOWN: {
3222 mKeyMementos.push();
3223 KeyMemento& memento = mKeyMementos.editTop();
3224 memento.deviceId = entry->deviceId;
3225 memento.source = entry->source;
3226 memento.keyCode = entry->keyCode;
3227 memento.scanCode = entry->scanCode;
3228 memento.downTime = entry->downTime;
3229 return CONSISTENT;
3230 }
3231
3232 default:
3233 return BROKEN;
3234 }
3235}
3236
3237InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3238 const MotionEntry* entry) {
3239 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3240 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3241 MotionMemento& memento = mMotionMementos.editItemAt(i);
3242 if (memento.deviceId == entry->deviceId
3243 && memento.source == entry->source) {
3244 switch (action) {
3245 case AMOTION_EVENT_ACTION_UP:
3246 case AMOTION_EVENT_ACTION_CANCEL:
3247 mMotionMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003248 return CONSISTENT;
3249
3250 case AMOTION_EVENT_ACTION_DOWN:
3251 return TOLERABLE;
3252
3253 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3254 if (entry->pointerCount == memento.pointerCount + 1) {
3255 memento.setPointers(entry);
3256 return CONSISTENT;
3257 }
3258 return BROKEN;
3259
3260 case AMOTION_EVENT_ACTION_POINTER_UP:
3261 if (entry->pointerCount == memento.pointerCount - 1) {
3262 memento.setPointers(entry);
3263 return CONSISTENT;
3264 }
3265 return BROKEN;
3266
3267 case AMOTION_EVENT_ACTION_MOVE:
3268 if (entry->pointerCount == memento.pointerCount) {
3269 return CONSISTENT;
3270 }
3271 return BROKEN;
3272
3273 default:
3274 return BROKEN;
3275 }
3276 }
3277 }
3278
3279 switch (action) {
3280 case AMOTION_EVENT_ACTION_DOWN: {
3281 mMotionMementos.push();
3282 MotionMemento& memento = mMotionMementos.editTop();
3283 memento.deviceId = entry->deviceId;
3284 memento.source = entry->source;
3285 memento.xPrecision = entry->xPrecision;
3286 memento.yPrecision = entry->yPrecision;
3287 memento.downTime = entry->downTime;
3288 memento.setPointers(entry);
3289 return CONSISTENT;
3290 }
3291
3292 default:
3293 return BROKEN;
3294 }
3295}
3296
3297void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3298 pointerCount = entry->pointerCount;
3299 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3300 pointerIds[i] = entry->pointerIds[i];
3301 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3302 }
3303}
3304
Jeff Brownb6997262010-10-08 22:31:17 -07003305void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3306 Allocator* allocator, Vector<EventEntry*>& outEvents,
3307 CancelationOptions options) {
3308 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003309 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brownb6997262010-10-08 22:31:17 -07003310 if (shouldCancelEvent(memento.source, options)) {
3311 outEvents.push(allocator->obtainKeyEntry(currentTime,
3312 memento.deviceId, memento.source, 0,
3313 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3314 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3315 mKeyMementos.removeAt(i);
3316 } else {
3317 i += 1;
3318 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003319 }
3320
Jeff Browna1160a72010-10-11 18:22:53 -07003321 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003322 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brownb6997262010-10-08 22:31:17 -07003323 if (shouldCancelEvent(memento.source, options)) {
3324 outEvents.push(allocator->obtainMotionEntry(currentTime,
3325 memento.deviceId, memento.source, 0,
3326 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3327 memento.xPrecision, memento.yPrecision, memento.downTime,
3328 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3329 mMotionMementos.removeAt(i);
3330 } else {
3331 i += 1;
3332 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003333 }
3334}
3335
3336void InputDispatcher::InputState::clear() {
3337 mKeyMementos.clear();
3338 mMotionMementos.clear();
Jeff Brownb6997262010-10-08 22:31:17 -07003339}
3340
3341bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3342 CancelationOptions options) {
3343 switch (options) {
3344 case CANCEL_POINTER_EVENTS:
3345 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3346 case CANCEL_NON_POINTER_EVENTS:
3347 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3348 default:
3349 return true;
3350 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003351}
3352
3353
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003354// --- InputDispatcher::Connection ---
3355
3356InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3357 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown519e0242010-09-15 15:18:56 -07003358 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003359}
3360
3361InputDispatcher::Connection::~Connection() {
3362}
3363
3364status_t InputDispatcher::Connection::initialize() {
3365 return inputPublisher.initialize();
3366}
3367
Jeff Brown9c3cda02010-06-15 01:31:58 -07003368const char* InputDispatcher::Connection::getStatusLabel() const {
3369 switch (status) {
3370 case STATUS_NORMAL:
3371 return "NORMAL";
3372
3373 case STATUS_BROKEN:
3374 return "BROKEN";
3375
Jeff Brown9c3cda02010-06-15 01:31:58 -07003376 case STATUS_ZOMBIE:
3377 return "ZOMBIE";
3378
3379 default:
3380 return "UNKNOWN";
3381 }
3382}
3383
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003384InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3385 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07003386 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3387 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003388 if (dispatchEntry->eventEntry == eventEntry) {
3389 return dispatchEntry;
3390 }
3391 }
3392 return NULL;
3393}
3394
Jeff Brownb88102f2010-09-08 11:49:43 -07003395
Jeff Brown9c3cda02010-06-15 01:31:58 -07003396// --- InputDispatcher::CommandEntry ---
3397
Jeff Brownb88102f2010-09-08 11:49:43 -07003398InputDispatcher::CommandEntry::CommandEntry() :
3399 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003400}
3401
3402InputDispatcher::CommandEntry::~CommandEntry() {
3403}
3404
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003405
Jeff Brown01ce2e92010-09-26 22:20:12 -07003406// --- InputDispatcher::TouchState ---
3407
3408InputDispatcher::TouchState::TouchState() :
3409 down(false), split(false) {
3410}
3411
3412InputDispatcher::TouchState::~TouchState() {
3413}
3414
3415void InputDispatcher::TouchState::reset() {
3416 down = false;
3417 split = false;
3418 windows.clear();
3419}
3420
3421void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3422 down = other.down;
3423 split = other.split;
3424 windows.clear();
3425 windows.appendVector(other.windows);
3426}
3427
3428void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3429 int32_t targetFlags, BitSet32 pointerIds) {
3430 if (targetFlags & InputTarget::FLAG_SPLIT) {
3431 split = true;
3432 }
3433
3434 for (size_t i = 0; i < windows.size(); i++) {
3435 TouchedWindow& touchedWindow = windows.editItemAt(i);
3436 if (touchedWindow.window == window) {
3437 touchedWindow.targetFlags |= targetFlags;
3438 touchedWindow.pointerIds.value |= pointerIds.value;
3439 return;
3440 }
3441 }
3442
3443 windows.push();
3444
3445 TouchedWindow& touchedWindow = windows.editTop();
3446 touchedWindow.window = window;
3447 touchedWindow.targetFlags = targetFlags;
3448 touchedWindow.pointerIds = pointerIds;
3449 touchedWindow.channel = window->inputChannel;
3450}
3451
3452void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3453 for (size_t i = 0 ; i < windows.size(); ) {
3454 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3455 windows.removeAt(i);
3456 } else {
3457 i += 1;
3458 }
3459 }
3460}
3461
3462const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3463 for (size_t i = 0; i < windows.size(); i++) {
3464 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3465 return windows[i].window;
3466 }
3467 }
3468 return NULL;
3469}
3470
3471
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003472// --- InputDispatcherThread ---
3473
3474InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3475 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3476}
3477
3478InputDispatcherThread::~InputDispatcherThread() {
3479}
3480
3481bool InputDispatcherThread::threadLoop() {
3482 mDispatcher->dispatchOnce();
3483 return true;
3484}
3485
3486} // namespace android