blob: 58c2cdfda8586b13fc120f267b0bf9ea27001a81 [file] [log] [blame]
Jeff Browne839a582010-04-22 18:58:52 -07001//
2// Copyright 2010 The Android Open Source Project
3//
4// The input dispatcher.
5//
6#define LOG_TAG "InputDispatcher"
7
8//#define LOG_NDEBUG 0
9
10// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown50de30a2010-06-22 01:27:15 -070011#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Browne839a582010-04-22 18:58:52 -070012
13// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown50de30a2010-06-22 01:27:15 -070014#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Browne839a582010-04-22 18:58:52 -070015
16// Log debug messages about batching.
Jeff Brown50de30a2010-06-22 01:27:15 -070017#define DEBUG_BATCHING 0
Jeff Browne839a582010-04-22 18:58:52 -070018
19// Log debug messages about the dispatch cycle.
Jeff Brown50de30a2010-06-22 01:27:15 -070020#define DEBUG_DISPATCH_CYCLE 0
Jeff Browne839a582010-04-22 18:58:52 -070021
Jeff Brown54bc2812010-06-15 01:31:58 -070022// Log debug messages about registrations.
Jeff Brown50de30a2010-06-22 01:27:15 -070023#define DEBUG_REGISTRATION 0
Jeff Brown54bc2812010-06-15 01:31:58 -070024
Jeff Browne839a582010-04-22 18:58:52 -070025// Log debug messages about performance statistics.
Jeff Brown50de30a2010-06-22 01:27:15 -070026#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Browne839a582010-04-22 18:58:52 -070027
Jeff Brown51d45a72010-06-17 20:52:56 -070028// Log debug messages about input event injection.
Jeff Brown50de30a2010-06-22 01:27:15 -070029#define DEBUG_INJECTION 0
Jeff Brown51d45a72010-06-17 20:52:56 -070030
Jeff Brown542412c2010-08-18 15:51:08 -070031// Log debug messages about input event throttling.
32#define DEBUG_THROTTLING 0
33
Jeff Browna665ca82010-09-08 11:49:43 -070034// Log debug messages about input focus tracking.
35#define DEBUG_FOCUS 0
36
37// Log debug messages about the app switch latency optimization.
38#define DEBUG_APP_SWITCH 0
39
Jeff Browne839a582010-04-22 18:58:52 -070040#include <cutils/log.h>
41#include <ui/InputDispatcher.h>
Jeff Browna665ca82010-09-08 11:49:43 -070042#include <ui/PowerManager.h>
Jeff Browne839a582010-04-22 18:58:52 -070043
44#include <stddef.h>
45#include <unistd.h>
Jeff Browne839a582010-04-22 18:58:52 -070046#include <errno.h>
47#include <limits.h>
Jeff Browne839a582010-04-22 18:58:52 -070048
Jeff Brown2806e382010-10-01 17:46:21 -070049#define INDENT " "
50#define INDENT2 " "
51
Jeff Browne839a582010-04-22 18:58:52 -070052namespace android {
53
Jeff Browna665ca82010-09-08 11:49:43 -070054// Delay between reporting long touch events to the power manager.
55const nsecs_t EVENT_IGNORE_DURATION = 300 * 1000000LL; // 300 ms
56
57// Default input dispatching timeout if there is no focused application or paused window
58// from which to determine an appropriate dispatching timeout.
59const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
60
61// Amount of time to allow for all pending events to be processed when an app switch
62// key is on the way. This is used to preempt input dispatch and drop input events
63// when an application takes too long to respond and the user has pressed an app switch key.
64const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
65
Jeff Browne839a582010-04-22 18:58:52 -070066
Jeff Brown51d45a72010-06-17 20:52:56 -070067static inline nsecs_t now() {
68 return systemTime(SYSTEM_TIME_MONOTONIC);
69}
70
Jeff Browna665ca82010-09-08 11:49:43 -070071static inline const char* toString(bool value) {
72 return value ? "true" : "false";
73}
74
Jeff Brownd1b0a2b2010-09-26 22:20:12 -070075static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
76 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
77 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
78}
79
80static bool isValidKeyAction(int32_t action) {
81 switch (action) {
82 case AKEY_EVENT_ACTION_DOWN:
83 case AKEY_EVENT_ACTION_UP:
84 return true;
85 default:
86 return false;
87 }
88}
89
90static bool validateKeyEvent(int32_t action) {
91 if (! isValidKeyAction(action)) {
92 LOGE("Key event has invalid action code 0x%x", action);
93 return false;
94 }
95 return true;
96}
97
Jeff Brown90f0cee2010-10-08 22:31:17 -070098static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -070099 switch (action & AMOTION_EVENT_ACTION_MASK) {
100 case AMOTION_EVENT_ACTION_DOWN:
101 case AMOTION_EVENT_ACTION_UP:
102 case AMOTION_EVENT_ACTION_CANCEL:
103 case AMOTION_EVENT_ACTION_MOVE:
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700104 case AMOTION_EVENT_ACTION_OUTSIDE:
105 return true;
Jeff Brown90f0cee2010-10-08 22:31:17 -0700106 case AMOTION_EVENT_ACTION_POINTER_DOWN:
107 case AMOTION_EVENT_ACTION_POINTER_UP: {
108 int32_t index = getMotionEventActionPointerIndex(action);
109 return index >= 0 && size_t(index) < pointerCount;
110 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700111 default:
112 return false;
113 }
114}
115
116static bool validateMotionEvent(int32_t action, size_t pointerCount,
117 const int32_t* pointerIds) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700118 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700119 LOGE("Motion event has invalid action code 0x%x", action);
120 return false;
121 }
122 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
123 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
124 pointerCount, MAX_POINTERS);
125 return false;
126 }
127 for (size_t i = 0; i < pointerCount; i++) {
128 if (pointerIds[i] < 0 || pointerIds[i] > MAX_POINTER_ID) {
129 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
130 pointerIds[i], MAX_POINTER_ID);
131 return false;
132 }
133 }
134 return true;
135}
136
Jeff Browna665ca82010-09-08 11:49:43 -0700137
138// --- InputWindow ---
139
Jeff Browna665ca82010-09-08 11:49:43 -0700140bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
141 return x >= touchableAreaLeft && x <= touchableAreaRight
142 && y >= touchableAreaTop && y <= touchableAreaBottom;
143}
144
Jeff Brown35cf0e92010-10-05 12:26:23 -0700145bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
146 return x >= frameLeft && x <= frameRight
147 && y >= frameTop && y <= frameBottom;
148}
149
150bool InputWindow::isTrustedOverlay() const {
151 return layoutParamsType == TYPE_INPUT_METHOD
152 || layoutParamsType == TYPE_INPUT_METHOD_DIALOG;
153}
154
Jeff Browna665ca82010-09-08 11:49:43 -0700155
Jeff Browne839a582010-04-22 18:58:52 -0700156// --- InputDispatcher ---
157
Jeff Brown54bc2812010-06-15 01:31:58 -0700158InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Browna665ca82010-09-08 11:49:43 -0700159 mPolicy(policy),
160 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
161 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700162 mFocusedWindow(NULL),
Jeff Browna665ca82010-09-08 11:49:43 -0700163 mFocusedApplication(NULL),
164 mCurrentInputTargetsValid(false),
165 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown59abe7e2010-09-13 23:17:30 -0700166 mLooper = new Looper(false);
Jeff Browne839a582010-04-22 18:58:52 -0700167
Jeff Browna665ca82010-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 Browne839a582010-04-22 18:58:52 -0700171
Jeff Browna665ca82010-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 Browne839a582010-04-22 18:58:52 -0700175
176 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown54bc2812010-06-15 01:31:58 -0700177
Jeff Brown542412c2010-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 Browne839a582010-04-22 18:58:52 -0700186}
187
188InputDispatcher::~InputDispatcher() {
Jeff Browna665ca82010-09-08 11:49:43 -0700189 { // acquire lock
190 AutoMutex _l(mLock);
191
192 resetKeyRepeatLocked();
Jeff Brownd8816c32010-09-16 14:07:33 -0700193 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700194 drainInboundQueueLocked();
195 }
Jeff Browne839a582010-04-22 18:58:52 -0700196
197 while (mConnectionsByReceiveFd.size() != 0) {
198 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
199 }
Jeff Browne839a582010-04-22 18:58:52 -0700200}
201
202void InputDispatcher::dispatchOnce() {
Jeff Brown54bc2812010-06-15 01:31:58 -0700203 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brown61ce3982010-09-07 10:44:57 -0700204 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Browne839a582010-04-22 18:58:52 -0700205
Jeff Browne839a582010-04-22 18:58:52 -0700206 nsecs_t nextWakeupTime = LONG_LONG_MAX;
207 { // acquire lock
208 AutoMutex _l(mLock);
Jeff Browna665ca82010-09-08 11:49:43 -0700209 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Browne839a582010-04-22 18:58:52 -0700210
Jeff Browna665ca82010-09-08 11:49:43 -0700211 if (runCommandsLockedInterruptible()) {
212 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Browne839a582010-04-22 18:58:52 -0700213 }
Jeff Browne839a582010-04-22 18:58:52 -0700214 } // release lock
215
Jeff Browna665ca82010-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 Brown59abe7e2010-09-13 23:17:30 -0700227 mLooper->pollOnce(timeoutMillis);
Jeff Browna665ca82010-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 Browna665ca82010-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 Browna665ca82010-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 Brown90f0cee2010-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 Browna665ca82010-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 Brownd8816c32010-09-16 14:07:33 -0700346 bool done = false;
Jeff Brown90f0cee2010-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 Browna665ca82010-09-08 11:49:43 -0700353 switch (mPendingEvent->type) {
354 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
355 ConfigurationChangedEntry* typedEntry =
356 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brownd8816c32010-09-16 14:07:33 -0700357 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700358 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Browna665ca82010-09-08 11:49:43 -0700359 break;
360 }
361
362 case EventEntry::TYPE_KEY: {
363 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700364 if (isAppSwitchDue) {
365 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700366 resetPendingAppSwitchLocked(true);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700367 isAppSwitchDue = false;
368 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
369 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700370 }
371 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700372 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
373 dropReason != DROP_REASON_NOT_DROPPED, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700374 break;
375 }
376
377 case EventEntry::TYPE_MOTION: {
378 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700379 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
380 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700381 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700382 done = dispatchMotionLocked(currentTime, typedEntry,
383 dropReason != DROP_REASON_NOT_DROPPED, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700384 break;
385 }
386
387 default:
388 assert(false);
Jeff Browna665ca82010-09-08 11:49:43 -0700389 break;
390 }
391
Jeff Brownd8816c32010-09-16 14:07:33 -0700392 if (done) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700393 if (dropReason != DROP_REASON_NOT_DROPPED) {
394 dropInboundEventLocked(mPendingEvent, dropReason);
395 }
396
Jeff Brownd8816c32010-09-16 14:07:33 -0700397 releasePendingEventLocked();
Jeff Browna665ca82010-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 Brown90f0cee2010-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 Browna665ca82010-09-08 11:49:43 -0700423 break;
424 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700425 }
Jeff Browna665ca82010-09-08 11:49:43 -0700426
427 return needWake;
428}
429
Jeff Brown90f0cee2010-10-08 22:31:17 -0700430void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
431 const char* reason;
432 switch (dropReason) {
433 case DROP_REASON_POLICY:
434 reason = "inbound event was dropped because the policy requested that it not be "
435 "delivered to the application";
436 break;
437 case DROP_REASON_DISABLED:
438 LOGI("Dropped event because input dispatch is disabled.");
439 reason = "inbound event was dropped because input dispatch is disabled";
440 break;
441 case DROP_REASON_APP_SWITCH:
442 LOGI("Dropped event because of pending overdue app switch.");
443 reason = "inbound event was dropped because of pending overdue app switch";
444 break;
445 default:
446 assert(false);
447 return;
448 }
449
450 switch (entry->type) {
451 case EventEntry::TYPE_KEY:
452 synthesizeCancelationEventsForAllConnectionsLocked(
453 InputState::CANCEL_NON_POINTER_EVENTS, reason);
454 break;
455 case EventEntry::TYPE_MOTION: {
456 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
457 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
458 synthesizeCancelationEventsForAllConnectionsLocked(
459 InputState::CANCEL_POINTER_EVENTS, reason);
460 } else {
461 synthesizeCancelationEventsForAllConnectionsLocked(
462 InputState::CANCEL_NON_POINTER_EVENTS, reason);
463 }
464 break;
465 }
466 }
467}
468
469bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Browna665ca82010-09-08 11:49:43 -0700470 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
471}
472
Jeff Brown90f0cee2010-10-08 22:31:17 -0700473bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
474 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
475 && isAppSwitchKeyCode(keyEntry->keyCode)
476 && isEventFromTrustedSourceLocked(keyEntry)
477 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
478}
479
Jeff Browna665ca82010-09-08 11:49:43 -0700480bool InputDispatcher::isAppSwitchPendingLocked() {
481 return mAppSwitchDueTime != LONG_LONG_MAX;
482}
483
Jeff Browna665ca82010-09-08 11:49:43 -0700484void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
485 mAppSwitchDueTime = LONG_LONG_MAX;
486
487#if DEBUG_APP_SWITCH
488 if (handled) {
489 LOGD("App switch has arrived.");
490 } else {
491 LOGD("App switch was abandoned.");
492 }
493#endif
Jeff Browne839a582010-04-22 18:58:52 -0700494}
495
Jeff Brown54bc2812010-06-15 01:31:58 -0700496bool InputDispatcher::runCommandsLockedInterruptible() {
497 if (mCommandQueue.isEmpty()) {
498 return false;
499 }
Jeff Browne839a582010-04-22 18:58:52 -0700500
Jeff Brown54bc2812010-06-15 01:31:58 -0700501 do {
502 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
503
504 Command command = commandEntry->command;
505 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
506
Jeff Brown51d45a72010-06-17 20:52:56 -0700507 commandEntry->connection.clear();
Jeff Brown54bc2812010-06-15 01:31:58 -0700508 mAllocator.releaseCommandEntry(commandEntry);
509 } while (! mCommandQueue.isEmpty());
510 return true;
Jeff Browne839a582010-04-22 18:58:52 -0700511}
512
Jeff Brown54bc2812010-06-15 01:31:58 -0700513InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
514 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
515 mCommandQueue.enqueueAtTail(commandEntry);
516 return commandEntry;
517}
518
Jeff Browna665ca82010-09-08 11:49:43 -0700519void InputDispatcher::drainInboundQueueLocked() {
520 while (! mInboundQueue.isEmpty()) {
521 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brownd8816c32010-09-16 14:07:33 -0700522 releaseInboundEventLocked(entry);
Jeff Browne839a582010-04-22 18:58:52 -0700523 }
Jeff Browne839a582010-04-22 18:58:52 -0700524}
525
Jeff Brownd8816c32010-09-16 14:07:33 -0700526void InputDispatcher::releasePendingEventLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700527 if (mPendingEvent) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700528 releaseInboundEventLocked(mPendingEvent);
Jeff Browna665ca82010-09-08 11:49:43 -0700529 mPendingEvent = NULL;
530 }
531}
532
Jeff Brownd8816c32010-09-16 14:07:33 -0700533void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700534 InjectionState* injectionState = entry->injectionState;
535 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Browna665ca82010-09-08 11:49:43 -0700536#if DEBUG_DISPATCH_CYCLE
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700537 LOGD("Injected inbound event was dropped.");
Jeff Browna665ca82010-09-08 11:49:43 -0700538#endif
539 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
540 }
541 mAllocator.releaseEventEntry(entry);
542}
543
Jeff Brown90f0cee2010-10-08 22:31:17 -0700544bool InputDispatcher::isEventFromTrustedSourceLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700545 InjectionState* injectionState = entry->injectionState;
546 return ! injectionState
Jeff Brown90f0cee2010-10-08 22:31:17 -0700547 || hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-09-08 11:49:43 -0700548}
549
550void InputDispatcher::resetKeyRepeatLocked() {
551 if (mKeyRepeatState.lastKeyEntry) {
552 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
553 mKeyRepeatState.lastKeyEntry = NULL;
554 }
555}
556
557InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brown61ce3982010-09-07 10:44:57 -0700558 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown50de30a2010-06-22 01:27:15 -0700559 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
560
Jeff Brown50de30a2010-06-22 01:27:15 -0700561 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown90f0cee2010-10-08 22:31:17 -0700562 uint32_t policyFlags = entry->policyFlags & (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER);
Jeff Browne839a582010-04-22 18:58:52 -0700563 if (entry->refCount == 1) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700564 mAllocator.recycleKeyEntry(entry);
Jeff Brown51d45a72010-06-17 20:52:56 -0700565 entry->eventTime = currentTime;
Jeff Brown51d45a72010-06-17 20:52:56 -0700566 entry->policyFlags = policyFlags;
Jeff Browne839a582010-04-22 18:58:52 -0700567 entry->repeatCount += 1;
568 } else {
Jeff Brown51d45a72010-06-17 20:52:56 -0700569 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700570 entry->deviceId, entry->source, policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700571 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brownf16c26d2010-07-02 15:37:36 -0700572 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Browne839a582010-04-22 18:58:52 -0700573
574 mKeyRepeatState.lastKeyEntry = newEntry;
575 mAllocator.releaseKeyEntry(entry);
576
577 entry = newEntry;
578 }
Jeff Browna665ca82010-09-08 11:49:43 -0700579 entry->syntheticRepeat = true;
580
581 // Increment reference count since we keep a reference to the event in
582 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
583 entry->refCount += 1;
Jeff Browne839a582010-04-22 18:58:52 -0700584
Jeff Brownf16c26d2010-07-02 15:37:36 -0700585 if (entry->repeatCount == 1) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700586 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brownf16c26d2010-07-02 15:37:36 -0700587 }
588
Jeff Brown61ce3982010-09-07 10:44:57 -0700589 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Browna665ca82010-09-08 11:49:43 -0700590 return entry;
Jeff Browne839a582010-04-22 18:58:52 -0700591}
592
Jeff Browna665ca82010-09-08 11:49:43 -0700593bool InputDispatcher::dispatchConfigurationChangedLocked(
594 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Browne839a582010-04-22 18:58:52 -0700595#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Browna665ca82010-09-08 11:49:43 -0700596 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
597#endif
598
599 // Reset key repeating in case a keyboard device was added or removed or something.
600 resetKeyRepeatLocked();
601
602 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
603 CommandEntry* commandEntry = postCommandLocked(
604 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
605 commandEntry->eventTime = entry->eventTime;
606 return true;
607}
608
609bool InputDispatcher::dispatchKeyLocked(
610 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brownd8816c32010-09-16 14:07:33 -0700611 bool dropEvent, nsecs_t* nextWakeupTime) {
612 // Give the policy a chance to intercept the key.
613 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
614 bool trusted;
615 if (! dropEvent && mFocusedWindow) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700616 trusted = checkInjectionPermission(mFocusedWindow, entry->injectionState);
Jeff Brownd8816c32010-09-16 14:07:33 -0700617 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700618 trusted = isEventFromTrustedSourceLocked(entry);
Jeff Brownd8816c32010-09-16 14:07:33 -0700619 }
620 if (trusted) {
621 CommandEntry* commandEntry = postCommandLocked(
622 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
623 if (! dropEvent && mFocusedWindow) {
624 commandEntry->inputChannel = mFocusedWindow->inputChannel;
625 }
626 commandEntry->keyEntry = entry;
627 entry->refCount += 1;
628 return false; // wait for the command to run
629 } else {
630 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
631 }
632 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
633 resetTargetsLocked();
634 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
635 return true;
636 }
637
638 // Clean up if dropping the event.
639 if (dropEvent) {
640 resetTargetsLocked();
641 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
642 return true;
643 }
644
Jeff Browna665ca82010-09-08 11:49:43 -0700645 // Preprocessing.
646 if (! entry->dispatchInProgress) {
647 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
648
649 if (entry->repeatCount == 0
650 && entry->action == AKEY_EVENT_ACTION_DOWN
651 && ! entry->isInjected()) {
652 if (mKeyRepeatState.lastKeyEntry
653 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
654 // We have seen two identical key downs in a row which indicates that the device
655 // driver is automatically generating key repeats itself. We take note of the
656 // repeat here, but we disable our own next key repeat timer since it is clear that
657 // we will not need to synthesize key repeats ourselves.
658 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
659 resetKeyRepeatLocked();
660 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
661 } else {
662 // Not a repeat. Save key down state in case we do see a repeat later.
663 resetKeyRepeatLocked();
664 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
665 }
666 mKeyRepeatState.lastKeyEntry = entry;
667 entry->refCount += 1;
668 } else if (! entry->syntheticRepeat) {
669 resetKeyRepeatLocked();
670 }
671
672 entry->dispatchInProgress = true;
Jeff Brownd8816c32010-09-16 14:07:33 -0700673 resetTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700674 }
675
676 // Identify targets.
677 if (! mCurrentInputTargetsValid) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700678 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
679 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700680 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
681 return false;
682 }
683
684 setInjectionResultLocked(entry, injectionResult);
685 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
686 return true;
687 }
688
689 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700690 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700691 }
692
693 // Dispatch the key.
694 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
695
696 // Poke user activity.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700697 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
698 pokeUserActivityLocked(entry->eventTime, POWER_MANAGER_BUTTON_EVENT);
699 }
Jeff Browna665ca82010-09-08 11:49:43 -0700700 return true;
701}
702
703void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
704#if DEBUG_OUTBOUND_EVENT_DETAILS
705 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
706 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
707 "downTime=%lld",
708 prefix,
709 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
710 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
711 entry->downTime);
712#endif
713}
714
715bool InputDispatcher::dispatchMotionLocked(
Jeff Brownd8816c32010-09-16 14:07:33 -0700716 nsecs_t currentTime, MotionEntry* entry, bool dropEvent, nsecs_t* nextWakeupTime) {
717 // Clean up if dropping the event.
718 if (dropEvent) {
719 resetTargetsLocked();
720 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
721 return true;
722 }
723
Jeff Browna665ca82010-09-08 11:49:43 -0700724 // Preprocessing.
725 if (! entry->dispatchInProgress) {
726 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
727
728 entry->dispatchInProgress = true;
Jeff Brownd8816c32010-09-16 14:07:33 -0700729 resetTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700730 }
731
732 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
733
734 // Identify targets.
735 if (! mCurrentInputTargetsValid) {
Jeff Browna665ca82010-09-08 11:49:43 -0700736 int32_t injectionResult;
737 if (isPointerEvent) {
738 // Pointer event. (eg. touchscreen)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700739 injectionResult = findTouchedWindowTargetsLocked(currentTime,
740 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700741 } else {
742 // Non touch event. (eg. trackball)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700743 injectionResult = findFocusedWindowTargetsLocked(currentTime,
744 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700745 }
746 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
747 return false;
748 }
749
750 setInjectionResultLocked(entry, injectionResult);
751 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
752 return true;
753 }
754
755 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700756 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700757 }
758
759 // Dispatch the motion.
760 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
761
762 // Poke user activity.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700763 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
764 int32_t eventType;
765 if (isPointerEvent) {
766 switch (entry->action) {
767 case AMOTION_EVENT_ACTION_DOWN:
Jeff Browna665ca82010-09-08 11:49:43 -0700768 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700769 break;
770 case AMOTION_EVENT_ACTION_UP:
771 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
772 break;
773 default:
774 if (entry->eventTime - entry->downTime >= EVENT_IGNORE_DURATION) {
775 eventType = POWER_MANAGER_TOUCH_EVENT;
776 } else {
777 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
778 }
779 break;
Jeff Browna665ca82010-09-08 11:49:43 -0700780 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700781 } else {
782 eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Browna665ca82010-09-08 11:49:43 -0700783 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700784 pokeUserActivityLocked(entry->eventTime, eventType);
Jeff Browna665ca82010-09-08 11:49:43 -0700785 }
Jeff Browna665ca82010-09-08 11:49:43 -0700786 return true;
787}
788
789
790void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
791#if DEBUG_OUTBOUND_EVENT_DETAILS
792 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700793 "action=0x%x, flags=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700794 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700795 prefix,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700796 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
797 entry->action, entry->flags,
Jeff Browne839a582010-04-22 18:58:52 -0700798 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
799 entry->downTime);
800
801 // Print the most recent sample that we have available, this may change due to batching.
802 size_t sampleCount = 1;
Jeff Browna665ca82010-09-08 11:49:43 -0700803 const MotionSample* sample = & entry->firstSample;
Jeff Browne839a582010-04-22 18:58:52 -0700804 for (; sample->next != NULL; sample = sample->next) {
805 sampleCount += 1;
806 }
807 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -0700808 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700809 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -0700810 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -0700811 i, entry->pointerIds[i],
Jeff Brown38a7fab2010-08-30 03:02:23 -0700812 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
813 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
814 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
815 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
816 sample->pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -0700817 }
818
819 // Keep in mind that due to batching, it is possible for the number of samples actually
820 // dispatched to change before the application finally consumed them.
Jeff Brown5c1ed842010-07-14 18:48:53 -0700821 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -0700822 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
823 }
824#endif
Jeff Browne839a582010-04-22 18:58:52 -0700825}
826
827void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
828 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
829#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700830 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700831 "resumeWithAppendedMotionSample=%s",
Jeff Browna665ca82010-09-08 11:49:43 -0700832 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -0700833#endif
834
Jeff Brown54bc2812010-06-15 01:31:58 -0700835 assert(eventEntry->dispatchInProgress); // should already have been set to true
836
Jeff Browne839a582010-04-22 18:58:52 -0700837 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
838 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
839
Jeff Brown53a415e2010-09-15 15:18:56 -0700840 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -0700841 if (connectionIndex >= 0) {
842 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown51d45a72010-06-17 20:52:56 -0700843 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -0700844 resumeWithAppendedMotionSample);
845 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700846#if DEBUG_FOCUS
847 LOGD("Dropping event delivery to target with channel '%s' because it "
848 "is no longer registered with the input dispatcher.",
Jeff Browne839a582010-04-22 18:58:52 -0700849 inputTarget.inputChannel->getName().string());
Jeff Brown90f0cee2010-10-08 22:31:17 -0700850#endif
Jeff Browne839a582010-04-22 18:58:52 -0700851 }
852 }
853}
854
Jeff Brownd8816c32010-09-16 14:07:33 -0700855void InputDispatcher::resetTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700856 mCurrentInputTargetsValid = false;
857 mCurrentInputTargets.clear();
Jeff Browna665ca82010-09-08 11:49:43 -0700858 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
859}
860
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700861void InputDispatcher::commitTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700862 mCurrentInputTargetsValid = true;
863}
864
865int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
866 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
867 nsecs_t* nextWakeupTime) {
868 if (application == NULL && window == NULL) {
869 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
870#if DEBUG_FOCUS
871 LOGD("Waiting for system to become ready for input.");
872#endif
873 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
874 mInputTargetWaitStartTime = currentTime;
875 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
876 mInputTargetWaitTimeoutExpired = false;
877 }
878 } else {
879 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
880#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700881 LOGD("Waiting for application to become ready for input: %s",
882 getApplicationWindowLabelLocked(application, window).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700883#endif
884 nsecs_t timeout = window ? window->dispatchingTimeout :
885 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
886
887 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
888 mInputTargetWaitStartTime = currentTime;
889 mInputTargetWaitTimeoutTime = currentTime + timeout;
890 mInputTargetWaitTimeoutExpired = false;
891 }
892 }
893
894 if (mInputTargetWaitTimeoutExpired) {
895 return INPUT_EVENT_INJECTION_TIMED_OUT;
896 }
897
898 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown53a415e2010-09-15 15:18:56 -0700899 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700900
901 // Force poll loop to wake up immediately on next iteration once we get the
902 // ANR response back from the policy.
903 *nextWakeupTime = LONG_LONG_MIN;
904 return INPUT_EVENT_INJECTION_PENDING;
905 } else {
906 // Force poll loop to wake up when timeout is due.
907 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
908 *nextWakeupTime = mInputTargetWaitTimeoutTime;
909 }
910 return INPUT_EVENT_INJECTION_PENDING;
911 }
912}
913
Jeff Brown53a415e2010-09-15 15:18:56 -0700914void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
915 const sp<InputChannel>& inputChannel) {
Jeff Browna665ca82010-09-08 11:49:43 -0700916 if (newTimeout > 0) {
917 // Extend the timeout.
918 mInputTargetWaitTimeoutTime = now() + newTimeout;
919 } else {
920 // Give up.
921 mInputTargetWaitTimeoutExpired = true;
Jeff Brown53a415e2010-09-15 15:18:56 -0700922
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700923 // Release the touch targets.
924 mTouchState.reset();
Jeff Brown405a1d32010-09-16 12:31:46 -0700925
Jeff Brown53a415e2010-09-15 15:18:56 -0700926 // Input state will not be realistic. Mark it out of sync.
Jeff Brown40ad4702010-09-16 11:02:16 -0700927 if (inputChannel.get()) {
928 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
929 if (connectionIndex >= 0) {
930 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700931 synthesizeCancelationEventsForConnectionLocked(
932 connection, InputState::CANCEL_ALL_EVENTS,
933 "application not responding");
Jeff Brown40ad4702010-09-16 11:02:16 -0700934 }
Jeff Brown53a415e2010-09-15 15:18:56 -0700935 }
Jeff Browna665ca82010-09-08 11:49:43 -0700936 }
937}
938
Jeff Brown53a415e2010-09-15 15:18:56 -0700939nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Browna665ca82010-09-08 11:49:43 -0700940 nsecs_t currentTime) {
941 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
942 return currentTime - mInputTargetWaitStartTime;
943 }
944 return 0;
945}
946
947void InputDispatcher::resetANRTimeoutsLocked() {
948#if DEBUG_FOCUS
949 LOGD("Resetting ANR timeouts.");
950#endif
951
Jeff Browna665ca82010-09-08 11:49:43 -0700952 // Reset input target wait timeout.
953 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
954}
955
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700956int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
957 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -0700958 mCurrentInputTargets.clear();
959
960 int32_t injectionResult;
961
962 // If there is no currently focused window and no focused application
963 // then drop the event.
964 if (! mFocusedWindow) {
965 if (mFocusedApplication) {
966#if DEBUG_FOCUS
967 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -0700968 "focused application that may eventually add a window: %s.",
969 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700970#endif
971 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
972 mFocusedApplication, NULL, nextWakeupTime);
973 goto Unresponsive;
974 }
975
976 LOGI("Dropping event because there is no focused window or focused application.");
977 injectionResult = INPUT_EVENT_INJECTION_FAILED;
978 goto Failed;
979 }
980
981 // Check permissions.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700982 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700983 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
984 goto Failed;
985 }
986
987 // If the currently focused window is paused then keep waiting.
988 if (mFocusedWindow->paused) {
989#if DEBUG_FOCUS
990 LOGD("Waiting because focused window is paused.");
991#endif
992 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
993 mFocusedApplication, mFocusedWindow, nextWakeupTime);
994 goto Unresponsive;
995 }
996
Jeff Brown53a415e2010-09-15 15:18:56 -0700997 // If the currently focused window is still working on previous events then keep waiting.
998 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
999#if DEBUG_FOCUS
1000 LOGD("Waiting because focused window still processing previous input.");
1001#endif
1002 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1003 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1004 goto Unresponsive;
1005 }
1006
Jeff Browna665ca82010-09-08 11:49:43 -07001007 // Success! Output targets.
1008 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001009 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -07001010
1011 // Done.
1012Failed:
1013Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -07001014 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1015 updateDispatchStatisticsLocked(currentTime, entry,
1016 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001017#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -07001018 LOGD("findFocusedWindow finished: injectionResult=%d, "
1019 "timeSpendWaitingForApplication=%0.1fms",
1020 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001021#endif
1022 return injectionResult;
1023}
1024
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001025int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1026 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -07001027 enum InjectionPermission {
1028 INJECTION_PERMISSION_UNKNOWN,
1029 INJECTION_PERMISSION_GRANTED,
1030 INJECTION_PERMISSION_DENIED
1031 };
1032
Jeff Browna665ca82010-09-08 11:49:43 -07001033 mCurrentInputTargets.clear();
1034
1035 nsecs_t startTime = now();
1036
1037 // For security reasons, we defer updating the touch state until we are sure that
1038 // event injection will be allowed.
1039 //
1040 // FIXME In the original code, screenWasOff could never be set to true.
1041 // The reason is that the POLICY_FLAG_WOKE_HERE
1042 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1043 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1044 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1045 // events upon which no preprocessing took place. So policyFlags was always 0.
1046 // In the new native input dispatcher we're a bit more careful about event
1047 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1048 // Unfortunately we obtain undesirable behavior.
1049 //
1050 // Here's what happens:
1051 //
1052 // When the device dims in anticipation of going to sleep, touches
1053 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1054 // the device to brighten and reset the user activity timer.
1055 // Touches on other windows (such as the launcher window)
1056 // are dropped. Then after a moment, the device goes to sleep. Oops.
1057 //
1058 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1059 // instead of POLICY_FLAG_WOKE_HERE...
1060 //
1061 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1062
1063 int32_t action = entry->action;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001064 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Browna665ca82010-09-08 11:49:43 -07001065
1066 // Update the touch state as needed based on the properties of the touch event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001067 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1068 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1069 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1070 mTempTouchState.reset();
1071 mTempTouchState.down = true;
1072 } else {
1073 mTempTouchState.copyFrom(mTouchState);
1074 }
Jeff Browna665ca82010-09-08 11:49:43 -07001075
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001076 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1077 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1078 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1079 /* Case 1: New splittable pointer going down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001080
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001081 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1082 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1083 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1084 const InputWindow* newTouchedWindow = NULL;
1085 const InputWindow* topErrorWindow = NULL;
Jeff Browna665ca82010-09-08 11:49:43 -07001086
1087 // Traverse windows from front to back to find touched window and outside targets.
1088 size_t numWindows = mWindows.size();
1089 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001090 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07001091 int32_t flags = window->layoutParamsFlags;
1092
1093 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1094 if (! topErrorWindow) {
1095 topErrorWindow = window;
1096 }
1097 }
1098
1099 if (window->visible) {
1100 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1101 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1102 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1103 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1104 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1105 newTouchedWindow = window;
Jeff Browna665ca82010-09-08 11:49:43 -07001106 }
1107 break; // found touched window, exit window loop
1108 }
1109 }
1110
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001111 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1112 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001113 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1114 if (isWindowObscuredAtPointLocked(window, x, y)) {
1115 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1116 }
1117
1118 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -07001119 }
1120 }
1121 }
1122
1123 // If there is an error window but it is not taking focus (typically because
1124 // it is invisible) then wait for it. Any other focused window may in
1125 // fact be in ANR state.
1126 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1127#if DEBUG_FOCUS
1128 LOGD("Waiting because system error window is pending.");
1129#endif
1130 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1131 NULL, NULL, nextWakeupTime);
1132 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1133 goto Unresponsive;
1134 }
1135
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001136 // Figure out whether splitting will be allowed for this window.
Jeff Brown1c322582010-09-28 13:24:41 -07001137 if (newTouchedWindow
1138 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001139 // New window supports splitting.
1140 isSplit = true;
1141 } else if (isSplit) {
1142 // New window does not support splitting but we have already split events.
1143 // Assign the pointer to the first foreground window we find.
1144 // (May be NULL which is why we put this code block before the next check.)
1145 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1146 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001147
Jeff Browna665ca82010-09-08 11:49:43 -07001148 // If we did not find a touched window then fail.
1149 if (! newTouchedWindow) {
1150 if (mFocusedApplication) {
1151#if DEBUG_FOCUS
1152 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -07001153 "focused application that may eventually add a new window: %s.",
1154 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -07001155#endif
1156 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1157 mFocusedApplication, NULL, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -07001158 goto Unresponsive;
1159 }
1160
1161 LOGI("Dropping event because there is no touched window or focused application.");
1162 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001163 goto Failed;
1164 }
1165
Jeff Brown35cf0e92010-10-05 12:26:23 -07001166 // Set target flags.
1167 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1168 if (isSplit) {
1169 targetFlags |= InputTarget::FLAG_SPLIT;
1170 }
1171 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1172 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1173 }
1174
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001175 // Update the temporary touch state.
1176 BitSet32 pointerIds;
1177 if (isSplit) {
1178 uint32_t pointerId = entry->pointerIds[pointerIndex];
1179 pointerIds.markBit(pointerId);
Jeff Browna665ca82010-09-08 11:49:43 -07001180 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001181 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001182 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001183 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001184
1185 // If the pointer is not currently down, then ignore the event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001186 if (! mTempTouchState.down) {
Jeff Browna665ca82010-09-08 11:49:43 -07001187 LOGI("Dropping event because the pointer is not down.");
1188 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001189 goto Failed;
1190 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001191 }
Jeff Browna665ca82010-09-08 11:49:43 -07001192
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001193 // Check permission to inject into all touched foreground windows and ensure there
1194 // is at least one touched foreground window.
1195 {
1196 bool haveForegroundWindow = false;
1197 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1198 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1199 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1200 haveForegroundWindow = true;
1201 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1202 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1203 injectionPermission = INJECTION_PERMISSION_DENIED;
1204 goto Failed;
1205 }
1206 }
1207 }
1208 if (! haveForegroundWindow) {
Jeff Browna665ca82010-09-08 11:49:43 -07001209#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001210 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Browna665ca82010-09-08 11:49:43 -07001211#endif
1212 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001213 goto Failed;
1214 }
1215
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001216 // Permission granted to injection into all touched foreground windows.
1217 injectionPermission = INJECTION_PERMISSION_GRANTED;
1218 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001219
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001220 // Ensure all touched foreground windows are ready for new input.
1221 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1222 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1223 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1224 // If the touched window is paused then keep waiting.
1225 if (touchedWindow.window->paused) {
1226#if DEBUG_INPUT_DISPATCHER_POLICY
1227 LOGD("Waiting because touched window is paused.");
Jeff Brown53a415e2010-09-15 15:18:56 -07001228#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001229 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1230 NULL, touchedWindow.window, nextWakeupTime);
1231 goto Unresponsive;
1232 }
1233
1234 // If the touched window is still working on previous events then keep waiting.
1235 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1236#if DEBUG_FOCUS
1237 LOGD("Waiting because touched window still processing previous input.");
1238#endif
1239 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1240 NULL, touchedWindow.window, nextWakeupTime);
1241 goto Unresponsive;
1242 }
1243 }
1244 }
1245
1246 // If this is the first pointer going down and the touched window has a wallpaper
1247 // then also add the touched wallpaper windows so they are locked in for the duration
1248 // of the touch gesture.
1249 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1250 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1251 if (foregroundWindow->hasWallpaper) {
1252 for (size_t i = 0; i < mWindows.size(); i++) {
1253 const InputWindow* window = & mWindows[i];
1254 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001255 mTempTouchState.addOrUpdateWindow(window,
1256 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001257 }
1258 }
1259 }
1260 }
1261
Jeff Browna665ca82010-09-08 11:49:43 -07001262 // Success! Output targets.
1263 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Browna665ca82010-09-08 11:49:43 -07001264
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001265 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1266 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1267 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1268 touchedWindow.pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001269 }
1270
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001271 // Drop the outside touch window since we will not care about them in the next iteration.
1272 mTempTouchState.removeOutsideTouchWindows();
1273
Jeff Browna665ca82010-09-08 11:49:43 -07001274Failed:
1275 // Check injection permission once and for all.
1276 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001277 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001278 injectionPermission = INJECTION_PERMISSION_GRANTED;
1279 } else {
1280 injectionPermission = INJECTION_PERMISSION_DENIED;
1281 }
1282 }
1283
1284 // Update final pieces of touch state if the injector had permission.
1285 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001286 if (maskedAction == AMOTION_EVENT_ACTION_UP
1287 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1288 // All pointers up or canceled.
1289 mTempTouchState.reset();
1290 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1291 // First pointer went down.
1292 if (mTouchState.down) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001293#if DEBUG_FOCUS
1294 LOGD("Pointer down received while already down.");
1295#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001296 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001297 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1298 // One pointer went up.
1299 if (isSplit) {
1300 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1301 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Browna665ca82010-09-08 11:49:43 -07001302
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001303 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1304 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1305 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1306 touchedWindow.pointerIds.clearBit(pointerId);
1307 if (touchedWindow.pointerIds.isEmpty()) {
1308 mTempTouchState.windows.removeAt(i);
1309 continue;
1310 }
1311 }
1312 i += 1;
1313 }
Jeff Browna665ca82010-09-08 11:49:43 -07001314 }
Jeff Browna665ca82010-09-08 11:49:43 -07001315 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001316
1317 // Save changes to touch state.
1318 mTouchState.copyFrom(mTempTouchState);
Jeff Browna665ca82010-09-08 11:49:43 -07001319 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001320#if DEBUG_FOCUS
1321 LOGD("Not updating touch focus because injection was denied.");
1322#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001323 }
1324
1325Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -07001326 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1327 updateDispatchStatisticsLocked(currentTime, entry,
1328 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001329#if DEBUG_FOCUS
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001330 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1331 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown53a415e2010-09-15 15:18:56 -07001332 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001333#endif
1334 return injectionResult;
1335}
1336
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001337void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1338 BitSet32 pointerIds) {
Jeff Browna665ca82010-09-08 11:49:43 -07001339 mCurrentInputTargets.push();
1340
1341 InputTarget& target = mCurrentInputTargets.editTop();
1342 target.inputChannel = window->inputChannel;
1343 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001344 target.xOffset = - window->frameLeft;
1345 target.yOffset = - window->frameTop;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001346 target.windowType = window->layoutParamsType;
1347 target.pointerIds = pointerIds;
Jeff Browna665ca82010-09-08 11:49:43 -07001348}
1349
1350void InputDispatcher::addMonitoringTargetsLocked() {
1351 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1352 mCurrentInputTargets.push();
1353
1354 InputTarget& target = mCurrentInputTargets.editTop();
1355 target.inputChannel = mMonitoringChannels[i];
1356 target.flags = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07001357 target.xOffset = 0;
1358 target.yOffset = 0;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001359 target.windowType = InputWindow::TYPE_SYSTEM_OVERLAY;
Jeff Browna665ca82010-09-08 11:49:43 -07001360 }
1361}
1362
1363bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001364 const InjectionState* injectionState) {
1365 if (injectionState
Jeff Brown90f0cee2010-10-08 22:31:17 -07001366 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1367 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1368 if (window) {
1369 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1370 "with input channel %s owned by uid %d",
1371 injectionState->injectorPid, injectionState->injectorUid,
1372 window->inputChannel->getName().string(),
1373 window->ownerUid);
1374 } else {
1375 LOGW("Permission denied: injecting event from pid %d uid %d",
1376 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-09-08 11:49:43 -07001377 }
Jeff Brown90f0cee2010-10-08 22:31:17 -07001378 return false;
Jeff Browna665ca82010-09-08 11:49:43 -07001379 }
1380 return true;
1381}
1382
Jeff Brown35cf0e92010-10-05 12:26:23 -07001383bool InputDispatcher::isWindowObscuredAtPointLocked(
1384 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Browna665ca82010-09-08 11:49:43 -07001385 size_t numWindows = mWindows.size();
1386 for (size_t i = 0; i < numWindows; i++) {
1387 const InputWindow* other = & mWindows.itemAt(i);
1388 if (other == window) {
1389 break;
1390 }
Jeff Brown35cf0e92010-10-05 12:26:23 -07001391 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001392 return true;
1393 }
1394 }
1395 return false;
1396}
1397
Jeff Brown53a415e2010-09-15 15:18:56 -07001398bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1399 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1400 if (connectionIndex >= 0) {
1401 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1402 return connection->outboundQueue.isEmpty();
1403 } else {
1404 return true;
1405 }
1406}
1407
1408String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1409 const InputWindow* window) {
1410 if (application) {
1411 if (window) {
1412 String8 label(application->name);
1413 label.append(" - ");
1414 label.append(window->name);
1415 return label;
1416 } else {
1417 return application->name;
1418 }
1419 } else if (window) {
1420 return window->name;
1421 } else {
1422 return String8("<unknown application or window>");
1423 }
1424}
1425
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001426bool InputDispatcher::shouldPokeUserActivityForCurrentInputTargetsLocked() {
1427 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
1428 if (mCurrentInputTargets[i].windowType == InputWindow::TYPE_KEYGUARD) {
1429 return false;
1430 }
1431 }
1432 return true;
1433}
1434
1435void InputDispatcher::pokeUserActivityLocked(nsecs_t eventTime, int32_t eventType) {
Jeff Browna665ca82010-09-08 11:49:43 -07001436 CommandEntry* commandEntry = postCommandLocked(
1437 & InputDispatcher::doPokeUserActivityLockedInterruptible);
1438 commandEntry->eventTime = eventTime;
Jeff Browna665ca82010-09-08 11:49:43 -07001439 commandEntry->userActivityEventType = eventType;
1440}
1441
Jeff Brown51d45a72010-06-17 20:52:56 -07001442void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1443 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -07001444 bool resumeWithAppendedMotionSample) {
1445#if DEBUG_DISPATCH_CYCLE
Jeff Brown53a415e2010-09-15 15:18:56 -07001446 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001447 "xOffset=%f, yOffset=%f, "
1448 "windowType=%d, pointerIds=0x%x, "
1449 "resumeWithAppendedMotionSample=%s",
Jeff Brown53a415e2010-09-15 15:18:56 -07001450 connection->getInputChannelName(), inputTarget->flags,
Jeff Browne839a582010-04-22 18:58:52 -07001451 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001452 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Browna665ca82010-09-08 11:49:43 -07001453 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -07001454#endif
1455
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001456 // Make sure we are never called for streaming when splitting across multiple windows.
1457 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1458 assert(! (resumeWithAppendedMotionSample && isSplit));
1459
Jeff Browne839a582010-04-22 18:58:52 -07001460 // Skip this event if the connection status is not normal.
Jeff Brown53a415e2010-09-15 15:18:56 -07001461 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Browne839a582010-04-22 18:58:52 -07001462 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001463#if DEBUG_DISPATCH_CYCLE
1464 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Browna665ca82010-09-08 11:49:43 -07001465 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown90f0cee2010-10-08 22:31:17 -07001466#endif
Jeff Browne839a582010-04-22 18:58:52 -07001467 return;
1468 }
1469
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001470 // Split a motion event if needed.
1471 if (isSplit) {
1472 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1473
1474 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1475 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1476 MotionEntry* splitMotionEntry = splitMotionEvent(
1477 originalMotionEntry, inputTarget->pointerIds);
1478#if DEBUG_FOCUS
1479 LOGD("channel '%s' ~ Split motion event.",
1480 connection->getInputChannelName());
1481 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1482#endif
1483 eventEntry = splitMotionEntry;
1484 }
1485 }
1486
Jeff Browne839a582010-04-22 18:58:52 -07001487 // Resume the dispatch cycle with a freshly appended motion sample.
1488 // First we check that the last dispatch entry in the outbound queue is for the same
1489 // motion event to which we appended the motion sample. If we find such a dispatch
1490 // entry, and if it is currently in progress then we try to stream the new sample.
1491 bool wasEmpty = connection->outboundQueue.isEmpty();
1492
1493 if (! wasEmpty && resumeWithAppendedMotionSample) {
1494 DispatchEntry* motionEventDispatchEntry =
1495 connection->findQueuedDispatchEntryForEvent(eventEntry);
1496 if (motionEventDispatchEntry) {
1497 // If the dispatch entry is not in progress, then we must be busy dispatching an
1498 // earlier event. Not a problem, the motion event is on the outbound queue and will
1499 // be dispatched later.
1500 if (! motionEventDispatchEntry->inProgress) {
1501#if DEBUG_BATCHING
1502 LOGD("channel '%s' ~ Not streaming because the motion event has "
1503 "not yet been dispatched. "
1504 "(Waiting for earlier events to be consumed.)",
1505 connection->getInputChannelName());
1506#endif
1507 return;
1508 }
1509
1510 // If the dispatch entry is in progress but it already has a tail of pending
1511 // motion samples, then it must mean that the shared memory buffer filled up.
1512 // Not a problem, when this dispatch cycle is finished, we will eventually start
1513 // a new dispatch cycle to process the tail and that tail includes the newly
1514 // appended motion sample.
1515 if (motionEventDispatchEntry->tailMotionSample) {
1516#if DEBUG_BATCHING
1517 LOGD("channel '%s' ~ Not streaming because no new samples can "
1518 "be appended to the motion event in this dispatch cycle. "
1519 "(Waiting for next dispatch cycle to start.)",
1520 connection->getInputChannelName());
1521#endif
1522 return;
1523 }
1524
1525 // The dispatch entry is in progress and is still potentially open for streaming.
1526 // Try to stream the new motion sample. This might fail if the consumer has already
1527 // consumed the motion event (or if the channel is broken).
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001528 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1529 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Browne839a582010-04-22 18:58:52 -07001530 status_t status = connection->inputPublisher.appendMotionSample(
1531 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1532 if (status == OK) {
1533#if DEBUG_BATCHING
1534 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1535 connection->getInputChannelName());
1536#endif
1537 return;
1538 }
1539
1540#if DEBUG_BATCHING
1541 if (status == NO_MEMORY) {
1542 LOGD("channel '%s' ~ Could not append motion sample to currently "
1543 "dispatched move event because the shared memory buffer is full. "
1544 "(Waiting for next dispatch cycle to start.)",
1545 connection->getInputChannelName());
1546 } else if (status == status_t(FAILED_TRANSACTION)) {
1547 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown50de30a2010-06-22 01:27:15 -07001548 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-04-22 18:58:52 -07001549 "(Waiting for next dispatch cycle to start.)",
1550 connection->getInputChannelName());
1551 } else {
1552 LOGD("channel '%s' ~ Could not append motion sample to currently "
1553 "dispatched move event due to an error, status=%d. "
1554 "(Waiting for next dispatch cycle to start.)",
1555 connection->getInputChannelName(), status);
1556 }
1557#endif
1558 // Failed to stream. Start a new tail of pending motion samples to dispatch
1559 // in the next cycle.
1560 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1561 return;
1562 }
1563 }
1564
1565 // This is a new event.
1566 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Browna665ca82010-09-08 11:49:43 -07001567 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown53a415e2010-09-15 15:18:56 -07001568 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1569 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001570 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001571 }
1572
Jeff Browne839a582010-04-22 18:58:52 -07001573 // Handle the case where we could not stream a new motion sample because the consumer has
1574 // already consumed the motion event (otherwise the corresponding dispatch entry would
1575 // still be in the outbound queue for this connection). We set the head motion sample
1576 // to the list starting with the newly appended motion sample.
1577 if (resumeWithAppendedMotionSample) {
1578#if DEBUG_BATCHING
1579 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1580 "that cannot be streamed because the motion event has already been consumed.",
1581 connection->getInputChannelName());
1582#endif
1583 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1584 dispatchEntry->headMotionSample = appendedMotionSample;
1585 }
1586
1587 // Enqueue the dispatch entry.
1588 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1589
1590 // If the outbound queue was previously empty, start the dispatch cycle going.
1591 if (wasEmpty) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001592 activateConnectionLocked(connection.get());
Jeff Brown53a415e2010-09-15 15:18:56 -07001593 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001594 }
1595}
1596
Jeff Brown51d45a72010-06-17 20:52:56 -07001597void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown53a415e2010-09-15 15:18:56 -07001598 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001599#if DEBUG_DISPATCH_CYCLE
1600 LOGD("channel '%s' ~ startDispatchCycle",
1601 connection->getInputChannelName());
1602#endif
1603
1604 assert(connection->status == Connection::STATUS_NORMAL);
1605 assert(! connection->outboundQueue.isEmpty());
1606
Jeff Browna665ca82010-09-08 11:49:43 -07001607 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001608 assert(! dispatchEntry->inProgress);
1609
Jeff Browna665ca82010-09-08 11:49:43 -07001610 // Mark the dispatch entry as in progress.
1611 dispatchEntry->inProgress = true;
1612
1613 // Update the connection's input state.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001614 EventEntry* eventEntry = dispatchEntry->eventEntry;
1615 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001616
1617#if FILTER_INPUT_EVENTS
1618 // Filter out inconsistent sequences of input events.
1619 // The input system may drop or inject events in a way that could violate implicit
1620 // invariants on input state and potentially cause an application to crash
1621 // or think that a key or pointer is stuck down. Technically we make no guarantees
1622 // of consistency but it would be nice to improve on this where possible.
1623 // XXX: This code is a proof of concept only. Not ready for prime time.
1624 if (consistency == InputState::TOLERABLE) {
1625#if DEBUG_DISPATCH_CYCLE
1626 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1627 "current input state but that is likely to be tolerated by the application.",
1628 connection->getInputChannelName());
1629#endif
1630 } else if (consistency == InputState::BROKEN) {
1631 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1632 "current input state and that is likely to cause the application to crash.",
1633 connection->getInputChannelName());
1634 startNextDispatchCycleLocked(currentTime, connection);
1635 return;
1636 }
1637#endif
Jeff Browne839a582010-04-22 18:58:52 -07001638
1639 // Publish the event.
1640 status_t status;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001641 switch (eventEntry->type) {
Jeff Browne839a582010-04-22 18:58:52 -07001642 case EventEntry::TYPE_KEY: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001643 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001644
1645 // Apply target flags.
1646 int32_t action = keyEntry->action;
1647 int32_t flags = keyEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001648
1649 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001650 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-04-22 18:58:52 -07001651 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1652 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1653 keyEntry->eventTime);
1654
1655 if (status) {
1656 LOGE("channel '%s' ~ Could not publish key event, "
1657 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001658 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001659 return;
1660 }
1661 break;
1662 }
1663
1664 case EventEntry::TYPE_MOTION: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001665 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001666
1667 // Apply target flags.
1668 int32_t action = motionEntry->action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07001669 int32_t flags = motionEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001670 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001671 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -07001672 }
Jeff Brownaf30ff62010-09-01 17:01:00 -07001673 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1674 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1675 }
Jeff Browne839a582010-04-22 18:58:52 -07001676
1677 // If headMotionSample is non-NULL, then it points to the first new sample that we
1678 // were unable to dispatch during the previous cycle so we resume dispatching from
1679 // that point in the list of motion samples.
1680 // Otherwise, we just start from the first sample of the motion event.
1681 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1682 if (! firstMotionSample) {
1683 firstMotionSample = & motionEntry->firstSample;
1684 }
1685
Jeff Brownf26db0d2010-07-16 17:21:06 -07001686 // Set the X and Y offset depending on the input source.
1687 float xOffset, yOffset;
1688 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1689 xOffset = dispatchEntry->xOffset;
1690 yOffset = dispatchEntry->yOffset;
1691 } else {
1692 xOffset = 0.0f;
1693 yOffset = 0.0f;
1694 }
1695
Jeff Browne839a582010-04-22 18:58:52 -07001696 // Publish the motion event and the first motion sample.
1697 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001698 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -07001699 xOffset, yOffset,
Jeff Browne839a582010-04-22 18:58:52 -07001700 motionEntry->xPrecision, motionEntry->yPrecision,
1701 motionEntry->downTime, firstMotionSample->eventTime,
1702 motionEntry->pointerCount, motionEntry->pointerIds,
1703 firstMotionSample->pointerCoords);
1704
1705 if (status) {
1706 LOGE("channel '%s' ~ Could not publish motion event, "
1707 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001708 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001709 return;
1710 }
1711
1712 // Append additional motion samples.
1713 MotionSample* nextMotionSample = firstMotionSample->next;
1714 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1715 status = connection->inputPublisher.appendMotionSample(
1716 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1717 if (status == NO_MEMORY) {
1718#if DEBUG_DISPATCH_CYCLE
1719 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1720 "be sent in the next dispatch cycle.",
1721 connection->getInputChannelName());
1722#endif
1723 break;
1724 }
1725 if (status != OK) {
1726 LOGE("channel '%s' ~ Could not append motion sample "
1727 "for a reason other than out of memory, status=%d",
1728 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001729 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001730 return;
1731 }
1732 }
1733
1734 // Remember the next motion sample that we could not dispatch, in case we ran out
1735 // of space in the shared memory buffer.
1736 dispatchEntry->tailMotionSample = nextMotionSample;
1737 break;
1738 }
1739
1740 default: {
1741 assert(false);
1742 }
1743 }
1744
1745 // Send the dispatch signal.
1746 status = connection->inputPublisher.sendDispatchSignal();
1747 if (status) {
1748 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1749 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001750 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001751 return;
1752 }
1753
1754 // Record information about the newly started dispatch cycle.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001755 connection->lastEventTime = eventEntry->eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07001756 connection->lastDispatchTime = currentTime;
1757
Jeff Browne839a582010-04-22 18:58:52 -07001758 // Notify other system components.
1759 onDispatchCycleStartedLocked(currentTime, connection);
1760}
1761
Jeff Brown51d45a72010-06-17 20:52:56 -07001762void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1763 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001764#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001765 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -07001766 "%01.1fms since dispatch",
1767 connection->getInputChannelName(),
1768 connection->getEventLatencyMillis(currentTime),
1769 connection->getDispatchLatencyMillis(currentTime));
1770#endif
1771
Jeff Brown54bc2812010-06-15 01:31:58 -07001772 if (connection->status == Connection::STATUS_BROKEN
1773 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001774 return;
1775 }
1776
Jeff Brown53a415e2010-09-15 15:18:56 -07001777 // Notify other system components.
1778 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001779
1780 // Reset the publisher since the event has been consumed.
1781 // We do this now so that the publisher can release some of its internal resources
1782 // while waiting for the next dispatch cycle to begin.
1783 status_t status = connection->inputPublisher.reset();
1784 if (status) {
1785 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1786 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001787 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001788 return;
1789 }
1790
Jeff Browna665ca82010-09-08 11:49:43 -07001791 startNextDispatchCycleLocked(currentTime, connection);
1792}
1793
1794void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1795 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001796 // Start the next dispatch cycle for this connection.
1797 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001798 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001799 if (dispatchEntry->inProgress) {
1800 // Finish or resume current event in progress.
1801 if (dispatchEntry->tailMotionSample) {
1802 // We have a tail of undispatched motion samples.
1803 // Reuse the same DispatchEntry and start a new cycle.
1804 dispatchEntry->inProgress = false;
1805 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1806 dispatchEntry->tailMotionSample = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07001807 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001808 return;
1809 }
1810 // Finished.
1811 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001812 if (dispatchEntry->hasForegroundTarget()) {
1813 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001814 }
Jeff Browne839a582010-04-22 18:58:52 -07001815 mAllocator.releaseDispatchEntry(dispatchEntry);
1816 } else {
1817 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown53a415e2010-09-15 15:18:56 -07001818 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001819 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001820 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001821 return;
1822 }
1823 }
1824
1825 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001826 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001827}
1828
Jeff Brown90f0cee2010-10-08 22:31:17 -07001829void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1830 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001831#if DEBUG_DISPATCH_CYCLE
Jeff Brown90f0cee2010-10-08 22:31:17 -07001832 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001833 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001834#endif
1835
Jeff Browna665ca82010-09-08 11:49:43 -07001836 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001837 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001838
Jeff Brown90f0cee2010-10-08 22:31:17 -07001839 // The connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001840 // Ignore already broken or zombie connections.
Jeff Brown90f0cee2010-10-08 22:31:17 -07001841 if (connection->status == Connection::STATUS_NORMAL) {
1842 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001843
Jeff Brown90f0cee2010-10-08 22:31:17 -07001844 // Notify other system components.
1845 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001846 }
Jeff Browne839a582010-04-22 18:58:52 -07001847}
1848
Jeff Brown53a415e2010-09-15 15:18:56 -07001849void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1850 while (! connection->outboundQueue.isEmpty()) {
1851 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1852 if (dispatchEntry->hasForegroundTarget()) {
1853 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001854 }
1855 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001856 }
1857
Jeff Brown53a415e2010-09-15 15:18:56 -07001858 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001859}
1860
Jeff Brown59abe7e2010-09-13 23:17:30 -07001861int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-04-22 18:58:52 -07001862 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1863
1864 { // acquire lock
1865 AutoMutex _l(d->mLock);
1866
1867 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1868 if (connectionIndex < 0) {
1869 LOGE("Received spurious receive callback for unknown input channel. "
1870 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001871 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001872 }
1873
Jeff Brown51d45a72010-06-17 20:52:56 -07001874 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001875
1876 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001877 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-04-22 18:58:52 -07001878 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1879 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001880 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001881 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001882 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001883 }
1884
Jeff Brown59abe7e2010-09-13 23:17:30 -07001885 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001886 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1887 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001888 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001889 }
1890
1891 status_t status = connection->inputPublisher.receiveFinishedSignal();
1892 if (status) {
1893 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1894 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001895 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001896 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001897 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001898 }
1899
Jeff Brown51d45a72010-06-17 20:52:56 -07001900 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001901 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001902 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001903 } // release lock
1904}
1905
Jeff Brown90f0cee2010-10-08 22:31:17 -07001906void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1907 InputState::CancelationOptions options, const char* reason) {
1908 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1909 synthesizeCancelationEventsForConnectionLocked(
1910 mConnectionsByReceiveFd.valueAt(i), options, reason);
1911 }
1912}
1913
1914void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1915 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1916 const char* reason) {
1917 ssize_t index = getConnectionIndexLocked(channel);
1918 if (index >= 0) {
1919 synthesizeCancelationEventsForConnectionLocked(
1920 mConnectionsByReceiveFd.valueAt(index), options, reason);
1921 }
1922}
1923
1924void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1925 const sp<Connection>& connection, InputState::CancelationOptions options,
1926 const char* reason) {
1927 nsecs_t currentTime = now();
1928
1929 mTempCancelationEvents.clear();
1930 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1931 mTempCancelationEvents, options);
1932
1933 if (! mTempCancelationEvents.isEmpty()
1934 && connection->status != Connection::STATUS_BROKEN) {
1935#if DEBUG_OUTBOUND_EVENT_DETAILS
1936 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1937 "with reality: %s, options=%d.",
1938 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1939#endif
1940 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1941 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1942 switch (cancelationEventEntry->type) {
1943 case EventEntry::TYPE_KEY:
1944 logOutboundKeyDetailsLocked("cancel - ",
1945 static_cast<KeyEntry*>(cancelationEventEntry));
1946 break;
1947 case EventEntry::TYPE_MOTION:
1948 logOutboundMotionDetailsLocked("cancel - ",
1949 static_cast<MotionEntry*>(cancelationEventEntry));
1950 break;
1951 }
1952
1953 int32_t xOffset, yOffset;
1954 const InputWindow* window = getWindowLocked(connection->inputChannel);
1955 if (window) {
1956 xOffset = -window->frameLeft;
1957 yOffset = -window->frameTop;
1958 } else {
1959 xOffset = 0;
1960 yOffset = 0;
1961 }
1962
1963 DispatchEntry* cancelationDispatchEntry =
1964 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1965 0, xOffset, yOffset);
1966 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1967
1968 mAllocator.releaseEventEntry(cancelationEventEntry);
1969 }
1970
1971 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1972 startDispatchCycleLocked(currentTime, connection);
1973 }
1974 }
1975}
1976
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001977InputDispatcher::MotionEntry*
1978InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1979 assert(pointerIds.value != 0);
1980
1981 uint32_t splitPointerIndexMap[MAX_POINTERS];
1982 int32_t splitPointerIds[MAX_POINTERS];
1983 PointerCoords splitPointerCoords[MAX_POINTERS];
1984
1985 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1986 uint32_t splitPointerCount = 0;
1987
1988 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1989 originalPointerIndex++) {
1990 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1991 if (pointerIds.hasBit(pointerId)) {
1992 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1993 splitPointerIds[splitPointerCount] = pointerId;
1994 splitPointerCoords[splitPointerCount] =
1995 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1996 splitPointerCount += 1;
1997 }
1998 }
1999 assert(splitPointerCount == pointerIds.count());
2000
2001 int32_t action = originalMotionEntry->action;
2002 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2003 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2004 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2005 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2006 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2007 if (pointerIds.hasBit(pointerId)) {
2008 if (pointerIds.count() == 1) {
2009 // The first/last pointer went down/up.
2010 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2011 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brownffb16d62010-09-27 16:35:11 -07002012 } else {
2013 // A secondary pointer went down/up.
2014 uint32_t splitPointerIndex = 0;
2015 while (pointerId != splitPointerIds[splitPointerIndex]) {
2016 splitPointerIndex += 1;
2017 }
2018 action = maskedAction | (splitPointerIndex
2019 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002020 }
2021 } else {
2022 // An unrelated pointer changed.
2023 action = AMOTION_EVENT_ACTION_MOVE;
2024 }
2025 }
2026
2027 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2028 originalMotionEntry->eventTime,
2029 originalMotionEntry->deviceId,
2030 originalMotionEntry->source,
2031 originalMotionEntry->policyFlags,
2032 action,
2033 originalMotionEntry->flags,
2034 originalMotionEntry->metaState,
2035 originalMotionEntry->edgeFlags,
2036 originalMotionEntry->xPrecision,
2037 originalMotionEntry->yPrecision,
2038 originalMotionEntry->downTime,
2039 splitPointerCount, splitPointerIds, splitPointerCoords);
2040
2041 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2042 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2043 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2044 splitPointerIndex++) {
2045 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2046 splitPointerCoords[splitPointerIndex] =
2047 originalMotionSample->pointerCoords[originalPointerIndex];
2048 }
2049
2050 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2051 splitPointerCoords);
2052 }
2053
2054 return splitMotionEntry;
2055}
2056
Jeff Brown54bc2812010-06-15 01:31:58 -07002057void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002058#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -07002059 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07002060#endif
2061
Jeff Browna665ca82010-09-08 11:49:43 -07002062 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002063 { // acquire lock
2064 AutoMutex _l(mLock);
2065
Jeff Brown51d45a72010-06-17 20:52:56 -07002066 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browna665ca82010-09-08 11:49:43 -07002067 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002068 } // release lock
2069
Jeff Browna665ca82010-09-08 11:49:43 -07002070 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002071 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002072 }
2073}
2074
Jeff Brown5c1ed842010-07-14 18:48:53 -07002075void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -07002076 uint32_t policyFlags, int32_t action, int32_t flags,
2077 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2078#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002079 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07002080 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07002081 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -07002082 keyCode, scanCode, metaState, downTime);
2083#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002084 if (! validateKeyEvent(action)) {
2085 return;
2086 }
Jeff Browne839a582010-04-22 18:58:52 -07002087
Jeff Brown90f0cee2010-10-08 22:31:17 -07002088 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2089 keyCode, scanCode, /*byref*/ policyFlags);
2090
Jeff Browna665ca82010-09-08 11:49:43 -07002091 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002092 { // acquire lock
2093 AutoMutex _l(mLock);
2094
Jeff Brown51d45a72010-06-17 20:52:56 -07002095 int32_t repeatCount = 0;
2096 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002097 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07002098 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07002099
Jeff Browna665ca82010-09-08 11:49:43 -07002100 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002101 } // release lock
2102
Jeff Browna665ca82010-09-08 11:49:43 -07002103 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002104 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002105 }
2106}
2107
Jeff Brown5c1ed842010-07-14 18:48:53 -07002108void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002109 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002110 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2111 float xPrecision, float yPrecision, nsecs_t downTime) {
2112#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002113 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002114 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2115 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2116 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002117 xPrecision, yPrecision, downTime);
2118 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07002119 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002120 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07002121 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07002122 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-08-30 03:02:23 -07002123 pointerCoords[i].pressure, pointerCoords[i].size,
2124 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2125 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2126 pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -07002127 }
2128#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002129 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2130 return;
2131 }
Jeff Browne839a582010-04-22 18:58:52 -07002132
Jeff Brown90f0cee2010-10-08 22:31:17 -07002133 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2134
Jeff Browna665ca82010-09-08 11:49:43 -07002135 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002136 { // acquire lock
2137 AutoMutex _l(mLock);
2138
2139 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07002140 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07002141 // BATCHING CASE
2142 //
2143 // Try to append a move sample to the tail of the inbound queue for this device.
2144 // Give up if we encounter a non-move motion event for this device since that
2145 // means we cannot append any new samples until a new motion event has started.
Jeff Browna665ca82010-09-08 11:49:43 -07002146 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2147 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07002148 if (entry->type != EventEntry::TYPE_MOTION) {
2149 // Keep looking for motion events.
2150 continue;
2151 }
2152
2153 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2154 if (motionEntry->deviceId != deviceId) {
2155 // Keep looking for this device.
2156 continue;
2157 }
2158
Jeff Brown5c1ed842010-07-14 18:48:53 -07002159 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07002160 || motionEntry->pointerCount != pointerCount
2161 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07002162 // Last motion event in the queue for this device is not compatible for
2163 // appending new samples. Stop here.
2164 goto NoBatchingOrStreaming;
2165 }
2166
2167 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07002168 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07002169 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002170#if DEBUG_BATCHING
2171 LOGD("Appended motion sample onto batch for most recent "
2172 "motion event for this device in the inbound queue.");
2173#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07002174 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002175 }
2176
2177 // STREAMING CASE
2178 //
2179 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07002180 // Search the outbound queue for the current foreground targets to find a dispatched
2181 // motion event that is still in progress. If found, then, appen the new sample to
2182 // that event and push it out to all current targets. The logic in
2183 // prepareDispatchCycleLocked takes care of the case where some targets may
2184 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown54bc2812010-06-15 01:31:58 -07002185 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002186 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2187 const InputTarget& inputTarget = mCurrentInputTargets[i];
2188 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2189 // Skip non-foreground targets. We only want to stream if there is at
2190 // least one foreground target whose dispatch is still in progress.
2191 continue;
Jeff Browne839a582010-04-22 18:58:52 -07002192 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002193
2194 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2195 if (connectionIndex < 0) {
2196 // Connection must no longer be valid.
2197 continue;
2198 }
2199
2200 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2201 if (connection->outboundQueue.isEmpty()) {
2202 // This foreground target has an empty outbound queue.
2203 continue;
2204 }
2205
2206 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2207 if (! dispatchEntry->inProgress
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002208 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2209 || dispatchEntry->isSplit()) {
2210 // No motion event is being dispatched, or it is being split across
2211 // windows in which case we cannot stream.
Jeff Brown53a415e2010-09-15 15:18:56 -07002212 continue;
2213 }
2214
2215 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2216 dispatchEntry->eventEntry);
2217 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2218 || motionEntry->deviceId != deviceId
2219 || motionEntry->pointerCount != pointerCount
2220 || motionEntry->isInjected()) {
2221 // The motion event is not compatible with this move.
2222 continue;
2223 }
2224
2225 // Hurray! This foreground target is currently dispatching a move event
2226 // that we can stream onto. Append the motion sample and resume dispatch.
2227 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2228#if DEBUG_BATCHING
2229 LOGD("Appended motion sample onto batch for most recently dispatched "
2230 "motion event for this device in the outbound queues. "
2231 "Attempting to stream the motion sample.");
2232#endif
2233 nsecs_t currentTime = now();
2234 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2235 true /*resumeWithAppendedMotionSample*/);
2236
2237 runCommandsLockedInterruptible();
2238 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002239 }
2240 }
2241
2242NoBatchingOrStreaming:;
2243 }
2244
2245 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07002246 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002247 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002248 xPrecision, yPrecision, downTime,
2249 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002250
Jeff Browna665ca82010-09-08 11:49:43 -07002251 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002252 } // release lock
2253
Jeff Browna665ca82010-09-08 11:49:43 -07002254 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002255 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002256 }
2257}
2258
Jeff Brown90f0cee2010-10-08 22:31:17 -07002259void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2260 uint32_t policyFlags) {
2261#if DEBUG_INBOUND_EVENT_DETAILS
2262 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2263 switchCode, switchValue, policyFlags);
2264#endif
2265
2266 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2267}
2268
Jeff Brown51d45a72010-06-17 20:52:56 -07002269int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07002270 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002271#if DEBUG_INBOUND_EVENT_DETAILS
2272 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002273 "syncMode=%d, timeoutMillis=%d",
2274 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07002275#endif
2276
2277 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002278 bool trusted = hasInjectionPermission(injectorPid, injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002279
Jeff Brown90f0cee2010-10-08 22:31:17 -07002280 EventEntry* injectedEntry;
2281 switch (event->getType()) {
2282 case AINPUT_EVENT_TYPE_KEY: {
2283 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2284 int32_t action = keyEvent->getAction();
2285 if (! validateKeyEvent(action)) {
Jeff Browna665ca82010-09-08 11:49:43 -07002286 return INPUT_EVENT_INJECTION_FAILED;
2287 }
2288
Jeff Brown90f0cee2010-10-08 22:31:17 -07002289 nsecs_t eventTime = keyEvent->getEventTime();
2290 int32_t deviceId = keyEvent->getDeviceId();
2291 int32_t flags = keyEvent->getFlags();
2292 int32_t keyCode = keyEvent->getKeyCode();
2293 int32_t scanCode = keyEvent->getScanCode();
2294 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2295 if (trusted) {
2296 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2297 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002298 }
2299
Jeff Brown90f0cee2010-10-08 22:31:17 -07002300 mLock.lock();
2301 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2302 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2303 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2304 break;
2305 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002306
Jeff Brown90f0cee2010-10-08 22:31:17 -07002307 case AINPUT_EVENT_TYPE_MOTION: {
2308 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2309 int32_t action = motionEvent->getAction();
2310 size_t pointerCount = motionEvent->getPointerCount();
2311 const int32_t* pointerIds = motionEvent->getPointerIds();
2312 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2313 return INPUT_EVENT_INJECTION_FAILED;
2314 }
2315
2316 nsecs_t eventTime = motionEvent->getEventTime();
2317 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2318 if (trusted) {
2319 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2320 }
2321
2322 mLock.lock();
2323 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2324 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2325 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2326 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2327 action, motionEvent->getFlags(),
2328 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2329 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2330 motionEvent->getDownTime(), uint32_t(pointerCount),
2331 pointerIds, samplePointerCoords);
2332 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2333 sampleEventTimes += 1;
2334 samplePointerCoords += pointerCount;
2335 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2336 }
2337 injectedEntry = motionEntry;
2338 break;
2339 }
2340
2341 default:
2342 LOGW("Cannot inject event of type %d", event->getType());
2343 return INPUT_EVENT_INJECTION_FAILED;
2344 }
2345
2346 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2347 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2348 injectionState->injectionIsAsync = true;
2349 }
2350
2351 injectionState->refCount += 1;
2352 injectedEntry->injectionState = injectionState;
2353
2354 bool needWake = enqueueInboundEventLocked(injectedEntry);
2355 mLock.unlock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002356
Jeff Browna665ca82010-09-08 11:49:43 -07002357 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002358 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07002359 }
2360
2361 int32_t injectionResult;
2362 { // acquire lock
2363 AutoMutex _l(mLock);
2364
Jeff Brownf67c53e2010-07-28 15:48:59 -07002365 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2366 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2367 } else {
2368 for (;;) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002369 injectionResult = injectionState->injectionResult;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002370 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2371 break;
2372 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002373
Jeff Brown51d45a72010-06-17 20:52:56 -07002374 nsecs_t remainingTimeout = endTime - now();
2375 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002376#if DEBUG_INJECTION
2377 LOGD("injectInputEvent - Timed out waiting for injection result "
2378 "to become available.");
2379#endif
Jeff Brown51d45a72010-06-17 20:52:56 -07002380 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2381 break;
2382 }
2383
Jeff Brownf67c53e2010-07-28 15:48:59 -07002384 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2385 }
2386
2387 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2388 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002389 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002390#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002391 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002392 injectionState->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002393#endif
2394 nsecs_t remainingTimeout = endTime - now();
2395 if (remainingTimeout <= 0) {
2396#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002397 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002398 "dispatches to finish.");
2399#endif
2400 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2401 break;
2402 }
2403
2404 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2405 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002406 }
2407 }
2408
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002409 mAllocator.releaseInjectionState(injectionState);
Jeff Brown51d45a72010-06-17 20:52:56 -07002410 } // release lock
2411
Jeff Brownf67c53e2010-07-28 15:48:59 -07002412#if DEBUG_INJECTION
2413 LOGD("injectInputEvent - Finished with result %d. "
2414 "injectorPid=%d, injectorUid=%d",
2415 injectionResult, injectorPid, injectorUid);
2416#endif
2417
Jeff Brown51d45a72010-06-17 20:52:56 -07002418 return injectionResult;
2419}
2420
Jeff Brown90f0cee2010-10-08 22:31:17 -07002421bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2422 return injectorUid == 0
2423 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2424}
2425
Jeff Brown51d45a72010-06-17 20:52:56 -07002426void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002427 InjectionState* injectionState = entry->injectionState;
2428 if (injectionState) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002429#if DEBUG_INJECTION
2430 LOGD("Setting input event injection result to %d. "
2431 "injectorPid=%d, injectorUid=%d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002432 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002433#endif
2434
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002435 if (injectionState->injectionIsAsync) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002436 // Log the outcome since the injector did not wait for the injection result.
2437 switch (injectionResult) {
2438 case INPUT_EVENT_INJECTION_SUCCEEDED:
2439 LOGV("Asynchronous input event injection succeeded.");
2440 break;
2441 case INPUT_EVENT_INJECTION_FAILED:
2442 LOGW("Asynchronous input event injection failed.");
2443 break;
2444 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2445 LOGW("Asynchronous input event injection permission denied.");
2446 break;
2447 case INPUT_EVENT_INJECTION_TIMED_OUT:
2448 LOGW("Asynchronous input event injection timed out.");
2449 break;
2450 }
2451 }
2452
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002453 injectionState->injectionResult = injectionResult;
Jeff Brown51d45a72010-06-17 20:52:56 -07002454 mInjectionResultAvailableCondition.broadcast();
2455 }
2456}
2457
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002458void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2459 InjectionState* injectionState = entry->injectionState;
2460 if (injectionState) {
2461 injectionState->pendingForegroundDispatches += 1;
2462 }
2463}
2464
Jeff Brown53a415e2010-09-15 15:18:56 -07002465void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002466 InjectionState* injectionState = entry->injectionState;
2467 if (injectionState) {
2468 injectionState->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002469
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002470 if (injectionState->pendingForegroundDispatches == 0) {
2471 mInjectionSyncFinishedCondition.broadcast();
2472 }
Jeff Browna665ca82010-09-08 11:49:43 -07002473 }
2474}
2475
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002476const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2477 for (size_t i = 0; i < mWindows.size(); i++) {
2478 const InputWindow* window = & mWindows[i];
2479 if (window->inputChannel == inputChannel) {
2480 return window;
2481 }
2482 }
2483 return NULL;
2484}
2485
Jeff Browna665ca82010-09-08 11:49:43 -07002486void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2487#if DEBUG_FOCUS
2488 LOGD("setInputWindows");
2489#endif
2490 { // acquire lock
2491 AutoMutex _l(mLock);
2492
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002493 // Clear old window pointers.
Jeff Brown90f0cee2010-10-08 22:31:17 -07002494 sp<InputChannel> oldFocusedWindowChannel;
2495 if (mFocusedWindow) {
2496 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2497 mFocusedWindow = NULL;
2498 }
2499
Jeff Browna665ca82010-09-08 11:49:43 -07002500 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002501
2502 // Loop over new windows and rebuild the necessary window pointers for
2503 // tracking focus and touch.
Jeff Browna665ca82010-09-08 11:49:43 -07002504 mWindows.appendVector(inputWindows);
2505
2506 size_t numWindows = mWindows.size();
2507 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002508 const InputWindow* window = & mWindows.itemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07002509 if (window->hasFocus) {
2510 mFocusedWindow = window;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002511 break;
Jeff Browna665ca82010-09-08 11:49:43 -07002512 }
2513 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002514
Jeff Brown90f0cee2010-10-08 22:31:17 -07002515 if (oldFocusedWindowChannel != NULL) {
2516 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2517#if DEBUG_FOCUS
2518 LOGD("Focus left window: %s",
2519 oldFocusedWindowChannel->getName().string());
2520#endif
2521 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2522 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2523 oldFocusedWindowChannel.clear();
2524 }
2525 }
2526 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2527#if DEBUG_FOCUS
2528 LOGD("Focus entered window: %s",
2529 mFocusedWindow->inputChannel->getName().string());
2530#endif
2531 }
2532
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002533 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2534 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2535 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2536 if (window) {
2537 touchedWindow.window = window;
2538 i += 1;
2539 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -07002540#if DEBUG_FOCUS
2541 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2542#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002543 mTouchState.windows.removeAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002544 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2545 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002546 }
2547 }
Jeff Browna665ca82010-09-08 11:49:43 -07002548
Jeff Browna665ca82010-09-08 11:49:43 -07002549#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002550 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002551#endif
2552 } // release lock
2553
2554 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002555 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002556}
2557
2558void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2559#if DEBUG_FOCUS
2560 LOGD("setFocusedApplication");
2561#endif
2562 { // acquire lock
2563 AutoMutex _l(mLock);
2564
2565 releaseFocusedApplicationLocked();
2566
2567 if (inputApplication) {
2568 mFocusedApplicationStorage = *inputApplication;
2569 mFocusedApplication = & mFocusedApplicationStorage;
2570 }
2571
2572#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002573 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002574#endif
2575 } // release lock
2576
2577 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002578 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002579}
2580
2581void InputDispatcher::releaseFocusedApplicationLocked() {
2582 if (mFocusedApplication) {
2583 mFocusedApplication = NULL;
2584 mFocusedApplicationStorage.handle.clear();
2585 }
2586}
2587
2588void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2589#if DEBUG_FOCUS
2590 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2591#endif
2592
2593 bool changed;
2594 { // acquire lock
2595 AutoMutex _l(mLock);
2596
2597 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2598 if (mDispatchFrozen && ! frozen) {
2599 resetANRTimeoutsLocked();
2600 }
2601
2602 mDispatchEnabled = enabled;
2603 mDispatchFrozen = frozen;
2604 changed = true;
2605 } else {
2606 changed = false;
2607 }
2608
2609#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002610 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002611#endif
2612 } // release lock
2613
2614 if (changed) {
2615 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002616 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002617 }
2618}
2619
Jeff Browna665ca82010-09-08 11:49:43 -07002620void InputDispatcher::logDispatchStateLocked() {
2621 String8 dump;
2622 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002623
2624 char* text = dump.lockBuffer(dump.size());
2625 char* start = text;
2626 while (*start != '\0') {
2627 char* end = strchr(start, '\n');
2628 if (*end == '\n') {
2629 *(end++) = '\0';
2630 }
2631 LOGD("%s", start);
2632 start = end;
2633 }
Jeff Browna665ca82010-09-08 11:49:43 -07002634}
2635
2636void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002637 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2638 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002639
2640 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002641 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002642 mFocusedApplication->name.string(),
2643 mFocusedApplication->dispatchingTimeout / 1000000.0);
2644 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002645 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002646 }
Jeff Brown2806e382010-10-01 17:46:21 -07002647 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002648 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-10-01 17:46:21 -07002649
2650 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2651 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2652 if (!mTouchState.windows.isEmpty()) {
2653 dump.append(INDENT "TouchedWindows:\n");
2654 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2655 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2656 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2657 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2658 touchedWindow.targetFlags);
2659 }
2660 } else {
2661 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002662 }
2663
Jeff Brown2806e382010-10-01 17:46:21 -07002664 if (!mWindows.isEmpty()) {
2665 dump.append(INDENT "Windows:\n");
2666 for (size_t i = 0; i < mWindows.size(); i++) {
2667 const InputWindow& window = mWindows[i];
2668 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2669 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2670 "frame=[%d,%d][%d,%d], "
2671 "visibleFrame=[%d,%d][%d,%d], "
2672 "touchableArea=[%d,%d][%d,%d], "
2673 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2674 i, window.name.string(),
2675 toString(window.paused),
2676 toString(window.hasFocus),
2677 toString(window.hasWallpaper),
2678 toString(window.visible),
2679 toString(window.canReceiveKeys),
2680 window.layoutParamsFlags, window.layoutParamsType,
2681 window.layer,
2682 window.frameLeft, window.frameTop,
2683 window.frameRight, window.frameBottom,
2684 window.visibleFrameLeft, window.visibleFrameTop,
2685 window.visibleFrameRight, window.visibleFrameBottom,
2686 window.touchableAreaLeft, window.touchableAreaTop,
2687 window.touchableAreaRight, window.touchableAreaBottom,
2688 window.ownerPid, window.ownerUid,
2689 window.dispatchingTimeout / 1000000.0);
2690 }
2691 } else {
2692 dump.append(INDENT "Windows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002693 }
2694
Jeff Brown2806e382010-10-01 17:46:21 -07002695 if (!mMonitoringChannels.isEmpty()) {
2696 dump.append(INDENT "MonitoringChannels:\n");
2697 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2698 const sp<InputChannel>& channel = mMonitoringChannels[i];
2699 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2700 }
2701 } else {
2702 dump.append(INDENT "MonitoringChannels: <none>\n");
2703 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002704
Jeff Brown2806e382010-10-01 17:46:21 -07002705 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2706
2707 if (!mActiveConnections.isEmpty()) {
2708 dump.append(INDENT "ActiveConnections:\n");
2709 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2710 const Connection* connection = mActiveConnections[i];
2711 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
Jeff Brown90f0cee2010-10-08 22:31:17 -07002712 "inputState.isNeutral=%s\n",
Jeff Brown2806e382010-10-01 17:46:21 -07002713 i, connection->getInputChannelName(), connection->getStatusLabel(),
2714 connection->outboundQueue.count(),
Jeff Brown90f0cee2010-10-08 22:31:17 -07002715 toString(connection->inputState.isNeutral()));
Jeff Brown2806e382010-10-01 17:46:21 -07002716 }
2717 } else {
2718 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002719 }
2720
2721 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002722 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002723 (mAppSwitchDueTime - now()) / 1000000.0);
2724 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002725 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002726 }
2727}
2728
2729status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002730#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002731 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2732 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002733#endif
2734
Jeff Browne839a582010-04-22 18:58:52 -07002735 { // acquire lock
2736 AutoMutex _l(mLock);
2737
Jeff Brown53a415e2010-09-15 15:18:56 -07002738 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002739 LOGW("Attempted to register already registered input channel '%s'",
2740 inputChannel->getName().string());
2741 return BAD_VALUE;
2742 }
2743
2744 sp<Connection> connection = new Connection(inputChannel);
2745 status_t status = connection->initialize();
2746 if (status) {
2747 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2748 inputChannel->getName().string(), status);
2749 return status;
2750 }
2751
Jeff Brown0cacb872010-08-17 15:59:26 -07002752 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002753 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002754
Jeff Browna665ca82010-09-08 11:49:43 -07002755 if (monitor) {
2756 mMonitoringChannels.push(inputChannel);
2757 }
2758
Jeff Brown59abe7e2010-09-13 23:17:30 -07002759 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002760
Jeff Brown54bc2812010-06-15 01:31:58 -07002761 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002762 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002763 return OK;
2764}
2765
2766status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002767#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002768 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002769#endif
2770
Jeff Browne839a582010-04-22 18:58:52 -07002771 { // acquire lock
2772 AutoMutex _l(mLock);
2773
Jeff Brown53a415e2010-09-15 15:18:56 -07002774 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002775 if (connectionIndex < 0) {
2776 LOGW("Attempted to unregister already unregistered input channel '%s'",
2777 inputChannel->getName().string());
2778 return BAD_VALUE;
2779 }
2780
2781 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2782 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2783
2784 connection->status = Connection::STATUS_ZOMBIE;
2785
Jeff Browna665ca82010-09-08 11:49:43 -07002786 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2787 if (mMonitoringChannels[i] == inputChannel) {
2788 mMonitoringChannels.removeAt(i);
2789 break;
2790 }
2791 }
2792
Jeff Brown59abe7e2010-09-13 23:17:30 -07002793 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002794
Jeff Brown51d45a72010-06-17 20:52:56 -07002795 nsecs_t currentTime = now();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002796 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002797
2798 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002799 } // release lock
2800
Jeff Browne839a582010-04-22 18:58:52 -07002801 // Wake the poll loop because removing the connection may have changed the current
2802 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002803 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002804 return OK;
2805}
2806
Jeff Brown53a415e2010-09-15 15:18:56 -07002807ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002808 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2809 if (connectionIndex >= 0) {
2810 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2811 if (connection->inputChannel.get() == inputChannel.get()) {
2812 return connectionIndex;
2813 }
2814 }
2815
2816 return -1;
2817}
2818
Jeff Browne839a582010-04-22 18:58:52 -07002819void InputDispatcher::activateConnectionLocked(Connection* connection) {
2820 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2821 if (mActiveConnections.itemAt(i) == connection) {
2822 return;
2823 }
2824 }
2825 mActiveConnections.add(connection);
2826}
2827
2828void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2829 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2830 if (mActiveConnections.itemAt(i) == connection) {
2831 mActiveConnections.removeAt(i);
2832 return;
2833 }
2834 }
2835}
2836
Jeff Brown54bc2812010-06-15 01:31:58 -07002837void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002838 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002839}
2840
Jeff Brown54bc2812010-06-15 01:31:58 -07002841void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002842 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002843}
2844
Jeff Brown54bc2812010-06-15 01:31:58 -07002845void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002846 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002847 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2848 connection->getInputChannelName());
2849
Jeff Brown54bc2812010-06-15 01:31:58 -07002850 CommandEntry* commandEntry = postCommandLocked(
2851 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002852 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002853}
2854
Jeff Brown53a415e2010-09-15 15:18:56 -07002855void InputDispatcher::onANRLocked(
2856 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2857 nsecs_t eventTime, nsecs_t waitStartTime) {
2858 LOGI("Application is not responding: %s. "
2859 "%01.1fms since event, %01.1fms since wait started",
2860 getApplicationWindowLabelLocked(application, window).string(),
2861 (currentTime - eventTime) / 1000000.0,
2862 (currentTime - waitStartTime) / 1000000.0);
2863
2864 CommandEntry* commandEntry = postCommandLocked(
2865 & InputDispatcher::doNotifyANRLockedInterruptible);
2866 if (application) {
2867 commandEntry->inputApplicationHandle = application->handle;
2868 }
2869 if (window) {
2870 commandEntry->inputChannel = window->inputChannel;
2871 }
2872}
2873
Jeff Browna665ca82010-09-08 11:49:43 -07002874void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2875 CommandEntry* commandEntry) {
2876 mLock.unlock();
2877
2878 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2879
2880 mLock.lock();
2881}
2882
Jeff Brown54bc2812010-06-15 01:31:58 -07002883void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2884 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002885 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002886
Jeff Brown51d45a72010-06-17 20:52:56 -07002887 if (connection->status != Connection::STATUS_ZOMBIE) {
2888 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002889
Jeff Brown51d45a72010-06-17 20:52:56 -07002890 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2891
2892 mLock.lock();
2893 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002894}
2895
Jeff Brown53a415e2010-09-15 15:18:56 -07002896void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002897 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002898 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002899
Jeff Brown53a415e2010-09-15 15:18:56 -07002900 nsecs_t newTimeout = mPolicy->notifyANR(
2901 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002902
Jeff Brown53a415e2010-09-15 15:18:56 -07002903 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002904
Jeff Brown53a415e2010-09-15 15:18:56 -07002905 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002906}
2907
Jeff Browna665ca82010-09-08 11:49:43 -07002908void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2909 CommandEntry* commandEntry) {
2910 KeyEntry* entry = commandEntry->keyEntry;
2911 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2912 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2913 entry->downTime, entry->eventTime);
2914
2915 mLock.unlock();
2916
2917 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2918 & mReusableKeyEvent, entry->policyFlags);
2919
2920 mLock.lock();
2921
2922 entry->interceptKeyResult = consumed
2923 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2924 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2925 mAllocator.releaseKeyEntry(entry);
2926}
2927
2928void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2929 mLock.unlock();
2930
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002931 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07002932
2933 mLock.lock();
2934}
2935
Jeff Brown53a415e2010-09-15 15:18:56 -07002936void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
2937 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
2938 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07002939}
2940
2941void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002942 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002943 dumpDispatchStateLocked(dump);
2944}
2945
Jeff Brown54bc2812010-06-15 01:31:58 -07002946
Jeff Brown53a415e2010-09-15 15:18:56 -07002947// --- InputDispatcher::Queue ---
2948
2949template <typename T>
2950uint32_t InputDispatcher::Queue<T>::count() const {
2951 uint32_t result = 0;
2952 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
2953 result += 1;
2954 }
2955 return result;
2956}
2957
2958
Jeff Browne839a582010-04-22 18:58:52 -07002959// --- InputDispatcher::Allocator ---
2960
2961InputDispatcher::Allocator::Allocator() {
2962}
2963
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002964InputDispatcher::InjectionState*
2965InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
2966 InjectionState* injectionState = mInjectionStatePool.alloc();
2967 injectionState->refCount = 1;
2968 injectionState->injectorPid = injectorPid;
2969 injectionState->injectorUid = injectorUid;
2970 injectionState->injectionIsAsync = false;
2971 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
2972 injectionState->pendingForegroundDispatches = 0;
2973 return injectionState;
2974}
2975
Jeff Brown51d45a72010-06-17 20:52:56 -07002976void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brown90f0cee2010-10-08 22:31:17 -07002977 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002978 entry->type = type;
2979 entry->refCount = 1;
2980 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07002981 entry->eventTime = eventTime;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002982 entry->policyFlags = policyFlags;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002983 entry->injectionState = NULL;
2984}
2985
2986void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
2987 if (entry->injectionState) {
2988 releaseInjectionState(entry->injectionState);
2989 entry->injectionState = NULL;
2990 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002991}
2992
Jeff Browne839a582010-04-22 18:58:52 -07002993InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07002994InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002995 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002996 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Browne839a582010-04-22 18:58:52 -07002997 return entry;
2998}
2999
Jeff Brown51d45a72010-06-17 20:52:56 -07003000InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07003001 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07003002 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3003 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003004 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003005 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003006
3007 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003008 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003009 entry->action = action;
3010 entry->flags = flags;
3011 entry->keyCode = keyCode;
3012 entry->scanCode = scanCode;
3013 entry->metaState = metaState;
3014 entry->repeatCount = repeatCount;
3015 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07003016 entry->syntheticRepeat = false;
3017 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07003018 return entry;
3019}
3020
Jeff Brown51d45a72010-06-17 20:52:56 -07003021InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07003022 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07003023 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3024 nsecs_t downTime, uint32_t pointerCount,
3025 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003026 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003027 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003028
3029 entry->eventTime = eventTime;
3030 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003031 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003032 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07003033 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07003034 entry->metaState = metaState;
3035 entry->edgeFlags = edgeFlags;
3036 entry->xPrecision = xPrecision;
3037 entry->yPrecision = yPrecision;
3038 entry->downTime = downTime;
3039 entry->pointerCount = pointerCount;
3040 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07003041 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07003042 entry->lastSample = & entry->firstSample;
3043 for (uint32_t i = 0; i < pointerCount; i++) {
3044 entry->pointerIds[i] = pointerIds[i];
3045 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3046 }
Jeff Browne839a582010-04-22 18:58:52 -07003047 return entry;
3048}
3049
3050InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07003051 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07003052 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07003053 DispatchEntry* entry = mDispatchEntryPool.alloc();
3054 entry->eventEntry = eventEntry;
3055 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07003056 entry->targetFlags = targetFlags;
3057 entry->xOffset = xOffset;
3058 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07003059 entry->inProgress = false;
3060 entry->headMotionSample = NULL;
3061 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07003062 return entry;
3063}
3064
Jeff Brown54bc2812010-06-15 01:31:58 -07003065InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3066 CommandEntry* entry = mCommandEntryPool.alloc();
3067 entry->command = command;
3068 return entry;
3069}
3070
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003071void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3072 injectionState->refCount -= 1;
3073 if (injectionState->refCount == 0) {
3074 mInjectionStatePool.free(injectionState);
3075 } else {
3076 assert(injectionState->refCount > 0);
3077 }
3078}
3079
Jeff Browne839a582010-04-22 18:58:52 -07003080void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3081 switch (entry->type) {
3082 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3083 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3084 break;
3085 case EventEntry::TYPE_KEY:
3086 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3087 break;
3088 case EventEntry::TYPE_MOTION:
3089 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3090 break;
3091 default:
3092 assert(false);
3093 break;
3094 }
3095}
3096
3097void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3098 ConfigurationChangedEntry* entry) {
3099 entry->refCount -= 1;
3100 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003101 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003102 mConfigurationChangeEntryPool.free(entry);
3103 } else {
3104 assert(entry->refCount > 0);
3105 }
3106}
3107
3108void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3109 entry->refCount -= 1;
3110 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003111 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003112 mKeyEntryPool.free(entry);
3113 } else {
3114 assert(entry->refCount > 0);
3115 }
3116}
3117
3118void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3119 entry->refCount -= 1;
3120 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003121 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -07003122 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3123 MotionSample* next = sample->next;
3124 mMotionSamplePool.free(sample);
3125 sample = next;
3126 }
Jeff Browne839a582010-04-22 18:58:52 -07003127 mMotionEntryPool.free(entry);
3128 } else {
3129 assert(entry->refCount > 0);
3130 }
3131}
3132
3133void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3134 releaseEventEntry(entry->eventEntry);
3135 mDispatchEntryPool.free(entry);
3136}
3137
Jeff Brown54bc2812010-06-15 01:31:58 -07003138void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3139 mCommandEntryPool.free(entry);
3140}
3141
Jeff Browne839a582010-04-22 18:58:52 -07003142void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003143 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003144 MotionSample* sample = mMotionSamplePool.alloc();
3145 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003146 uint32_t pointerCount = motionEntry->pointerCount;
3147 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07003148 sample->pointerCoords[i] = pointerCoords[i];
3149 }
3150
3151 sample->next = NULL;
3152 motionEntry->lastSample->next = sample;
3153 motionEntry->lastSample = sample;
3154}
3155
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003156void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3157 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003158
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003159 keyEntry->dispatchInProgress = false;
3160 keyEntry->syntheticRepeat = false;
3161 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003162}
3163
3164
Jeff Brown542412c2010-08-18 15:51:08 -07003165// --- InputDispatcher::MotionEntry ---
3166
3167uint32_t InputDispatcher::MotionEntry::countSamples() const {
3168 uint32_t count = 1;
3169 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3170 count += 1;
3171 }
3172 return count;
3173}
3174
Jeff Browna665ca82010-09-08 11:49:43 -07003175
3176// --- InputDispatcher::InputState ---
3177
Jeff Brown90f0cee2010-10-08 22:31:17 -07003178InputDispatcher::InputState::InputState() {
Jeff Browna665ca82010-09-08 11:49:43 -07003179}
3180
3181InputDispatcher::InputState::~InputState() {
3182}
3183
3184bool InputDispatcher::InputState::isNeutral() const {
3185 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3186}
3187
Jeff Browna665ca82010-09-08 11:49:43 -07003188InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3189 const EventEntry* entry) {
3190 switch (entry->type) {
3191 case EventEntry::TYPE_KEY:
3192 return trackKey(static_cast<const KeyEntry*>(entry));
3193
3194 case EventEntry::TYPE_MOTION:
3195 return trackMotion(static_cast<const MotionEntry*>(entry));
3196
3197 default:
3198 return CONSISTENT;
3199 }
3200}
3201
3202InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3203 const KeyEntry* entry) {
3204 int32_t action = entry->action;
3205 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3206 KeyMemento& memento = mKeyMementos.editItemAt(i);
3207 if (memento.deviceId == entry->deviceId
3208 && memento.source == entry->source
3209 && memento.keyCode == entry->keyCode
3210 && memento.scanCode == entry->scanCode) {
3211 switch (action) {
3212 case AKEY_EVENT_ACTION_UP:
3213 mKeyMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003214 return CONSISTENT;
3215
3216 case AKEY_EVENT_ACTION_DOWN:
3217 return TOLERABLE;
3218
3219 default:
3220 return BROKEN;
3221 }
3222 }
3223 }
3224
3225 switch (action) {
3226 case AKEY_EVENT_ACTION_DOWN: {
3227 mKeyMementos.push();
3228 KeyMemento& memento = mKeyMementos.editTop();
3229 memento.deviceId = entry->deviceId;
3230 memento.source = entry->source;
3231 memento.keyCode = entry->keyCode;
3232 memento.scanCode = entry->scanCode;
3233 memento.downTime = entry->downTime;
3234 return CONSISTENT;
3235 }
3236
3237 default:
3238 return BROKEN;
3239 }
3240}
3241
3242InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3243 const MotionEntry* entry) {
3244 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3245 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3246 MotionMemento& memento = mMotionMementos.editItemAt(i);
3247 if (memento.deviceId == entry->deviceId
3248 && memento.source == entry->source) {
3249 switch (action) {
3250 case AMOTION_EVENT_ACTION_UP:
3251 case AMOTION_EVENT_ACTION_CANCEL:
3252 mMotionMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003253 return CONSISTENT;
3254
3255 case AMOTION_EVENT_ACTION_DOWN:
3256 return TOLERABLE;
3257
3258 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3259 if (entry->pointerCount == memento.pointerCount + 1) {
3260 memento.setPointers(entry);
3261 return CONSISTENT;
3262 }
3263 return BROKEN;
3264
3265 case AMOTION_EVENT_ACTION_POINTER_UP:
3266 if (entry->pointerCount == memento.pointerCount - 1) {
3267 memento.setPointers(entry);
3268 return CONSISTENT;
3269 }
3270 return BROKEN;
3271
3272 case AMOTION_EVENT_ACTION_MOVE:
3273 if (entry->pointerCount == memento.pointerCount) {
3274 return CONSISTENT;
3275 }
3276 return BROKEN;
3277
3278 default:
3279 return BROKEN;
3280 }
3281 }
3282 }
3283
3284 switch (action) {
3285 case AMOTION_EVENT_ACTION_DOWN: {
3286 mMotionMementos.push();
3287 MotionMemento& memento = mMotionMementos.editTop();
3288 memento.deviceId = entry->deviceId;
3289 memento.source = entry->source;
3290 memento.xPrecision = entry->xPrecision;
3291 memento.yPrecision = entry->yPrecision;
3292 memento.downTime = entry->downTime;
3293 memento.setPointers(entry);
3294 return CONSISTENT;
3295 }
3296
3297 default:
3298 return BROKEN;
3299 }
3300}
3301
3302void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3303 pointerCount = entry->pointerCount;
3304 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3305 pointerIds[i] = entry->pointerIds[i];
3306 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3307 }
3308}
3309
Jeff Brown90f0cee2010-10-08 22:31:17 -07003310void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3311 Allocator* allocator, Vector<EventEntry*>& outEvents,
3312 CancelationOptions options) {
3313 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003314 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003315 if (shouldCancelEvent(memento.source, options)) {
3316 outEvents.push(allocator->obtainKeyEntry(currentTime,
3317 memento.deviceId, memento.source, 0,
3318 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3319 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3320 mKeyMementos.removeAt(i);
3321 } else {
3322 i += 1;
3323 }
Jeff Browna665ca82010-09-08 11:49:43 -07003324 }
3325
3326 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3327 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003328 if (shouldCancelEvent(memento.source, options)) {
3329 outEvents.push(allocator->obtainMotionEntry(currentTime,
3330 memento.deviceId, memento.source, 0,
3331 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3332 memento.xPrecision, memento.yPrecision, memento.downTime,
3333 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3334 mMotionMementos.removeAt(i);
3335 } else {
3336 i += 1;
3337 }
Jeff Browna665ca82010-09-08 11:49:43 -07003338 }
3339}
3340
3341void InputDispatcher::InputState::clear() {
3342 mKeyMementos.clear();
3343 mMotionMementos.clear();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003344}
3345
3346bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3347 CancelationOptions options) {
3348 switch (options) {
3349 case CANCEL_POINTER_EVENTS:
3350 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3351 case CANCEL_NON_POINTER_EVENTS:
3352 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3353 default:
3354 return true;
3355 }
Jeff Browna665ca82010-09-08 11:49:43 -07003356}
3357
3358
Jeff Browne839a582010-04-22 18:58:52 -07003359// --- InputDispatcher::Connection ---
3360
3361InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3362 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003363 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003364}
3365
3366InputDispatcher::Connection::~Connection() {
3367}
3368
3369status_t InputDispatcher::Connection::initialize() {
3370 return inputPublisher.initialize();
3371}
3372
Jeff Brown54bc2812010-06-15 01:31:58 -07003373const char* InputDispatcher::Connection::getStatusLabel() const {
3374 switch (status) {
3375 case STATUS_NORMAL:
3376 return "NORMAL";
3377
3378 case STATUS_BROKEN:
3379 return "BROKEN";
3380
Jeff Brown54bc2812010-06-15 01:31:58 -07003381 case STATUS_ZOMBIE:
3382 return "ZOMBIE";
3383
3384 default:
3385 return "UNKNOWN";
3386 }
3387}
3388
Jeff Browne839a582010-04-22 18:58:52 -07003389InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3390 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003391 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3392 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003393 if (dispatchEntry->eventEntry == eventEntry) {
3394 return dispatchEntry;
3395 }
3396 }
3397 return NULL;
3398}
3399
Jeff Browna665ca82010-09-08 11:49:43 -07003400
Jeff Brown54bc2812010-06-15 01:31:58 -07003401// --- InputDispatcher::CommandEntry ---
3402
Jeff Browna665ca82010-09-08 11:49:43 -07003403InputDispatcher::CommandEntry::CommandEntry() :
3404 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003405}
3406
3407InputDispatcher::CommandEntry::~CommandEntry() {
3408}
3409
Jeff Browne839a582010-04-22 18:58:52 -07003410
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003411// --- InputDispatcher::TouchState ---
3412
3413InputDispatcher::TouchState::TouchState() :
3414 down(false), split(false) {
3415}
3416
3417InputDispatcher::TouchState::~TouchState() {
3418}
3419
3420void InputDispatcher::TouchState::reset() {
3421 down = false;
3422 split = false;
3423 windows.clear();
3424}
3425
3426void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3427 down = other.down;
3428 split = other.split;
3429 windows.clear();
3430 windows.appendVector(other.windows);
3431}
3432
3433void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3434 int32_t targetFlags, BitSet32 pointerIds) {
3435 if (targetFlags & InputTarget::FLAG_SPLIT) {
3436 split = true;
3437 }
3438
3439 for (size_t i = 0; i < windows.size(); i++) {
3440 TouchedWindow& touchedWindow = windows.editItemAt(i);
3441 if (touchedWindow.window == window) {
3442 touchedWindow.targetFlags |= targetFlags;
3443 touchedWindow.pointerIds.value |= pointerIds.value;
3444 return;
3445 }
3446 }
3447
3448 windows.push();
3449
3450 TouchedWindow& touchedWindow = windows.editTop();
3451 touchedWindow.window = window;
3452 touchedWindow.targetFlags = targetFlags;
3453 touchedWindow.pointerIds = pointerIds;
3454 touchedWindow.channel = window->inputChannel;
3455}
3456
3457void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3458 for (size_t i = 0 ; i < windows.size(); ) {
3459 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3460 windows.removeAt(i);
3461 } else {
3462 i += 1;
3463 }
3464 }
3465}
3466
3467const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3468 for (size_t i = 0; i < windows.size(); i++) {
3469 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3470 return windows[i].window;
3471 }
3472 }
3473 return NULL;
3474}
3475
3476
Jeff Browne839a582010-04-22 18:58:52 -07003477// --- InputDispatcherThread ---
3478
3479InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3480 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3481}
3482
3483InputDispatcherThread::~InputDispatcherThread() {
3484}
3485
3486bool InputDispatcherThread::threadLoop() {
3487 mDispatcher->dispatchOnce();
3488 return true;
3489}
3490
3491} // namespace android