blob: a796ef51e501d298d9cb78a951f52a535cbf1d5a [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 Brown3c2450f2010-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 Brown744c5592010-09-27 14:52:15 -07002620bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2621 const sp<InputChannel>& toChannel) {
2622#if DEBUG_FOCUS
2623 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2624 fromChannel->getName().string(), toChannel->getName().string());
2625#endif
2626 { // acquire lock
2627 AutoMutex _l(mLock);
2628
2629 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2630 const InputWindow* toWindow = getWindowLocked(toChannel);
2631 if (! fromWindow || ! toWindow) {
2632#if DEBUG_FOCUS
2633 LOGD("Cannot transfer focus because from or to window not found.");
2634#endif
2635 return false;
2636 }
2637 if (fromWindow == toWindow) {
2638#if DEBUG_FOCUS
2639 LOGD("Trivial transfer to same window.");
2640#endif
2641 return true;
2642 }
2643
2644 bool found = false;
2645 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2646 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2647 if (touchedWindow.window == fromWindow) {
2648 int32_t oldTargetFlags = touchedWindow.targetFlags;
2649 BitSet32 pointerIds = touchedWindow.pointerIds;
2650
2651 mTouchState.windows.removeAt(i);
2652
2653 int32_t newTargetFlags = 0;
2654 if (oldTargetFlags & InputTarget::FLAG_FOREGROUND) {
2655 newTargetFlags |= InputTarget::FLAG_FOREGROUND;
2656 if (toWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) {
2657 newTargetFlags |= InputTarget::FLAG_SPLIT;
2658 }
2659 }
2660 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2661
2662 found = true;
2663 break;
2664 }
2665 }
2666
2667 if (! found) {
2668#if DEBUG_FOCUS
2669 LOGD("Focus transfer failed because from window did not have focus.");
2670#endif
2671 return false;
2672 }
2673
2674#if DEBUG_FOCUS
2675 logDispatchStateLocked();
2676#endif
2677 } // release lock
2678
2679 // Wake up poll loop since it may need to make new input dispatching choices.
2680 mLooper->wake();
2681 return true;
2682}
2683
Jeff Browna665ca82010-09-08 11:49:43 -07002684void InputDispatcher::logDispatchStateLocked() {
2685 String8 dump;
2686 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002687
2688 char* text = dump.lockBuffer(dump.size());
2689 char* start = text;
2690 while (*start != '\0') {
2691 char* end = strchr(start, '\n');
2692 if (*end == '\n') {
2693 *(end++) = '\0';
2694 }
2695 LOGD("%s", start);
2696 start = end;
2697 }
Jeff Browna665ca82010-09-08 11:49:43 -07002698}
2699
2700void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002701 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2702 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002703
2704 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002705 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002706 mFocusedApplication->name.string(),
2707 mFocusedApplication->dispatchingTimeout / 1000000.0);
2708 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002709 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002710 }
Jeff Brown2806e382010-10-01 17:46:21 -07002711 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002712 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-10-01 17:46:21 -07002713
2714 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2715 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2716 if (!mTouchState.windows.isEmpty()) {
2717 dump.append(INDENT "TouchedWindows:\n");
2718 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2719 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2720 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2721 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2722 touchedWindow.targetFlags);
2723 }
2724 } else {
2725 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002726 }
2727
Jeff Brown2806e382010-10-01 17:46:21 -07002728 if (!mWindows.isEmpty()) {
2729 dump.append(INDENT "Windows:\n");
2730 for (size_t i = 0; i < mWindows.size(); i++) {
2731 const InputWindow& window = mWindows[i];
2732 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2733 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2734 "frame=[%d,%d][%d,%d], "
2735 "visibleFrame=[%d,%d][%d,%d], "
2736 "touchableArea=[%d,%d][%d,%d], "
2737 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2738 i, window.name.string(),
2739 toString(window.paused),
2740 toString(window.hasFocus),
2741 toString(window.hasWallpaper),
2742 toString(window.visible),
2743 toString(window.canReceiveKeys),
2744 window.layoutParamsFlags, window.layoutParamsType,
2745 window.layer,
2746 window.frameLeft, window.frameTop,
2747 window.frameRight, window.frameBottom,
2748 window.visibleFrameLeft, window.visibleFrameTop,
2749 window.visibleFrameRight, window.visibleFrameBottom,
2750 window.touchableAreaLeft, window.touchableAreaTop,
2751 window.touchableAreaRight, window.touchableAreaBottom,
2752 window.ownerPid, window.ownerUid,
2753 window.dispatchingTimeout / 1000000.0);
2754 }
2755 } else {
2756 dump.append(INDENT "Windows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002757 }
2758
Jeff Brown2806e382010-10-01 17:46:21 -07002759 if (!mMonitoringChannels.isEmpty()) {
2760 dump.append(INDENT "MonitoringChannels:\n");
2761 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2762 const sp<InputChannel>& channel = mMonitoringChannels[i];
2763 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2764 }
2765 } else {
2766 dump.append(INDENT "MonitoringChannels: <none>\n");
2767 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002768
Jeff Brown2806e382010-10-01 17:46:21 -07002769 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2770
2771 if (!mActiveConnections.isEmpty()) {
2772 dump.append(INDENT "ActiveConnections:\n");
2773 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2774 const Connection* connection = mActiveConnections[i];
2775 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
Jeff Brown90f0cee2010-10-08 22:31:17 -07002776 "inputState.isNeutral=%s\n",
Jeff Brown2806e382010-10-01 17:46:21 -07002777 i, connection->getInputChannelName(), connection->getStatusLabel(),
2778 connection->outboundQueue.count(),
Jeff Brown90f0cee2010-10-08 22:31:17 -07002779 toString(connection->inputState.isNeutral()));
Jeff Brown2806e382010-10-01 17:46:21 -07002780 }
2781 } else {
2782 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002783 }
2784
2785 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002786 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002787 (mAppSwitchDueTime - now()) / 1000000.0);
2788 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002789 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002790 }
2791}
2792
2793status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002794#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002795 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2796 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002797#endif
2798
Jeff Browne839a582010-04-22 18:58:52 -07002799 { // acquire lock
2800 AutoMutex _l(mLock);
2801
Jeff Brown53a415e2010-09-15 15:18:56 -07002802 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002803 LOGW("Attempted to register already registered input channel '%s'",
2804 inputChannel->getName().string());
2805 return BAD_VALUE;
2806 }
2807
2808 sp<Connection> connection = new Connection(inputChannel);
2809 status_t status = connection->initialize();
2810 if (status) {
2811 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2812 inputChannel->getName().string(), status);
2813 return status;
2814 }
2815
Jeff Brown0cacb872010-08-17 15:59:26 -07002816 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002817 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002818
Jeff Browna665ca82010-09-08 11:49:43 -07002819 if (monitor) {
2820 mMonitoringChannels.push(inputChannel);
2821 }
2822
Jeff Brown59abe7e2010-09-13 23:17:30 -07002823 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002824
Jeff Brown54bc2812010-06-15 01:31:58 -07002825 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002826 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002827 return OK;
2828}
2829
2830status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002831#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002832 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002833#endif
2834
Jeff Browne839a582010-04-22 18:58:52 -07002835 { // acquire lock
2836 AutoMutex _l(mLock);
2837
Jeff Brown53a415e2010-09-15 15:18:56 -07002838 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002839 if (connectionIndex < 0) {
2840 LOGW("Attempted to unregister already unregistered input channel '%s'",
2841 inputChannel->getName().string());
2842 return BAD_VALUE;
2843 }
2844
2845 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2846 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2847
2848 connection->status = Connection::STATUS_ZOMBIE;
2849
Jeff Browna665ca82010-09-08 11:49:43 -07002850 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2851 if (mMonitoringChannels[i] == inputChannel) {
2852 mMonitoringChannels.removeAt(i);
2853 break;
2854 }
2855 }
2856
Jeff Brown59abe7e2010-09-13 23:17:30 -07002857 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002858
Jeff Brown51d45a72010-06-17 20:52:56 -07002859 nsecs_t currentTime = now();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002860 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002861
2862 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002863 } // release lock
2864
Jeff Browne839a582010-04-22 18:58:52 -07002865 // Wake the poll loop because removing the connection may have changed the current
2866 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002867 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002868 return OK;
2869}
2870
Jeff Brown53a415e2010-09-15 15:18:56 -07002871ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002872 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2873 if (connectionIndex >= 0) {
2874 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2875 if (connection->inputChannel.get() == inputChannel.get()) {
2876 return connectionIndex;
2877 }
2878 }
2879
2880 return -1;
2881}
2882
Jeff Browne839a582010-04-22 18:58:52 -07002883void InputDispatcher::activateConnectionLocked(Connection* connection) {
2884 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2885 if (mActiveConnections.itemAt(i) == connection) {
2886 return;
2887 }
2888 }
2889 mActiveConnections.add(connection);
2890}
2891
2892void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2893 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2894 if (mActiveConnections.itemAt(i) == connection) {
2895 mActiveConnections.removeAt(i);
2896 return;
2897 }
2898 }
2899}
2900
Jeff Brown54bc2812010-06-15 01:31:58 -07002901void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002902 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002903}
2904
Jeff Brown54bc2812010-06-15 01:31:58 -07002905void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002906 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002907}
2908
Jeff Brown54bc2812010-06-15 01:31:58 -07002909void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002910 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002911 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2912 connection->getInputChannelName());
2913
Jeff Brown54bc2812010-06-15 01:31:58 -07002914 CommandEntry* commandEntry = postCommandLocked(
2915 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002916 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002917}
2918
Jeff Brown53a415e2010-09-15 15:18:56 -07002919void InputDispatcher::onANRLocked(
2920 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2921 nsecs_t eventTime, nsecs_t waitStartTime) {
2922 LOGI("Application is not responding: %s. "
2923 "%01.1fms since event, %01.1fms since wait started",
2924 getApplicationWindowLabelLocked(application, window).string(),
2925 (currentTime - eventTime) / 1000000.0,
2926 (currentTime - waitStartTime) / 1000000.0);
2927
2928 CommandEntry* commandEntry = postCommandLocked(
2929 & InputDispatcher::doNotifyANRLockedInterruptible);
2930 if (application) {
2931 commandEntry->inputApplicationHandle = application->handle;
2932 }
2933 if (window) {
2934 commandEntry->inputChannel = window->inputChannel;
2935 }
2936}
2937
Jeff Browna665ca82010-09-08 11:49:43 -07002938void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2939 CommandEntry* commandEntry) {
2940 mLock.unlock();
2941
2942 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2943
2944 mLock.lock();
2945}
2946
Jeff Brown54bc2812010-06-15 01:31:58 -07002947void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2948 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002949 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002950
Jeff Brown51d45a72010-06-17 20:52:56 -07002951 if (connection->status != Connection::STATUS_ZOMBIE) {
2952 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002953
Jeff Brown51d45a72010-06-17 20:52:56 -07002954 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2955
2956 mLock.lock();
2957 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002958}
2959
Jeff Brown53a415e2010-09-15 15:18:56 -07002960void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002961 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002962 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002963
Jeff Brown53a415e2010-09-15 15:18:56 -07002964 nsecs_t newTimeout = mPolicy->notifyANR(
2965 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002966
Jeff Brown53a415e2010-09-15 15:18:56 -07002967 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002968
Jeff Brown53a415e2010-09-15 15:18:56 -07002969 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002970}
2971
Jeff Browna665ca82010-09-08 11:49:43 -07002972void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2973 CommandEntry* commandEntry) {
2974 KeyEntry* entry = commandEntry->keyEntry;
2975 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2976 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2977 entry->downTime, entry->eventTime);
2978
2979 mLock.unlock();
2980
2981 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2982 & mReusableKeyEvent, entry->policyFlags);
2983
2984 mLock.lock();
2985
2986 entry->interceptKeyResult = consumed
2987 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2988 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2989 mAllocator.releaseKeyEntry(entry);
2990}
2991
2992void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2993 mLock.unlock();
2994
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002995 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07002996
2997 mLock.lock();
2998}
2999
Jeff Brown53a415e2010-09-15 15:18:56 -07003000void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3001 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3002 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07003003}
3004
3005void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07003006 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07003007 dumpDispatchStateLocked(dump);
3008}
3009
Jeff Brown54bc2812010-06-15 01:31:58 -07003010
Jeff Brown53a415e2010-09-15 15:18:56 -07003011// --- InputDispatcher::Queue ---
3012
3013template <typename T>
3014uint32_t InputDispatcher::Queue<T>::count() const {
3015 uint32_t result = 0;
3016 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3017 result += 1;
3018 }
3019 return result;
3020}
3021
3022
Jeff Browne839a582010-04-22 18:58:52 -07003023// --- InputDispatcher::Allocator ---
3024
3025InputDispatcher::Allocator::Allocator() {
3026}
3027
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003028InputDispatcher::InjectionState*
3029InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3030 InjectionState* injectionState = mInjectionStatePool.alloc();
3031 injectionState->refCount = 1;
3032 injectionState->injectorPid = injectorPid;
3033 injectionState->injectorUid = injectorUid;
3034 injectionState->injectionIsAsync = false;
3035 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3036 injectionState->pendingForegroundDispatches = 0;
3037 return injectionState;
3038}
3039
Jeff Brown51d45a72010-06-17 20:52:56 -07003040void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brown90f0cee2010-10-08 22:31:17 -07003041 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown51d45a72010-06-17 20:52:56 -07003042 entry->type = type;
3043 entry->refCount = 1;
3044 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07003045 entry->eventTime = eventTime;
Jeff Brown90f0cee2010-10-08 22:31:17 -07003046 entry->policyFlags = policyFlags;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003047 entry->injectionState = NULL;
3048}
3049
3050void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3051 if (entry->injectionState) {
3052 releaseInjectionState(entry->injectionState);
3053 entry->injectionState = NULL;
3054 }
Jeff Brown51d45a72010-06-17 20:52:56 -07003055}
3056
Jeff Browne839a582010-04-22 18:58:52 -07003057InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07003058InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003059 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003060 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Browne839a582010-04-22 18:58:52 -07003061 return entry;
3062}
3063
Jeff Brown51d45a72010-06-17 20:52:56 -07003064InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07003065 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07003066 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3067 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003068 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003069 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003070
3071 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003072 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003073 entry->action = action;
3074 entry->flags = flags;
3075 entry->keyCode = keyCode;
3076 entry->scanCode = scanCode;
3077 entry->metaState = metaState;
3078 entry->repeatCount = repeatCount;
3079 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07003080 entry->syntheticRepeat = false;
3081 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07003082 return entry;
3083}
3084
Jeff Brown51d45a72010-06-17 20:52:56 -07003085InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07003086 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07003087 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3088 nsecs_t downTime, uint32_t pointerCount,
3089 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003090 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003091 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003092
3093 entry->eventTime = eventTime;
3094 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003095 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003096 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07003097 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07003098 entry->metaState = metaState;
3099 entry->edgeFlags = edgeFlags;
3100 entry->xPrecision = xPrecision;
3101 entry->yPrecision = yPrecision;
3102 entry->downTime = downTime;
3103 entry->pointerCount = pointerCount;
3104 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07003105 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07003106 entry->lastSample = & entry->firstSample;
3107 for (uint32_t i = 0; i < pointerCount; i++) {
3108 entry->pointerIds[i] = pointerIds[i];
3109 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3110 }
Jeff Browne839a582010-04-22 18:58:52 -07003111 return entry;
3112}
3113
3114InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07003115 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07003116 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07003117 DispatchEntry* entry = mDispatchEntryPool.alloc();
3118 entry->eventEntry = eventEntry;
3119 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07003120 entry->targetFlags = targetFlags;
3121 entry->xOffset = xOffset;
3122 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07003123 entry->inProgress = false;
3124 entry->headMotionSample = NULL;
3125 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07003126 return entry;
3127}
3128
Jeff Brown54bc2812010-06-15 01:31:58 -07003129InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3130 CommandEntry* entry = mCommandEntryPool.alloc();
3131 entry->command = command;
3132 return entry;
3133}
3134
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003135void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3136 injectionState->refCount -= 1;
3137 if (injectionState->refCount == 0) {
3138 mInjectionStatePool.free(injectionState);
3139 } else {
3140 assert(injectionState->refCount > 0);
3141 }
3142}
3143
Jeff Browne839a582010-04-22 18:58:52 -07003144void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3145 switch (entry->type) {
3146 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3147 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3148 break;
3149 case EventEntry::TYPE_KEY:
3150 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3151 break;
3152 case EventEntry::TYPE_MOTION:
3153 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3154 break;
3155 default:
3156 assert(false);
3157 break;
3158 }
3159}
3160
3161void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3162 ConfigurationChangedEntry* entry) {
3163 entry->refCount -= 1;
3164 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003165 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003166 mConfigurationChangeEntryPool.free(entry);
3167 } else {
3168 assert(entry->refCount > 0);
3169 }
3170}
3171
3172void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3173 entry->refCount -= 1;
3174 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003175 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003176 mKeyEntryPool.free(entry);
3177 } else {
3178 assert(entry->refCount > 0);
3179 }
3180}
3181
3182void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3183 entry->refCount -= 1;
3184 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003185 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -07003186 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3187 MotionSample* next = sample->next;
3188 mMotionSamplePool.free(sample);
3189 sample = next;
3190 }
Jeff Browne839a582010-04-22 18:58:52 -07003191 mMotionEntryPool.free(entry);
3192 } else {
3193 assert(entry->refCount > 0);
3194 }
3195}
3196
3197void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3198 releaseEventEntry(entry->eventEntry);
3199 mDispatchEntryPool.free(entry);
3200}
3201
Jeff Brown54bc2812010-06-15 01:31:58 -07003202void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3203 mCommandEntryPool.free(entry);
3204}
3205
Jeff Browne839a582010-04-22 18:58:52 -07003206void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003207 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003208 MotionSample* sample = mMotionSamplePool.alloc();
3209 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003210 uint32_t pointerCount = motionEntry->pointerCount;
3211 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07003212 sample->pointerCoords[i] = pointerCoords[i];
3213 }
3214
3215 sample->next = NULL;
3216 motionEntry->lastSample->next = sample;
3217 motionEntry->lastSample = sample;
3218}
3219
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003220void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3221 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003222
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003223 keyEntry->dispatchInProgress = false;
3224 keyEntry->syntheticRepeat = false;
3225 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003226}
3227
3228
Jeff Brown542412c2010-08-18 15:51:08 -07003229// --- InputDispatcher::MotionEntry ---
3230
3231uint32_t InputDispatcher::MotionEntry::countSamples() const {
3232 uint32_t count = 1;
3233 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3234 count += 1;
3235 }
3236 return count;
3237}
3238
Jeff Browna665ca82010-09-08 11:49:43 -07003239
3240// --- InputDispatcher::InputState ---
3241
Jeff Brown90f0cee2010-10-08 22:31:17 -07003242InputDispatcher::InputState::InputState() {
Jeff Browna665ca82010-09-08 11:49:43 -07003243}
3244
3245InputDispatcher::InputState::~InputState() {
3246}
3247
3248bool InputDispatcher::InputState::isNeutral() const {
3249 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3250}
3251
Jeff Browna665ca82010-09-08 11:49:43 -07003252InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3253 const EventEntry* entry) {
3254 switch (entry->type) {
3255 case EventEntry::TYPE_KEY:
3256 return trackKey(static_cast<const KeyEntry*>(entry));
3257
3258 case EventEntry::TYPE_MOTION:
3259 return trackMotion(static_cast<const MotionEntry*>(entry));
3260
3261 default:
3262 return CONSISTENT;
3263 }
3264}
3265
3266InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3267 const KeyEntry* entry) {
3268 int32_t action = entry->action;
3269 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3270 KeyMemento& memento = mKeyMementos.editItemAt(i);
3271 if (memento.deviceId == entry->deviceId
3272 && memento.source == entry->source
3273 && memento.keyCode == entry->keyCode
3274 && memento.scanCode == entry->scanCode) {
3275 switch (action) {
3276 case AKEY_EVENT_ACTION_UP:
3277 mKeyMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003278 return CONSISTENT;
3279
3280 case AKEY_EVENT_ACTION_DOWN:
3281 return TOLERABLE;
3282
3283 default:
3284 return BROKEN;
3285 }
3286 }
3287 }
3288
3289 switch (action) {
3290 case AKEY_EVENT_ACTION_DOWN: {
3291 mKeyMementos.push();
3292 KeyMemento& memento = mKeyMementos.editTop();
3293 memento.deviceId = entry->deviceId;
3294 memento.source = entry->source;
3295 memento.keyCode = entry->keyCode;
3296 memento.scanCode = entry->scanCode;
3297 memento.downTime = entry->downTime;
3298 return CONSISTENT;
3299 }
3300
3301 default:
3302 return BROKEN;
3303 }
3304}
3305
3306InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3307 const MotionEntry* entry) {
3308 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3309 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3310 MotionMemento& memento = mMotionMementos.editItemAt(i);
3311 if (memento.deviceId == entry->deviceId
3312 && memento.source == entry->source) {
3313 switch (action) {
3314 case AMOTION_EVENT_ACTION_UP:
3315 case AMOTION_EVENT_ACTION_CANCEL:
3316 mMotionMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003317 return CONSISTENT;
3318
3319 case AMOTION_EVENT_ACTION_DOWN:
3320 return TOLERABLE;
3321
3322 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3323 if (entry->pointerCount == memento.pointerCount + 1) {
3324 memento.setPointers(entry);
3325 return CONSISTENT;
3326 }
3327 return BROKEN;
3328
3329 case AMOTION_EVENT_ACTION_POINTER_UP:
3330 if (entry->pointerCount == memento.pointerCount - 1) {
3331 memento.setPointers(entry);
3332 return CONSISTENT;
3333 }
3334 return BROKEN;
3335
3336 case AMOTION_EVENT_ACTION_MOVE:
3337 if (entry->pointerCount == memento.pointerCount) {
3338 return CONSISTENT;
3339 }
3340 return BROKEN;
3341
3342 default:
3343 return BROKEN;
3344 }
3345 }
3346 }
3347
3348 switch (action) {
3349 case AMOTION_EVENT_ACTION_DOWN: {
3350 mMotionMementos.push();
3351 MotionMemento& memento = mMotionMementos.editTop();
3352 memento.deviceId = entry->deviceId;
3353 memento.source = entry->source;
3354 memento.xPrecision = entry->xPrecision;
3355 memento.yPrecision = entry->yPrecision;
3356 memento.downTime = entry->downTime;
3357 memento.setPointers(entry);
3358 return CONSISTENT;
3359 }
3360
3361 default:
3362 return BROKEN;
3363 }
3364}
3365
3366void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3367 pointerCount = entry->pointerCount;
3368 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3369 pointerIds[i] = entry->pointerIds[i];
3370 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3371 }
3372}
3373
Jeff Brown90f0cee2010-10-08 22:31:17 -07003374void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3375 Allocator* allocator, Vector<EventEntry*>& outEvents,
3376 CancelationOptions options) {
3377 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003378 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003379 if (shouldCancelEvent(memento.source, options)) {
3380 outEvents.push(allocator->obtainKeyEntry(currentTime,
3381 memento.deviceId, memento.source, 0,
3382 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3383 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3384 mKeyMementos.removeAt(i);
3385 } else {
3386 i += 1;
3387 }
Jeff Browna665ca82010-09-08 11:49:43 -07003388 }
3389
3390 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3391 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003392 if (shouldCancelEvent(memento.source, options)) {
3393 outEvents.push(allocator->obtainMotionEntry(currentTime,
3394 memento.deviceId, memento.source, 0,
3395 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3396 memento.xPrecision, memento.yPrecision, memento.downTime,
3397 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3398 mMotionMementos.removeAt(i);
3399 } else {
3400 i += 1;
3401 }
Jeff Browna665ca82010-09-08 11:49:43 -07003402 }
3403}
3404
3405void InputDispatcher::InputState::clear() {
3406 mKeyMementos.clear();
3407 mMotionMementos.clear();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003408}
3409
3410bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3411 CancelationOptions options) {
3412 switch (options) {
3413 case CANCEL_POINTER_EVENTS:
3414 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3415 case CANCEL_NON_POINTER_EVENTS:
3416 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3417 default:
3418 return true;
3419 }
Jeff Browna665ca82010-09-08 11:49:43 -07003420}
3421
3422
Jeff Browne839a582010-04-22 18:58:52 -07003423// --- InputDispatcher::Connection ---
3424
3425InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3426 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003427 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003428}
3429
3430InputDispatcher::Connection::~Connection() {
3431}
3432
3433status_t InputDispatcher::Connection::initialize() {
3434 return inputPublisher.initialize();
3435}
3436
Jeff Brown54bc2812010-06-15 01:31:58 -07003437const char* InputDispatcher::Connection::getStatusLabel() const {
3438 switch (status) {
3439 case STATUS_NORMAL:
3440 return "NORMAL";
3441
3442 case STATUS_BROKEN:
3443 return "BROKEN";
3444
Jeff Brown54bc2812010-06-15 01:31:58 -07003445 case STATUS_ZOMBIE:
3446 return "ZOMBIE";
3447
3448 default:
3449 return "UNKNOWN";
3450 }
3451}
3452
Jeff Browne839a582010-04-22 18:58:52 -07003453InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3454 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003455 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3456 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003457 if (dispatchEntry->eventEntry == eventEntry) {
3458 return dispatchEntry;
3459 }
3460 }
3461 return NULL;
3462}
3463
Jeff Browna665ca82010-09-08 11:49:43 -07003464
Jeff Brown54bc2812010-06-15 01:31:58 -07003465// --- InputDispatcher::CommandEntry ---
3466
Jeff Browna665ca82010-09-08 11:49:43 -07003467InputDispatcher::CommandEntry::CommandEntry() :
3468 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003469}
3470
3471InputDispatcher::CommandEntry::~CommandEntry() {
3472}
3473
Jeff Browne839a582010-04-22 18:58:52 -07003474
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003475// --- InputDispatcher::TouchState ---
3476
3477InputDispatcher::TouchState::TouchState() :
3478 down(false), split(false) {
3479}
3480
3481InputDispatcher::TouchState::~TouchState() {
3482}
3483
3484void InputDispatcher::TouchState::reset() {
3485 down = false;
3486 split = false;
3487 windows.clear();
3488}
3489
3490void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3491 down = other.down;
3492 split = other.split;
3493 windows.clear();
3494 windows.appendVector(other.windows);
3495}
3496
3497void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3498 int32_t targetFlags, BitSet32 pointerIds) {
3499 if (targetFlags & InputTarget::FLAG_SPLIT) {
3500 split = true;
3501 }
3502
3503 for (size_t i = 0; i < windows.size(); i++) {
3504 TouchedWindow& touchedWindow = windows.editItemAt(i);
3505 if (touchedWindow.window == window) {
3506 touchedWindow.targetFlags |= targetFlags;
3507 touchedWindow.pointerIds.value |= pointerIds.value;
3508 return;
3509 }
3510 }
3511
3512 windows.push();
3513
3514 TouchedWindow& touchedWindow = windows.editTop();
3515 touchedWindow.window = window;
3516 touchedWindow.targetFlags = targetFlags;
3517 touchedWindow.pointerIds = pointerIds;
3518 touchedWindow.channel = window->inputChannel;
3519}
3520
3521void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3522 for (size_t i = 0 ; i < windows.size(); ) {
3523 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3524 windows.removeAt(i);
3525 } else {
3526 i += 1;
3527 }
3528 }
3529}
3530
3531const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3532 for (size_t i = 0; i < windows.size(); i++) {
3533 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3534 return windows[i].window;
3535 }
3536 }
3537 return NULL;
3538}
3539
3540
Jeff Browne839a582010-04-22 18:58:52 -07003541// --- InputDispatcherThread ---
3542
3543InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3544 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3545}
3546
3547InputDispatcherThread::~InputDispatcherThread() {
3548}
3549
3550bool InputDispatcherThread::threadLoop() {
3551 mDispatcher->dispatchOnce();
3552 return true;
3553}
3554
3555} // namespace android