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