blob: 1f6a9200a393f833dbf56928beaf8fec16be4139 [file] [log] [blame]
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001//
2// Copyright 2010 The Android Open Source Project
3//
4// The input dispatcher.
5//
6#define LOG_TAG "InputDispatcher"
7
8//#define LOG_NDEBUG 0
9
10// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070011#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070012
13// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070014#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070015
16// Log debug messages about batching.
Jeff Brown349703e2010-06-22 01:27:15 -070017#define DEBUG_BATCHING 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070018
19// Log debug messages about the dispatch cycle.
Jeff Brown349703e2010-06-22 01:27:15 -070020#define DEBUG_DISPATCH_CYCLE 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070021
Jeff Brown9c3cda02010-06-15 01:31:58 -070022// Log debug messages about registrations.
Jeff Brown349703e2010-06-22 01:27:15 -070023#define DEBUG_REGISTRATION 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070024
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070025// Log debug messages about performance statistics.
Jeff Brown349703e2010-06-22 01:27:15 -070026#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070027
Jeff Brown7fbdc842010-06-17 20:52:56 -070028// Log debug messages about input event injection.
Jeff Brown349703e2010-06-22 01:27:15 -070029#define DEBUG_INJECTION 0
Jeff Brown7fbdc842010-06-17 20:52:56 -070030
Jeff Brownae9fc032010-08-18 15:51:08 -070031// Log debug messages about input event throttling.
32#define DEBUG_THROTTLING 0
33
Jeff Brownb88102f2010-09-08 11:49:43 -070034// Log debug messages about input focus tracking.
35#define DEBUG_FOCUS 0
36
37// Log debug messages about the app switch latency optimization.
38#define DEBUG_APP_SWITCH 0
39
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070040#include <cutils/log.h>
41#include <ui/InputDispatcher.h>
Jeff Brownb88102f2010-09-08 11:49:43 -070042#include <ui/PowerManager.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070043
44#include <stddef.h>
45#include <unistd.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070046#include <errno.h>
47#include <limits.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070048
Jeff Brownf2f487182010-10-01 17:46:21 -070049#define INDENT " "
50#define INDENT2 " "
51
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070052namespace android {
53
Jeff Brownb88102f2010-09-08 11:49:43 -070054// Default input dispatching timeout if there is no focused application or paused window
55// from which to determine an appropriate dispatching timeout.
56const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
57
58// Amount of time to allow for all pending events to be processed when an app switch
59// key is on the way. This is used to preempt input dispatch and drop input events
60// when an application takes too long to respond and the user has pressed an app switch key.
61const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
62
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070063
Jeff Brown7fbdc842010-06-17 20:52:56 -070064static inline nsecs_t now() {
65 return systemTime(SYSTEM_TIME_MONOTONIC);
66}
67
Jeff Brownb88102f2010-09-08 11:49:43 -070068static inline const char* toString(bool value) {
69 return value ? "true" : "false";
70}
71
Jeff Brown01ce2e92010-09-26 22:20:12 -070072static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
73 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
74 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
75}
76
77static bool isValidKeyAction(int32_t action) {
78 switch (action) {
79 case AKEY_EVENT_ACTION_DOWN:
80 case AKEY_EVENT_ACTION_UP:
81 return true;
82 default:
83 return false;
84 }
85}
86
87static bool validateKeyEvent(int32_t action) {
88 if (! isValidKeyAction(action)) {
89 LOGE("Key event has invalid action code 0x%x", action);
90 return false;
91 }
92 return true;
93}
94
Jeff Brownb6997262010-10-08 22:31:17 -070095static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brown01ce2e92010-09-26 22:20:12 -070096 switch (action & AMOTION_EVENT_ACTION_MASK) {
97 case AMOTION_EVENT_ACTION_DOWN:
98 case AMOTION_EVENT_ACTION_UP:
99 case AMOTION_EVENT_ACTION_CANCEL:
100 case AMOTION_EVENT_ACTION_MOVE:
Jeff Brown01ce2e92010-09-26 22:20:12 -0700101 case AMOTION_EVENT_ACTION_OUTSIDE:
102 return true;
Jeff Brownb6997262010-10-08 22:31:17 -0700103 case AMOTION_EVENT_ACTION_POINTER_DOWN:
104 case AMOTION_EVENT_ACTION_POINTER_UP: {
105 int32_t index = getMotionEventActionPointerIndex(action);
106 return index >= 0 && size_t(index) < pointerCount;
107 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700108 default:
109 return false;
110 }
111}
112
113static bool validateMotionEvent(int32_t action, size_t pointerCount,
114 const int32_t* pointerIds) {
Jeff Brownb6997262010-10-08 22:31:17 -0700115 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700116 LOGE("Motion event has invalid action code 0x%x", action);
117 return false;
118 }
119 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
120 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
121 pointerCount, MAX_POINTERS);
122 return false;
123 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700124 BitSet32 pointerIdBits;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700125 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownc3db8582010-10-20 15:33:38 -0700126 int32_t id = pointerIds[i];
127 if (id < 0 || id > MAX_POINTER_ID) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700128 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
Jeff Brownc3db8582010-10-20 15:33:38 -0700129 id, MAX_POINTER_ID);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700130 return false;
131 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700132 if (pointerIdBits.hasBit(id)) {
133 LOGE("Motion event has duplicate pointer id %d", id);
134 return false;
135 }
136 pointerIdBits.markBit(id);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700137 }
138 return true;
139}
140
Jeff Brownb88102f2010-09-08 11:49:43 -0700141
142// --- InputWindow ---
143
Jeff Brownb88102f2010-09-08 11:49:43 -0700144bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
145 return x >= touchableAreaLeft && x <= touchableAreaRight
146 && y >= touchableAreaTop && y <= touchableAreaBottom;
147}
148
Jeff Brown19dfc832010-10-05 12:26:23 -0700149bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
150 return x >= frameLeft && x <= frameRight
151 && y >= frameTop && y <= frameBottom;
152}
153
154bool InputWindow::isTrustedOverlay() const {
155 return layoutParamsType == TYPE_INPUT_METHOD
Jeff Brown3b2b3542010-10-15 00:54:27 -0700156 || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
157 || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
Jeff Brown19dfc832010-10-05 12:26:23 -0700158}
159
Jeff Brown46e75292010-11-10 16:53:45 -0800160bool InputWindow::supportsSplitTouch() const {
161 return layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH;
162}
163
Jeff Brownb88102f2010-09-08 11:49:43 -0700164
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700165// --- InputDispatcher ---
166
Jeff Brown9c3cda02010-06-15 01:31:58 -0700167InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Brownb88102f2010-09-08 11:49:43 -0700168 mPolicy(policy),
169 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
170 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brown01ce2e92010-09-26 22:20:12 -0700171 mFocusedWindow(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700172 mFocusedApplication(NULL),
173 mCurrentInputTargetsValid(false),
174 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700175 mLooper = new Looper(false);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700176
Jeff Brownb88102f2010-09-08 11:49:43 -0700177 mInboundQueue.headSentinel.refCount = -1;
178 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
179 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700180
Jeff Brownb88102f2010-09-08 11:49:43 -0700181 mInboundQueue.tailSentinel.refCount = -1;
182 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
183 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700184
185 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700186
Jeff Brownae9fc032010-08-18 15:51:08 -0700187 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
188 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
189 mThrottleState.lastDeviceId = -1;
190
191#if DEBUG_THROTTLING
192 mThrottleState.originalSampleCount = 0;
193 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
194#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700195}
196
197InputDispatcher::~InputDispatcher() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700198 { // acquire lock
199 AutoMutex _l(mLock);
200
201 resetKeyRepeatLocked();
Jeff Brown54a18252010-09-16 14:07:33 -0700202 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700203 drainInboundQueueLocked();
204 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700205
206 while (mConnectionsByReceiveFd.size() != 0) {
207 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
208 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700209}
210
211void InputDispatcher::dispatchOnce() {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700212 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700213 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700214
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700215 nsecs_t nextWakeupTime = LONG_LONG_MAX;
216 { // acquire lock
217 AutoMutex _l(mLock);
Jeff Brownb88102f2010-09-08 11:49:43 -0700218 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700219
Jeff Brownb88102f2010-09-08 11:49:43 -0700220 if (runCommandsLockedInterruptible()) {
221 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700222 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700223 } // release lock
224
Jeff Brownb88102f2010-09-08 11:49:43 -0700225 // Wait for callback or timeout or wake. (make sure we round up, not down)
226 nsecs_t currentTime = now();
227 int32_t timeoutMillis;
228 if (nextWakeupTime > currentTime) {
229 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
230 timeout = (timeout + 999999LL) / 1000000LL;
231 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
232 } else {
233 timeoutMillis = 0;
234 }
235
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700236 mLooper->pollOnce(timeoutMillis);
Jeff Brownb88102f2010-09-08 11:49:43 -0700237}
238
239void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
240 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
241 nsecs_t currentTime = now();
242
243 // Reset the key repeat timer whenever we disallow key events, even if the next event
244 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
245 // out of sleep.
246 if (keyRepeatTimeout < 0) {
247 resetKeyRepeatLocked();
248 }
249
Jeff Brownb88102f2010-09-08 11:49:43 -0700250 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
251 if (mDispatchFrozen) {
252#if DEBUG_FOCUS
253 LOGD("Dispatch frozen. Waiting some more.");
254#endif
255 return;
256 }
257
258 // Optimize latency of app switches.
259 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
260 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
261 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
262 if (mAppSwitchDueTime < *nextWakeupTime) {
263 *nextWakeupTime = mAppSwitchDueTime;
264 }
265
Jeff Brownb88102f2010-09-08 11:49:43 -0700266 // Ready to start a new event.
267 // If we don't already have a pending event, go grab one.
268 if (! mPendingEvent) {
269 if (mInboundQueue.isEmpty()) {
270 if (isAppSwitchDue) {
271 // The inbound queue is empty so the app switch key we were waiting
272 // for will never arrive. Stop waiting for it.
273 resetPendingAppSwitchLocked(false);
274 isAppSwitchDue = false;
275 }
276
277 // Synthesize a key repeat if appropriate.
278 if (mKeyRepeatState.lastKeyEntry) {
279 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
280 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
281 } else {
282 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
283 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
284 }
285 }
286 }
287 if (! mPendingEvent) {
288 return;
289 }
290 } else {
291 // Inbound queue has at least one entry.
292 EventEntry* entry = mInboundQueue.headSentinel.next;
293
294 // Throttle the entry if it is a move event and there are no
295 // other events behind it in the queue. Due to movement batching, additional
296 // samples may be appended to this event by the time the throttling timeout
297 // expires.
298 // TODO Make this smarter and consider throttling per device independently.
Jeff Brownb6997262010-10-08 22:31:17 -0700299 if (entry->type == EventEntry::TYPE_MOTION
300 && !isAppSwitchDue
301 && mDispatchEnabled
302 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
303 && !entry->isInjected()) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700304 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
305 int32_t deviceId = motionEntry->deviceId;
306 uint32_t source = motionEntry->source;
307 if (! isAppSwitchDue
308 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
309 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
310 && deviceId == mThrottleState.lastDeviceId
311 && source == mThrottleState.lastSource) {
312 nsecs_t nextTime = mThrottleState.lastEventTime
313 + mThrottleState.minTimeBetweenEvents;
314 if (currentTime < nextTime) {
315 // Throttle it!
316#if DEBUG_THROTTLING
317 LOGD("Throttling - Delaying motion event for "
Jeff Brown90655042010-12-02 13:50:46 -0800318 "device %d, source 0x%08x by up to %0.3fms.",
Jeff Brownb88102f2010-09-08 11:49:43 -0700319 deviceId, source, (nextTime - currentTime) * 0.000001);
320#endif
321 if (nextTime < *nextWakeupTime) {
322 *nextWakeupTime = nextTime;
323 }
324 if (mThrottleState.originalSampleCount == 0) {
325 mThrottleState.originalSampleCount =
326 motionEntry->countSamples();
327 }
328 return;
329 }
330 }
331
332#if DEBUG_THROTTLING
333 if (mThrottleState.originalSampleCount != 0) {
334 uint32_t count = motionEntry->countSamples();
335 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
336 count - mThrottleState.originalSampleCount,
337 mThrottleState.originalSampleCount, count);
338 mThrottleState.originalSampleCount = 0;
339 }
340#endif
341
342 mThrottleState.lastEventTime = entry->eventTime < currentTime
343 ? entry->eventTime : currentTime;
344 mThrottleState.lastDeviceId = deviceId;
345 mThrottleState.lastSource = source;
346 }
347
348 mInboundQueue.dequeue(entry);
349 mPendingEvent = entry;
350 }
Jeff Browne2fe69e2010-10-18 13:21:23 -0700351
352 // Poke user activity for this event.
353 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
354 pokeUserActivityLocked(mPendingEvent);
355 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700356 }
357
358 // Now we have an event to dispatch.
359 assert(mPendingEvent != NULL);
Jeff Brown54a18252010-09-16 14:07:33 -0700360 bool done = false;
Jeff Brownb6997262010-10-08 22:31:17 -0700361 DropReason dropReason = DROP_REASON_NOT_DROPPED;
362 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
363 dropReason = DROP_REASON_POLICY;
364 } else if (!mDispatchEnabled) {
365 dropReason = DROP_REASON_DISABLED;
366 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700367 switch (mPendingEvent->type) {
368 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
369 ConfigurationChangedEntry* typedEntry =
370 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700371 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brownb6997262010-10-08 22:31:17 -0700372 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Brownb88102f2010-09-08 11:49:43 -0700373 break;
374 }
375
376 case EventEntry::TYPE_KEY: {
377 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700378 if (isAppSwitchDue) {
379 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700380 resetPendingAppSwitchLocked(true);
Jeff Brownb6997262010-10-08 22:31:17 -0700381 isAppSwitchDue = false;
382 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
383 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700384 }
385 }
Jeff Brownb6997262010-10-08 22:31:17 -0700386 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Browne20c9e02010-10-11 14:20:19 -0700387 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700388 break;
389 }
390
391 case EventEntry::TYPE_MOTION: {
392 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700393 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
394 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700395 }
Jeff Brownb6997262010-10-08 22:31:17 -0700396 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Browne20c9e02010-10-11 14:20:19 -0700397 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700398 break;
399 }
400
401 default:
402 assert(false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700403 break;
404 }
405
Jeff Brown54a18252010-09-16 14:07:33 -0700406 if (done) {
Jeff Brownb6997262010-10-08 22:31:17 -0700407 if (dropReason != DROP_REASON_NOT_DROPPED) {
408 dropInboundEventLocked(mPendingEvent, dropReason);
409 }
410
Jeff Brown54a18252010-09-16 14:07:33 -0700411 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700412 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
413 }
414}
415
416bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
417 bool needWake = mInboundQueue.isEmpty();
418 mInboundQueue.enqueueAtTail(entry);
419
420 switch (entry->type) {
Jeff Brownb6997262010-10-08 22:31:17 -0700421 case EventEntry::TYPE_KEY: {
422 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
423 if (isAppSwitchKeyEventLocked(keyEntry)) {
424 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
425 mAppSwitchSawKeyDown = true;
426 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
427 if (mAppSwitchSawKeyDown) {
428#if DEBUG_APP_SWITCH
429 LOGD("App switch is pending!");
430#endif
431 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
432 mAppSwitchSawKeyDown = false;
433 needWake = true;
434 }
435 }
436 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700437 break;
438 }
Jeff Brownb6997262010-10-08 22:31:17 -0700439 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700440
441 return needWake;
442}
443
Jeff Brownb6997262010-10-08 22:31:17 -0700444void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
445 const char* reason;
446 switch (dropReason) {
447 case DROP_REASON_POLICY:
Jeff Browne20c9e02010-10-11 14:20:19 -0700448#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown3122e442010-10-11 23:32:49 -0700449 LOGD("Dropped event because policy consumed it.");
Jeff Browne20c9e02010-10-11 14:20:19 -0700450#endif
Jeff Brown3122e442010-10-11 23:32:49 -0700451 reason = "inbound event was dropped because the policy consumed it";
Jeff Brownb6997262010-10-08 22:31:17 -0700452 break;
453 case DROP_REASON_DISABLED:
454 LOGI("Dropped event because input dispatch is disabled.");
455 reason = "inbound event was dropped because input dispatch is disabled";
456 break;
457 case DROP_REASON_APP_SWITCH:
458 LOGI("Dropped event because of pending overdue app switch.");
459 reason = "inbound event was dropped because of pending overdue app switch";
460 break;
461 default:
462 assert(false);
463 return;
464 }
465
466 switch (entry->type) {
467 case EventEntry::TYPE_KEY:
468 synthesizeCancelationEventsForAllConnectionsLocked(
469 InputState::CANCEL_NON_POINTER_EVENTS, reason);
470 break;
471 case EventEntry::TYPE_MOTION: {
472 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
473 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
474 synthesizeCancelationEventsForAllConnectionsLocked(
475 InputState::CANCEL_POINTER_EVENTS, reason);
476 } else {
477 synthesizeCancelationEventsForAllConnectionsLocked(
478 InputState::CANCEL_NON_POINTER_EVENTS, reason);
479 }
480 break;
481 }
482 }
483}
484
485bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700486 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
487}
488
Jeff Brownb6997262010-10-08 22:31:17 -0700489bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
490 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
491 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Browne20c9e02010-10-11 14:20:19 -0700492 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brownb6997262010-10-08 22:31:17 -0700493 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
494}
495
Jeff Brownb88102f2010-09-08 11:49:43 -0700496bool InputDispatcher::isAppSwitchPendingLocked() {
497 return mAppSwitchDueTime != LONG_LONG_MAX;
498}
499
Jeff Brownb88102f2010-09-08 11:49:43 -0700500void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
501 mAppSwitchDueTime = LONG_LONG_MAX;
502
503#if DEBUG_APP_SWITCH
504 if (handled) {
505 LOGD("App switch has arrived.");
506 } else {
507 LOGD("App switch was abandoned.");
508 }
509#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700510}
511
Jeff Brown9c3cda02010-06-15 01:31:58 -0700512bool InputDispatcher::runCommandsLockedInterruptible() {
513 if (mCommandQueue.isEmpty()) {
514 return false;
515 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700516
Jeff Brown9c3cda02010-06-15 01:31:58 -0700517 do {
518 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
519
520 Command command = commandEntry->command;
521 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
522
Jeff Brown7fbdc842010-06-17 20:52:56 -0700523 commandEntry->connection.clear();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700524 mAllocator.releaseCommandEntry(commandEntry);
525 } while (! mCommandQueue.isEmpty());
526 return true;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700527}
528
Jeff Brown9c3cda02010-06-15 01:31:58 -0700529InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
530 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
531 mCommandQueue.enqueueAtTail(commandEntry);
532 return commandEntry;
533}
534
Jeff Brownb88102f2010-09-08 11:49:43 -0700535void InputDispatcher::drainInboundQueueLocked() {
536 while (! mInboundQueue.isEmpty()) {
537 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700538 releaseInboundEventLocked(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700539 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700540}
541
Jeff Brown54a18252010-09-16 14:07:33 -0700542void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700543 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700544 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700545 mPendingEvent = NULL;
546 }
547}
548
Jeff Brown54a18252010-09-16 14:07:33 -0700549void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700550 InjectionState* injectionState = entry->injectionState;
551 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700552#if DEBUG_DISPATCH_CYCLE
Jeff Brown01ce2e92010-09-26 22:20:12 -0700553 LOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700554#endif
555 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
556 }
557 mAllocator.releaseEventEntry(entry);
558}
559
Jeff Brownb88102f2010-09-08 11:49:43 -0700560void InputDispatcher::resetKeyRepeatLocked() {
561 if (mKeyRepeatState.lastKeyEntry) {
562 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
563 mKeyRepeatState.lastKeyEntry = NULL;
564 }
565}
566
567InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brownb21fb102010-09-07 10:44:57 -0700568 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown349703e2010-06-22 01:27:15 -0700569 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
570
Jeff Brown349703e2010-06-22 01:27:15 -0700571 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Browne20c9e02010-10-11 14:20:19 -0700572 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
573 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700574 if (entry->refCount == 1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700575 mAllocator.recycleKeyEntry(entry);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700576 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700577 entry->policyFlags = policyFlags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700578 entry->repeatCount += 1;
579 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700580 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700581 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700582 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700583 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700584
585 mKeyRepeatState.lastKeyEntry = newEntry;
586 mAllocator.releaseKeyEntry(entry);
587
588 entry = newEntry;
589 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700590 entry->syntheticRepeat = true;
591
592 // Increment reference count since we keep a reference to the event in
593 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
594 entry->refCount += 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700595
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700596 if (entry->repeatCount == 1) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700597 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700598 }
599
Jeff Brownb21fb102010-09-07 10:44:57 -0700600 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700601 return entry;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700602}
603
Jeff Brownb88102f2010-09-08 11:49:43 -0700604bool InputDispatcher::dispatchConfigurationChangedLocked(
605 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700606#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownb88102f2010-09-08 11:49:43 -0700607 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
608#endif
609
610 // Reset key repeating in case a keyboard device was added or removed or something.
611 resetKeyRepeatLocked();
612
613 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
614 CommandEntry* commandEntry = postCommandLocked(
615 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
616 commandEntry->eventTime = entry->eventTime;
617 return true;
618}
619
620bool InputDispatcher::dispatchKeyLocked(
621 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Browne20c9e02010-10-11 14:20:19 -0700622 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700623 // Preprocessing.
624 if (! entry->dispatchInProgress) {
625 if (entry->repeatCount == 0
626 && entry->action == AKEY_EVENT_ACTION_DOWN
627 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
628 && !entry->isInjected()) {
629 if (mKeyRepeatState.lastKeyEntry
630 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
631 // We have seen two identical key downs in a row which indicates that the device
632 // driver is automatically generating key repeats itself. We take note of the
633 // repeat here, but we disable our own next key repeat timer since it is clear that
634 // we will not need to synthesize key repeats ourselves.
635 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
636 resetKeyRepeatLocked();
637 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
638 } else {
639 // Not a repeat. Save key down state in case we do see a repeat later.
640 resetKeyRepeatLocked();
641 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
642 }
643 mKeyRepeatState.lastKeyEntry = entry;
644 entry->refCount += 1;
645 } else if (! entry->syntheticRepeat) {
646 resetKeyRepeatLocked();
647 }
648
649 entry->dispatchInProgress = true;
650 resetTargetsLocked();
651
652 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
653 }
654
Jeff Brown54a18252010-09-16 14:07:33 -0700655 // Give the policy a chance to intercept the key.
656 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700657 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brown54a18252010-09-16 14:07:33 -0700658 CommandEntry* commandEntry = postCommandLocked(
659 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Browne20c9e02010-10-11 14:20:19 -0700660 if (mFocusedWindow) {
Jeff Brown54a18252010-09-16 14:07:33 -0700661 commandEntry->inputChannel = mFocusedWindow->inputChannel;
662 }
663 commandEntry->keyEntry = entry;
664 entry->refCount += 1;
665 return false; // wait for the command to run
666 } else {
667 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
668 }
669 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700670 if (*dropReason == DROP_REASON_NOT_DROPPED) {
671 *dropReason = DROP_REASON_POLICY;
672 }
Jeff Brown54a18252010-09-16 14:07:33 -0700673 }
674
675 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700676 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700677 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700678 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
679 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700680 return true;
681 }
682
Jeff Brownb88102f2010-09-08 11:49:43 -0700683 // Identify targets.
684 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700685 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
686 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700687 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
688 return false;
689 }
690
691 setInjectionResultLocked(entry, injectionResult);
692 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
693 return true;
694 }
695
696 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700697 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700698 }
699
700 // Dispatch the key.
701 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700702 return true;
703}
704
705void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
706#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800707 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brownb88102f2010-09-08 11:49:43 -0700708 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
Jeff Browne46a0a42010-11-02 17:58:22 -0700709 "repeatCount=%d, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700710 prefix,
711 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
712 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Jeff Browne46a0a42010-11-02 17:58:22 -0700713 entry->repeatCount, entry->downTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700714#endif
715}
716
717bool InputDispatcher::dispatchMotionLocked(
Jeff Browne20c9e02010-10-11 14:20:19 -0700718 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700719 // Preprocessing.
720 if (! entry->dispatchInProgress) {
721 entry->dispatchInProgress = true;
722 resetTargetsLocked();
723
724 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
725 }
726
Jeff Brown54a18252010-09-16 14:07:33 -0700727 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700728 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700729 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700730 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
731 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700732 return true;
733 }
734
Jeff Brownb88102f2010-09-08 11:49:43 -0700735 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
736
737 // Identify targets.
738 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700739 int32_t injectionResult;
740 if (isPointerEvent) {
741 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700742 injectionResult = findTouchedWindowTargetsLocked(currentTime,
743 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700744 } else {
745 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700746 injectionResult = findFocusedWindowTargetsLocked(currentTime,
747 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700748 }
749 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
750 return false;
751 }
752
753 setInjectionResultLocked(entry, injectionResult);
754 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
755 return true;
756 }
757
758 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700759 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700760 }
761
762 // Dispatch the motion.
763 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700764 return true;
765}
766
767
768void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
769#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800770 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700771 "action=0x%x, flags=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700772 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700773 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700774 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
775 entry->action, entry->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700776 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
777 entry->downTime);
778
779 // Print the most recent sample that we have available, this may change due to batching.
780 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700781 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700782 for (; sample->next != NULL; sample = sample->next) {
783 sampleCount += 1;
784 }
785 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -0700786 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700787 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700788 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700789 i, entry->pointerIds[i],
Jeff Brown8d608662010-08-30 03:02:23 -0700790 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
791 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
792 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
793 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
794 sample->pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700795 }
796
797 // Keep in mind that due to batching, it is possible for the number of samples actually
798 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700799 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700800 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
801 }
802#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700803}
804
805void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
806 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
807#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -0700808 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700809 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700810 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700811#endif
812
Jeff Brown9c3cda02010-06-15 01:31:58 -0700813 assert(eventEntry->dispatchInProgress); // should already have been set to true
814
Jeff Browne2fe69e2010-10-18 13:21:23 -0700815 pokeUserActivityLocked(eventEntry);
816
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700817 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
818 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
819
Jeff Brown519e0242010-09-15 15:18:56 -0700820 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700821 if (connectionIndex >= 0) {
822 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700823 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700824 resumeWithAppendedMotionSample);
825 } else {
Jeff Brownb6997262010-10-08 22:31:17 -0700826#if DEBUG_FOCUS
827 LOGD("Dropping event delivery to target with channel '%s' because it "
828 "is no longer registered with the input dispatcher.",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700829 inputTarget.inputChannel->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -0700830#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700831 }
832 }
833}
834
Jeff Brown54a18252010-09-16 14:07:33 -0700835void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700836 mCurrentInputTargetsValid = false;
837 mCurrentInputTargets.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700838 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
839}
840
Jeff Brown01ce2e92010-09-26 22:20:12 -0700841void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700842 mCurrentInputTargetsValid = true;
843}
844
845int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
846 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
847 nsecs_t* nextWakeupTime) {
848 if (application == NULL && window == NULL) {
849 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
850#if DEBUG_FOCUS
851 LOGD("Waiting for system to become ready for input.");
852#endif
853 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
854 mInputTargetWaitStartTime = currentTime;
855 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
856 mInputTargetWaitTimeoutExpired = false;
857 }
858 } else {
859 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
860#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700861 LOGD("Waiting for application to become ready for input: %s",
862 getApplicationWindowLabelLocked(application, window).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700863#endif
864 nsecs_t timeout = window ? window->dispatchingTimeout :
865 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
866
867 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
868 mInputTargetWaitStartTime = currentTime;
869 mInputTargetWaitTimeoutTime = currentTime + timeout;
870 mInputTargetWaitTimeoutExpired = false;
871 }
872 }
873
874 if (mInputTargetWaitTimeoutExpired) {
875 return INPUT_EVENT_INJECTION_TIMED_OUT;
876 }
877
878 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown519e0242010-09-15 15:18:56 -0700879 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700880
881 // Force poll loop to wake up immediately on next iteration once we get the
882 // ANR response back from the policy.
883 *nextWakeupTime = LONG_LONG_MIN;
884 return INPUT_EVENT_INJECTION_PENDING;
885 } else {
886 // Force poll loop to wake up when timeout is due.
887 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
888 *nextWakeupTime = mInputTargetWaitTimeoutTime;
889 }
890 return INPUT_EVENT_INJECTION_PENDING;
891 }
892}
893
Jeff Brown519e0242010-09-15 15:18:56 -0700894void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
895 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700896 if (newTimeout > 0) {
897 // Extend the timeout.
898 mInputTargetWaitTimeoutTime = now() + newTimeout;
899 } else {
900 // Give up.
901 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -0700902
Jeff Brown01ce2e92010-09-26 22:20:12 -0700903 // Release the touch targets.
904 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -0700905
Jeff Brown519e0242010-09-15 15:18:56 -0700906 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -0700907 if (inputChannel.get()) {
908 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
909 if (connectionIndex >= 0) {
910 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brownb6997262010-10-08 22:31:17 -0700911 synthesizeCancelationEventsForConnectionLocked(
912 connection, InputState::CANCEL_ALL_EVENTS,
913 "application not responding");
Jeff Browndc3e0052010-09-16 11:02:16 -0700914 }
Jeff Brown519e0242010-09-15 15:18:56 -0700915 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700916 }
917}
918
Jeff Brown519e0242010-09-15 15:18:56 -0700919nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -0700920 nsecs_t currentTime) {
921 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
922 return currentTime - mInputTargetWaitStartTime;
923 }
924 return 0;
925}
926
927void InputDispatcher::resetANRTimeoutsLocked() {
928#if DEBUG_FOCUS
929 LOGD("Resetting ANR timeouts.");
930#endif
931
Jeff Brownb88102f2010-09-08 11:49:43 -0700932 // Reset input target wait timeout.
933 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
934}
935
Jeff Brown01ce2e92010-09-26 22:20:12 -0700936int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
937 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700938 mCurrentInputTargets.clear();
939
940 int32_t injectionResult;
941
942 // If there is no currently focused window and no focused application
943 // then drop the event.
944 if (! mFocusedWindow) {
945 if (mFocusedApplication) {
946#if DEBUG_FOCUS
947 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -0700948 "focused application that may eventually add a window: %s.",
949 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700950#endif
951 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
952 mFocusedApplication, NULL, nextWakeupTime);
953 goto Unresponsive;
954 }
955
956 LOGI("Dropping event because there is no focused window or focused application.");
957 injectionResult = INPUT_EVENT_INJECTION_FAILED;
958 goto Failed;
959 }
960
961 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700962 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700963 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
964 goto Failed;
965 }
966
967 // If the currently focused window is paused then keep waiting.
968 if (mFocusedWindow->paused) {
969#if DEBUG_FOCUS
970 LOGD("Waiting because focused window is paused.");
971#endif
972 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
973 mFocusedApplication, mFocusedWindow, nextWakeupTime);
974 goto Unresponsive;
975 }
976
Jeff Brown519e0242010-09-15 15:18:56 -0700977 // If the currently focused window is still working on previous events then keep waiting.
978 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
979#if DEBUG_FOCUS
980 LOGD("Waiting because focused window still processing previous input.");
981#endif
982 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
983 mFocusedApplication, mFocusedWindow, nextWakeupTime);
984 goto Unresponsive;
985 }
986
Jeff Brownb88102f2010-09-08 11:49:43 -0700987 // Success! Output targets.
988 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700989 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -0700990
991 // Done.
992Failed:
993Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -0700994 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
995 updateDispatchStatisticsLocked(currentTime, entry,
996 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -0700997#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700998 LOGD("findFocusedWindow finished: injectionResult=%d, "
999 "timeSpendWaitingForApplication=%0.1fms",
1000 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001001#endif
1002 return injectionResult;
1003}
1004
Jeff Brown01ce2e92010-09-26 22:20:12 -07001005int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1006 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001007 enum InjectionPermission {
1008 INJECTION_PERMISSION_UNKNOWN,
1009 INJECTION_PERMISSION_GRANTED,
1010 INJECTION_PERMISSION_DENIED
1011 };
1012
Jeff Brownb88102f2010-09-08 11:49:43 -07001013 mCurrentInputTargets.clear();
1014
1015 nsecs_t startTime = now();
1016
1017 // For security reasons, we defer updating the touch state until we are sure that
1018 // event injection will be allowed.
1019 //
1020 // FIXME In the original code, screenWasOff could never be set to true.
1021 // The reason is that the POLICY_FLAG_WOKE_HERE
1022 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1023 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1024 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1025 // events upon which no preprocessing took place. So policyFlags was always 0.
1026 // In the new native input dispatcher we're a bit more careful about event
1027 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1028 // Unfortunately we obtain undesirable behavior.
1029 //
1030 // Here's what happens:
1031 //
1032 // When the device dims in anticipation of going to sleep, touches
1033 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1034 // the device to brighten and reset the user activity timer.
1035 // Touches on other windows (such as the launcher window)
1036 // are dropped. Then after a moment, the device goes to sleep. Oops.
1037 //
1038 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1039 // instead of POLICY_FLAG_WOKE_HERE...
1040 //
1041 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1042
1043 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001044 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001045
1046 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001047 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1048 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1049 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1050 mTempTouchState.reset();
1051 mTempTouchState.down = true;
1052 } else {
1053 mTempTouchState.copyFrom(mTouchState);
1054 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001055
Jeff Brown01ce2e92010-09-26 22:20:12 -07001056 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1057 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1058 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1059 /* Case 1: New splittable pointer going down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001060
Jeff Brown01ce2e92010-09-26 22:20:12 -07001061 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1062 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1063 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1064 const InputWindow* newTouchedWindow = NULL;
1065 const InputWindow* topErrorWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07001066
1067 // Traverse windows from front to back to find touched window and outside targets.
1068 size_t numWindows = mWindows.size();
1069 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001070 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001071 int32_t flags = window->layoutParamsFlags;
1072
1073 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1074 if (! topErrorWindow) {
1075 topErrorWindow = window;
1076 }
1077 }
1078
1079 if (window->visible) {
1080 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1081 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1082 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1083 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1084 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1085 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001086 }
1087 break; // found touched window, exit window loop
1088 }
1089 }
1090
Jeff Brown01ce2e92010-09-26 22:20:12 -07001091 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1092 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001093 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1094 if (isWindowObscuredAtPointLocked(window, x, y)) {
1095 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1096 }
1097
1098 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001099 }
1100 }
1101 }
1102
1103 // If there is an error window but it is not taking focus (typically because
1104 // it is invisible) then wait for it. Any other focused window may in
1105 // fact be in ANR state.
1106 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1107#if DEBUG_FOCUS
1108 LOGD("Waiting because system error window is pending.");
1109#endif
1110 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1111 NULL, NULL, nextWakeupTime);
1112 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1113 goto Unresponsive;
1114 }
1115
Jeff Brown01ce2e92010-09-26 22:20:12 -07001116 // Figure out whether splitting will be allowed for this window.
Jeff Brown46e75292010-11-10 16:53:45 -08001117 if (newTouchedWindow && newTouchedWindow->supportsSplitTouch()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001118 // New window supports splitting.
1119 isSplit = true;
1120 } else if (isSplit) {
1121 // New window does not support splitting but we have already split events.
1122 // Assign the pointer to the first foreground window we find.
1123 // (May be NULL which is why we put this code block before the next check.)
1124 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1125 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001126
Jeff Brownb88102f2010-09-08 11:49:43 -07001127 // If we did not find a touched window then fail.
1128 if (! newTouchedWindow) {
1129 if (mFocusedApplication) {
1130#if DEBUG_FOCUS
1131 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001132 "focused application that may eventually add a new window: %s.",
1133 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001134#endif
1135 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1136 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001137 goto Unresponsive;
1138 }
1139
1140 LOGI("Dropping event because there is no touched window or focused application.");
1141 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001142 goto Failed;
1143 }
1144
Jeff Brown19dfc832010-10-05 12:26:23 -07001145 // Set target flags.
1146 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1147 if (isSplit) {
1148 targetFlags |= InputTarget::FLAG_SPLIT;
1149 }
1150 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1151 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1152 }
1153
Jeff Brown01ce2e92010-09-26 22:20:12 -07001154 // Update the temporary touch state.
1155 BitSet32 pointerIds;
1156 if (isSplit) {
1157 uint32_t pointerId = entry->pointerIds[pointerIndex];
1158 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001159 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001160 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001161 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001162 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001163
1164 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001165 if (! mTempTouchState.down) {
Jeff Brown76860e32010-10-25 17:37:46 -07001166#if DEBUG_INPUT_DISPATCHER_POLICY
1167 LOGD("Dropping event because the pointer is not down or we previously "
1168 "dropped the pointer down event.");
1169#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001170 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001171 goto Failed;
1172 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001173 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001174
Jeff Brown01ce2e92010-09-26 22:20:12 -07001175 // Check permission to inject into all touched foreground windows and ensure there
1176 // is at least one touched foreground window.
1177 {
1178 bool haveForegroundWindow = false;
1179 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1180 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1181 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1182 haveForegroundWindow = true;
1183 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1184 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1185 injectionPermission = INJECTION_PERMISSION_DENIED;
1186 goto Failed;
1187 }
1188 }
1189 }
1190 if (! haveForegroundWindow) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001191#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown01ce2e92010-09-26 22:20:12 -07001192 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001193#endif
1194 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001195 goto Failed;
1196 }
1197
Jeff Brown01ce2e92010-09-26 22:20:12 -07001198 // Permission granted to injection into all touched foreground windows.
1199 injectionPermission = INJECTION_PERMISSION_GRANTED;
1200 }
Jeff Brown519e0242010-09-15 15:18:56 -07001201
Jeff Brown01ce2e92010-09-26 22:20:12 -07001202 // Ensure all touched foreground windows are ready for new input.
1203 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1204 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1205 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1206 // If the touched window is paused then keep waiting.
1207 if (touchedWindow.window->paused) {
1208#if DEBUG_INPUT_DISPATCHER_POLICY
1209 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001210#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001211 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1212 NULL, touchedWindow.window, nextWakeupTime);
1213 goto Unresponsive;
1214 }
1215
1216 // If the touched window is still working on previous events then keep waiting.
1217 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1218#if DEBUG_FOCUS
1219 LOGD("Waiting because touched window still processing previous input.");
1220#endif
1221 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1222 NULL, touchedWindow.window, nextWakeupTime);
1223 goto Unresponsive;
1224 }
1225 }
1226 }
1227
1228 // If this is the first pointer going down and the touched window has a wallpaper
1229 // then also add the touched wallpaper windows so they are locked in for the duration
1230 // of the touch gesture.
1231 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1232 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1233 if (foregroundWindow->hasWallpaper) {
1234 for (size_t i = 0; i < mWindows.size(); i++) {
1235 const InputWindow* window = & mWindows[i];
1236 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001237 mTempTouchState.addOrUpdateWindow(window,
1238 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001239 }
1240 }
1241 }
1242 }
1243
Jeff Brownb88102f2010-09-08 11:49:43 -07001244 // Success! Output targets.
1245 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001246
Jeff Brown01ce2e92010-09-26 22:20:12 -07001247 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1248 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1249 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1250 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001251 }
1252
Jeff Brown01ce2e92010-09-26 22:20:12 -07001253 // Drop the outside touch window since we will not care about them in the next iteration.
1254 mTempTouchState.removeOutsideTouchWindows();
1255
Jeff Brownb88102f2010-09-08 11:49:43 -07001256Failed:
1257 // Check injection permission once and for all.
1258 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001259 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001260 injectionPermission = INJECTION_PERMISSION_GRANTED;
1261 } else {
1262 injectionPermission = INJECTION_PERMISSION_DENIED;
1263 }
1264 }
1265
1266 // Update final pieces of touch state if the injector had permission.
1267 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001268 if (maskedAction == AMOTION_EVENT_ACTION_UP
1269 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1270 // All pointers up or canceled.
1271 mTempTouchState.reset();
1272 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1273 // First pointer went down.
1274 if (mTouchState.down) {
Jeff Brownb6997262010-10-08 22:31:17 -07001275#if DEBUG_FOCUS
1276 LOGD("Pointer down received while already down.");
1277#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001278 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001279 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1280 // One pointer went up.
1281 if (isSplit) {
1282 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1283 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001284
Jeff Brown01ce2e92010-09-26 22:20:12 -07001285 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1286 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1287 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1288 touchedWindow.pointerIds.clearBit(pointerId);
1289 if (touchedWindow.pointerIds.isEmpty()) {
1290 mTempTouchState.windows.removeAt(i);
1291 continue;
1292 }
1293 }
1294 i += 1;
1295 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001296 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001297 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001298
1299 // Save changes to touch state.
1300 mTouchState.copyFrom(mTempTouchState);
Jeff Brownb88102f2010-09-08 11:49:43 -07001301 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001302#if DEBUG_FOCUS
1303 LOGD("Not updating touch focus because injection was denied.");
1304#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001305 }
1306
1307Unresponsive:
Jeff Brown120a4592010-10-27 18:43:51 -07001308 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1309 mTempTouchState.reset();
1310
Jeff Brown519e0242010-09-15 15:18:56 -07001311 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1312 updateDispatchStatisticsLocked(currentTime, entry,
1313 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001314#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001315 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1316 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001317 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001318#endif
1319 return injectionResult;
1320}
1321
Jeff Brown01ce2e92010-09-26 22:20:12 -07001322void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1323 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001324 mCurrentInputTargets.push();
1325
1326 InputTarget& target = mCurrentInputTargets.editTop();
1327 target.inputChannel = window->inputChannel;
1328 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001329 target.xOffset = - window->frameLeft;
1330 target.yOffset = - window->frameTop;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001331 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001332}
1333
1334void InputDispatcher::addMonitoringTargetsLocked() {
1335 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1336 mCurrentInputTargets.push();
1337
1338 InputTarget& target = mCurrentInputTargets.editTop();
1339 target.inputChannel = mMonitoringChannels[i];
1340 target.flags = 0;
Jeff Brownb88102f2010-09-08 11:49:43 -07001341 target.xOffset = 0;
1342 target.yOffset = 0;
1343 }
1344}
1345
1346bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001347 const InjectionState* injectionState) {
1348 if (injectionState
Jeff Brownb6997262010-10-08 22:31:17 -07001349 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1350 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1351 if (window) {
1352 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1353 "with input channel %s owned by uid %d",
1354 injectionState->injectorPid, injectionState->injectorUid,
1355 window->inputChannel->getName().string(),
1356 window->ownerUid);
1357 } else {
1358 LOGW("Permission denied: injecting event from pid %d uid %d",
1359 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001360 }
Jeff Brownb6997262010-10-08 22:31:17 -07001361 return false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001362 }
1363 return true;
1364}
1365
Jeff Brown19dfc832010-10-05 12:26:23 -07001366bool InputDispatcher::isWindowObscuredAtPointLocked(
1367 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07001368 size_t numWindows = mWindows.size();
1369 for (size_t i = 0; i < numWindows; i++) {
1370 const InputWindow* other = & mWindows.itemAt(i);
1371 if (other == window) {
1372 break;
1373 }
Jeff Brown19dfc832010-10-05 12:26:23 -07001374 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001375 return true;
1376 }
1377 }
1378 return false;
1379}
1380
Jeff Brown519e0242010-09-15 15:18:56 -07001381bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1382 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1383 if (connectionIndex >= 0) {
1384 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1385 return connection->outboundQueue.isEmpty();
1386 } else {
1387 return true;
1388 }
1389}
1390
1391String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1392 const InputWindow* window) {
1393 if (application) {
1394 if (window) {
1395 String8 label(application->name);
1396 label.append(" - ");
1397 label.append(window->name);
1398 return label;
1399 } else {
1400 return application->name;
1401 }
1402 } else if (window) {
1403 return window->name;
1404 } else {
1405 return String8("<unknown application or window>");
1406 }
1407}
1408
Jeff Browne2fe69e2010-10-18 13:21:23 -07001409void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1410 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brown4d396052010-10-29 21:50:21 -07001411 switch (eventEntry->type) {
1412 case EventEntry::TYPE_MOTION: {
Jeff Browne2fe69e2010-10-18 13:21:23 -07001413 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Brown4d396052010-10-29 21:50:21 -07001414 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1415 return;
1416 }
1417
Jeff Browne2fe69e2010-10-18 13:21:23 -07001418 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
Joe Onorato1a542c72010-11-08 09:48:20 -08001419 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001420 }
Jeff Brown4d396052010-10-29 21:50:21 -07001421 break;
1422 }
1423 case EventEntry::TYPE_KEY: {
1424 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1425 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1426 return;
1427 }
1428 break;
1429 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001430 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001431
Jeff Brownb88102f2010-09-08 11:49:43 -07001432 CommandEntry* commandEntry = postCommandLocked(
1433 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Browne2fe69e2010-10-18 13:21:23 -07001434 commandEntry->eventTime = eventEntry->eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001435 commandEntry->userActivityEventType = eventType;
1436}
1437
Jeff Brown7fbdc842010-06-17 20:52:56 -07001438void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1439 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001440 bool resumeWithAppendedMotionSample) {
1441#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001442 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001443 "xOffset=%f, yOffset=%f, "
1444 "windowType=%d, pointerIds=0x%x, "
1445 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001446 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001447 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001448 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001449 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001450#endif
1451
Jeff Brown01ce2e92010-09-26 22:20:12 -07001452 // Make sure we are never called for streaming when splitting across multiple windows.
1453 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1454 assert(! (resumeWithAppendedMotionSample && isSplit));
1455
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001456 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001457 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001458 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb6997262010-10-08 22:31:17 -07001459#if DEBUG_DISPATCH_CYCLE
1460 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001461 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brownb6997262010-10-08 22:31:17 -07001462#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001463 return;
1464 }
1465
Jeff Brown01ce2e92010-09-26 22:20:12 -07001466 // Split a motion event if needed.
1467 if (isSplit) {
1468 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1469
1470 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1471 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1472 MotionEntry* splitMotionEntry = splitMotionEvent(
1473 originalMotionEntry, inputTarget->pointerIds);
1474#if DEBUG_FOCUS
1475 LOGD("channel '%s' ~ Split motion event.",
1476 connection->getInputChannelName());
1477 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1478#endif
1479 eventEntry = splitMotionEntry;
1480 }
1481 }
1482
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001483 // Resume the dispatch cycle with a freshly appended motion sample.
1484 // First we check that the last dispatch entry in the outbound queue is for the same
1485 // motion event to which we appended the motion sample. If we find such a dispatch
1486 // entry, and if it is currently in progress then we try to stream the new sample.
1487 bool wasEmpty = connection->outboundQueue.isEmpty();
1488
1489 if (! wasEmpty && resumeWithAppendedMotionSample) {
1490 DispatchEntry* motionEventDispatchEntry =
1491 connection->findQueuedDispatchEntryForEvent(eventEntry);
1492 if (motionEventDispatchEntry) {
1493 // If the dispatch entry is not in progress, then we must be busy dispatching an
1494 // earlier event. Not a problem, the motion event is on the outbound queue and will
1495 // be dispatched later.
1496 if (! motionEventDispatchEntry->inProgress) {
1497#if DEBUG_BATCHING
1498 LOGD("channel '%s' ~ Not streaming because the motion event has "
1499 "not yet been dispatched. "
1500 "(Waiting for earlier events to be consumed.)",
1501 connection->getInputChannelName());
1502#endif
1503 return;
1504 }
1505
1506 // If the dispatch entry is in progress but it already has a tail of pending
1507 // motion samples, then it must mean that the shared memory buffer filled up.
1508 // Not a problem, when this dispatch cycle is finished, we will eventually start
1509 // a new dispatch cycle to process the tail and that tail includes the newly
1510 // appended motion sample.
1511 if (motionEventDispatchEntry->tailMotionSample) {
1512#if DEBUG_BATCHING
1513 LOGD("channel '%s' ~ Not streaming because no new samples can "
1514 "be appended to the motion event in this dispatch cycle. "
1515 "(Waiting for next dispatch cycle to start.)",
1516 connection->getInputChannelName());
1517#endif
1518 return;
1519 }
1520
1521 // The dispatch entry is in progress and is still potentially open for streaming.
1522 // Try to stream the new motion sample. This might fail if the consumer has already
1523 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001524 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1525 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001526 status_t status = connection->inputPublisher.appendMotionSample(
1527 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1528 if (status == OK) {
1529#if DEBUG_BATCHING
1530 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1531 connection->getInputChannelName());
1532#endif
1533 return;
1534 }
1535
1536#if DEBUG_BATCHING
1537 if (status == NO_MEMORY) {
1538 LOGD("channel '%s' ~ Could not append motion sample to currently "
1539 "dispatched move event because the shared memory buffer is full. "
1540 "(Waiting for next dispatch cycle to start.)",
1541 connection->getInputChannelName());
1542 } else if (status == status_t(FAILED_TRANSACTION)) {
1543 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001544 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001545 "(Waiting for next dispatch cycle to start.)",
1546 connection->getInputChannelName());
1547 } else {
1548 LOGD("channel '%s' ~ Could not append motion sample to currently "
1549 "dispatched move event due to an error, status=%d. "
1550 "(Waiting for next dispatch cycle to start.)",
1551 connection->getInputChannelName(), status);
1552 }
1553#endif
1554 // Failed to stream. Start a new tail of pending motion samples to dispatch
1555 // in the next cycle.
1556 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1557 return;
1558 }
1559 }
1560
1561 // This is a new event.
1562 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001563 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown519e0242010-09-15 15:18:56 -07001564 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1565 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001566 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001567 }
1568
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001569 // Handle the case where we could not stream a new motion sample because the consumer has
1570 // already consumed the motion event (otherwise the corresponding dispatch entry would
1571 // still be in the outbound queue for this connection). We set the head motion sample
1572 // to the list starting with the newly appended motion sample.
1573 if (resumeWithAppendedMotionSample) {
1574#if DEBUG_BATCHING
1575 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1576 "that cannot be streamed because the motion event has already been consumed.",
1577 connection->getInputChannelName());
1578#endif
1579 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1580 dispatchEntry->headMotionSample = appendedMotionSample;
1581 }
1582
1583 // Enqueue the dispatch entry.
1584 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1585
1586 // If the outbound queue was previously empty, start the dispatch cycle going.
1587 if (wasEmpty) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001588 activateConnectionLocked(connection.get());
Jeff Brown519e0242010-09-15 15:18:56 -07001589 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001590 }
1591}
1592
Jeff Brown7fbdc842010-06-17 20:52:56 -07001593void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001594 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001595#if DEBUG_DISPATCH_CYCLE
1596 LOGD("channel '%s' ~ startDispatchCycle",
1597 connection->getInputChannelName());
1598#endif
1599
1600 assert(connection->status == Connection::STATUS_NORMAL);
1601 assert(! connection->outboundQueue.isEmpty());
1602
Jeff Brownb88102f2010-09-08 11:49:43 -07001603 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001604 assert(! dispatchEntry->inProgress);
1605
Jeff Brownb88102f2010-09-08 11:49:43 -07001606 // Mark the dispatch entry as in progress.
1607 dispatchEntry->inProgress = true;
1608
1609 // Update the connection's input state.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001610 EventEntry* eventEntry = dispatchEntry->eventEntry;
1611 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001612
1613#if FILTER_INPUT_EVENTS
1614 // Filter out inconsistent sequences of input events.
1615 // The input system may drop or inject events in a way that could violate implicit
1616 // invariants on input state and potentially cause an application to crash
1617 // or think that a key or pointer is stuck down. Technically we make no guarantees
1618 // of consistency but it would be nice to improve on this where possible.
1619 // XXX: This code is a proof of concept only. Not ready for prime time.
1620 if (consistency == InputState::TOLERABLE) {
1621#if DEBUG_DISPATCH_CYCLE
1622 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1623 "current input state but that is likely to be tolerated by the application.",
1624 connection->getInputChannelName());
1625#endif
1626 } else if (consistency == InputState::BROKEN) {
1627 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1628 "current input state and that is likely to cause the application to crash.",
1629 connection->getInputChannelName());
1630 startNextDispatchCycleLocked(currentTime, connection);
1631 return;
1632 }
1633#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001634
1635 // Publish the event.
1636 status_t status;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001637 switch (eventEntry->type) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001638 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001639 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001640
1641 // Apply target flags.
1642 int32_t action = keyEntry->action;
1643 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001644
1645 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001646 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001647 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1648 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1649 keyEntry->eventTime);
1650
1651 if (status) {
1652 LOGE("channel '%s' ~ Could not publish key event, "
1653 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001654 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001655 return;
1656 }
1657 break;
1658 }
1659
1660 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001661 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001662
1663 // Apply target flags.
1664 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001665 int32_t flags = motionEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001666 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001667 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001668 }
Jeff Brown85a31762010-09-01 17:01:00 -07001669 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1670 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1671 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001672
1673 // If headMotionSample is non-NULL, then it points to the first new sample that we
1674 // were unable to dispatch during the previous cycle so we resume dispatching from
1675 // that point in the list of motion samples.
1676 // Otherwise, we just start from the first sample of the motion event.
1677 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1678 if (! firstMotionSample) {
1679 firstMotionSample = & motionEntry->firstSample;
1680 }
1681
Jeff Brownd3616592010-07-16 17:21:06 -07001682 // Set the X and Y offset depending on the input source.
1683 float xOffset, yOffset;
1684 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1685 xOffset = dispatchEntry->xOffset;
1686 yOffset = dispatchEntry->yOffset;
1687 } else {
1688 xOffset = 0.0f;
1689 yOffset = 0.0f;
1690 }
1691
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001692 // Publish the motion event and the first motion sample.
1693 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07001694 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownd3616592010-07-16 17:21:06 -07001695 xOffset, yOffset,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001696 motionEntry->xPrecision, motionEntry->yPrecision,
1697 motionEntry->downTime, firstMotionSample->eventTime,
1698 motionEntry->pointerCount, motionEntry->pointerIds,
1699 firstMotionSample->pointerCoords);
1700
1701 if (status) {
1702 LOGE("channel '%s' ~ Could not publish motion event, "
1703 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001704 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001705 return;
1706 }
1707
1708 // Append additional motion samples.
1709 MotionSample* nextMotionSample = firstMotionSample->next;
1710 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1711 status = connection->inputPublisher.appendMotionSample(
1712 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1713 if (status == NO_MEMORY) {
1714#if DEBUG_DISPATCH_CYCLE
1715 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1716 "be sent in the next dispatch cycle.",
1717 connection->getInputChannelName());
1718#endif
1719 break;
1720 }
1721 if (status != OK) {
1722 LOGE("channel '%s' ~ Could not append motion sample "
1723 "for a reason other than out of memory, status=%d",
1724 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001725 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001726 return;
1727 }
1728 }
1729
1730 // Remember the next motion sample that we could not dispatch, in case we ran out
1731 // of space in the shared memory buffer.
1732 dispatchEntry->tailMotionSample = nextMotionSample;
1733 break;
1734 }
1735
1736 default: {
1737 assert(false);
1738 }
1739 }
1740
1741 // Send the dispatch signal.
1742 status = connection->inputPublisher.sendDispatchSignal();
1743 if (status) {
1744 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1745 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001746 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001747 return;
1748 }
1749
1750 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001751 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001752 connection->lastDispatchTime = currentTime;
1753
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001754 // Notify other system components.
1755 onDispatchCycleStartedLocked(currentTime, connection);
1756}
1757
Jeff Brown7fbdc842010-06-17 20:52:56 -07001758void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown3915bb82010-11-05 15:02:16 -07001759 const sp<Connection>& connection, bool handled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001760#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001761 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown3915bb82010-11-05 15:02:16 -07001762 "%01.1fms since dispatch, handled=%s",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001763 connection->getInputChannelName(),
1764 connection->getEventLatencyMillis(currentTime),
Jeff Brown3915bb82010-11-05 15:02:16 -07001765 connection->getDispatchLatencyMillis(currentTime),
1766 toString(handled));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001767#endif
1768
Jeff Brown9c3cda02010-06-15 01:31:58 -07001769 if (connection->status == Connection::STATUS_BROKEN
1770 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001771 return;
1772 }
1773
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001774 // Reset the publisher since the event has been consumed.
1775 // We do this now so that the publisher can release some of its internal resources
1776 // while waiting for the next dispatch cycle to begin.
1777 status_t status = connection->inputPublisher.reset();
1778 if (status) {
1779 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1780 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001781 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001782 return;
1783 }
1784
Jeff Brown3915bb82010-11-05 15:02:16 -07001785 // Notify other system components and prepare to start the next dispatch cycle.
1786 onDispatchCycleFinishedLocked(currentTime, connection, handled);
Jeff Brownb88102f2010-09-08 11:49:43 -07001787}
1788
1789void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1790 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001791 // Start the next dispatch cycle for this connection.
1792 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001793 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001794 if (dispatchEntry->inProgress) {
1795 // Finish or resume current event in progress.
1796 if (dispatchEntry->tailMotionSample) {
1797 // We have a tail of undispatched motion samples.
1798 // Reuse the same DispatchEntry and start a new cycle.
1799 dispatchEntry->inProgress = false;
1800 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1801 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07001802 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001803 return;
1804 }
1805 // Finished.
1806 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07001807 if (dispatchEntry->hasForegroundTarget()) {
1808 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001809 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001810 mAllocator.releaseDispatchEntry(dispatchEntry);
1811 } else {
1812 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07001813 // progress event, which means we actually aborted it.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001814 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07001815 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001816 return;
1817 }
1818 }
1819
1820 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07001821 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001822}
1823
Jeff Brownb6997262010-10-08 22:31:17 -07001824void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1825 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001826#if DEBUG_DISPATCH_CYCLE
Jeff Brownb6997262010-10-08 22:31:17 -07001827 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001828 connection->getInputChannelName(), toString(broken));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001829#endif
1830
Jeff Brownb88102f2010-09-08 11:49:43 -07001831 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07001832 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001833
Jeff Brownb6997262010-10-08 22:31:17 -07001834 // The connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07001835 // Ignore already broken or zombie connections.
Jeff Brownb6997262010-10-08 22:31:17 -07001836 if (connection->status == Connection::STATUS_NORMAL) {
1837 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001838
Jeff Brownb6997262010-10-08 22:31:17 -07001839 // Notify other system components.
1840 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001841 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001842}
1843
Jeff Brown519e0242010-09-15 15:18:56 -07001844void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1845 while (! connection->outboundQueue.isEmpty()) {
1846 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1847 if (dispatchEntry->hasForegroundTarget()) {
1848 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001849 }
1850 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001851 }
1852
Jeff Brown519e0242010-09-15 15:18:56 -07001853 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07001854}
1855
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001856int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001857 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1858
1859 { // acquire lock
1860 AutoMutex _l(d->mLock);
1861
1862 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1863 if (connectionIndex < 0) {
1864 LOGE("Received spurious receive callback for unknown input channel. "
1865 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001866 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001867 }
1868
Jeff Brown7fbdc842010-06-17 20:52:56 -07001869 nsecs_t currentTime = now();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001870
1871 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001872 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001873 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1874 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brownb6997262010-10-08 22:31:17 -07001875 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001876 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001877 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001878 }
1879
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001880 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001881 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1882 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001883 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001884 }
1885
Jeff Brown3915bb82010-11-05 15:02:16 -07001886 bool handled = false;
Jeff Brown49ed71d2010-12-06 17:13:33 -08001887 status_t status = connection->inputPublisher.receiveFinishedSignal(&handled);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001888 if (status) {
1889 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1890 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001891 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001892 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001893 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001894 }
1895
Jeff Brown3915bb82010-11-05 15:02:16 -07001896 d->finishDispatchCycleLocked(currentTime, connection, handled);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001897 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001898 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001899 } // release lock
1900}
1901
Jeff Brownb6997262010-10-08 22:31:17 -07001902void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1903 InputState::CancelationOptions options, const char* reason) {
1904 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1905 synthesizeCancelationEventsForConnectionLocked(
1906 mConnectionsByReceiveFd.valueAt(i), options, reason);
1907 }
1908}
1909
1910void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1911 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1912 const char* reason) {
1913 ssize_t index = getConnectionIndexLocked(channel);
1914 if (index >= 0) {
1915 synthesizeCancelationEventsForConnectionLocked(
1916 mConnectionsByReceiveFd.valueAt(index), options, reason);
1917 }
1918}
1919
1920void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1921 const sp<Connection>& connection, InputState::CancelationOptions options,
1922 const char* reason) {
1923 nsecs_t currentTime = now();
1924
1925 mTempCancelationEvents.clear();
1926 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1927 mTempCancelationEvents, options);
1928
1929 if (! mTempCancelationEvents.isEmpty()
1930 && connection->status != Connection::STATUS_BROKEN) {
1931#if DEBUG_OUTBOUND_EVENT_DETAILS
1932 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1933 "with reality: %s, options=%d.",
1934 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1935#endif
1936 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1937 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1938 switch (cancelationEventEntry->type) {
1939 case EventEntry::TYPE_KEY:
1940 logOutboundKeyDetailsLocked("cancel - ",
1941 static_cast<KeyEntry*>(cancelationEventEntry));
1942 break;
1943 case EventEntry::TYPE_MOTION:
1944 logOutboundMotionDetailsLocked("cancel - ",
1945 static_cast<MotionEntry*>(cancelationEventEntry));
1946 break;
1947 }
1948
1949 int32_t xOffset, yOffset;
1950 const InputWindow* window = getWindowLocked(connection->inputChannel);
1951 if (window) {
1952 xOffset = -window->frameLeft;
1953 yOffset = -window->frameTop;
1954 } else {
1955 xOffset = 0;
1956 yOffset = 0;
1957 }
1958
1959 DispatchEntry* cancelationDispatchEntry =
1960 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1961 0, xOffset, yOffset);
1962 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1963
1964 mAllocator.releaseEventEntry(cancelationEventEntry);
1965 }
1966
1967 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1968 startDispatchCycleLocked(currentTime, connection);
1969 }
1970 }
1971}
1972
Jeff Brown01ce2e92010-09-26 22:20:12 -07001973InputDispatcher::MotionEntry*
1974InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1975 assert(pointerIds.value != 0);
1976
1977 uint32_t splitPointerIndexMap[MAX_POINTERS];
1978 int32_t splitPointerIds[MAX_POINTERS];
1979 PointerCoords splitPointerCoords[MAX_POINTERS];
1980
1981 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1982 uint32_t splitPointerCount = 0;
1983
1984 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1985 originalPointerIndex++) {
1986 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1987 if (pointerIds.hasBit(pointerId)) {
1988 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1989 splitPointerIds[splitPointerCount] = pointerId;
1990 splitPointerCoords[splitPointerCount] =
1991 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1992 splitPointerCount += 1;
1993 }
1994 }
1995 assert(splitPointerCount == pointerIds.count());
1996
1997 int32_t action = originalMotionEntry->action;
1998 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1999 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2000 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2001 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2002 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2003 if (pointerIds.hasBit(pointerId)) {
2004 if (pointerIds.count() == 1) {
2005 // The first/last pointer went down/up.
2006 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2007 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07002008 } else {
2009 // A secondary pointer went down/up.
2010 uint32_t splitPointerIndex = 0;
2011 while (pointerId != splitPointerIds[splitPointerIndex]) {
2012 splitPointerIndex += 1;
2013 }
2014 action = maskedAction | (splitPointerIndex
2015 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002016 }
2017 } else {
2018 // An unrelated pointer changed.
2019 action = AMOTION_EVENT_ACTION_MOVE;
2020 }
2021 }
2022
2023 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2024 originalMotionEntry->eventTime,
2025 originalMotionEntry->deviceId,
2026 originalMotionEntry->source,
2027 originalMotionEntry->policyFlags,
2028 action,
2029 originalMotionEntry->flags,
2030 originalMotionEntry->metaState,
2031 originalMotionEntry->edgeFlags,
2032 originalMotionEntry->xPrecision,
2033 originalMotionEntry->yPrecision,
2034 originalMotionEntry->downTime,
2035 splitPointerCount, splitPointerIds, splitPointerCoords);
2036
2037 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2038 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2039 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2040 splitPointerIndex++) {
2041 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2042 splitPointerCoords[splitPointerIndex] =
2043 originalMotionSample->pointerCoords[originalPointerIndex];
2044 }
2045
2046 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2047 splitPointerCoords);
2048 }
2049
2050 return splitMotionEntry;
2051}
2052
Jeff Brown9c3cda02010-06-15 01:31:58 -07002053void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002054#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07002055 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002056#endif
2057
Jeff Brownb88102f2010-09-08 11:49:43 -07002058 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002059 { // acquire lock
2060 AutoMutex _l(mLock);
2061
Jeff Brown7fbdc842010-06-17 20:52:56 -07002062 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07002063 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002064 } // release lock
2065
Jeff Brownb88102f2010-09-08 11:49:43 -07002066 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002067 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002068 }
2069}
2070
Jeff Brownc5ed5912010-07-14 18:48:53 -07002071void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002072 uint32_t policyFlags, int32_t action, int32_t flags,
2073 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2074#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002075 LOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002076 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07002077 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002078 keyCode, scanCode, metaState, downTime);
2079#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002080 if (! validateKeyEvent(action)) {
2081 return;
2082 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002083
Jeff Brown1f245102010-11-18 20:53:46 -08002084 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2085 policyFlags |= POLICY_FLAG_VIRTUAL;
2086 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2087 }
2088
Jeff Browne20c9e02010-10-11 14:20:19 -07002089 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown1f245102010-11-18 20:53:46 -08002090
2091 KeyEvent event;
2092 event.initialize(deviceId, source, action, flags, keyCode, scanCode,
2093 metaState, 0, downTime, eventTime);
2094
2095 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
2096
2097 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2098 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2099 }
Jeff Brownb6997262010-10-08 22:31:17 -07002100
Jeff Brownb88102f2010-09-08 11:49:43 -07002101 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002102 { // acquire lock
2103 AutoMutex _l(mLock);
2104
Jeff Brown7fbdc842010-06-17 20:52:56 -07002105 int32_t repeatCount = 0;
2106 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002107 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002108 metaState, repeatCount, downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002109
Jeff Brownb88102f2010-09-08 11:49:43 -07002110 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002111 } // release lock
2112
Jeff Brownb88102f2010-09-08 11:49:43 -07002113 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002114 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002115 }
2116}
2117
Jeff Brownc5ed5912010-07-14 18:48:53 -07002118void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002119 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002120 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2121 float xPrecision, float yPrecision, nsecs_t downTime) {
2122#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002123 LOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002124 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2125 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2126 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002127 xPrecision, yPrecision, downTime);
2128 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002129 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002130 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002131 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002132 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown8d608662010-08-30 03:02:23 -07002133 pointerCoords[i].pressure, pointerCoords[i].size,
2134 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2135 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2136 pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002137 }
2138#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002139 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2140 return;
2141 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002142
Jeff Browne20c9e02010-10-11 14:20:19 -07002143 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002144 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2145
Jeff Brownb88102f2010-09-08 11:49:43 -07002146 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002147 { // acquire lock
2148 AutoMutex _l(mLock);
2149
2150 // Attempt batching and streaming of move events.
Jeff Brownc5ed5912010-07-14 18:48:53 -07002151 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002152 // BATCHING CASE
2153 //
2154 // Try to append a move sample to the tail of the inbound queue for this device.
2155 // Give up if we encounter a non-move motion event for this device since that
2156 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002157 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2158 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002159 if (entry->type != EventEntry::TYPE_MOTION) {
2160 // Keep looking for motion events.
2161 continue;
2162 }
2163
2164 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2165 if (motionEntry->deviceId != deviceId) {
2166 // Keep looking for this device.
2167 continue;
2168 }
2169
Jeff Brownc5ed5912010-07-14 18:48:53 -07002170 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown7fbdc842010-06-17 20:52:56 -07002171 || motionEntry->pointerCount != pointerCount
2172 || motionEntry->isInjected()) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002173 // Last motion event in the queue for this device is not compatible for
2174 // appending new samples. Stop here.
2175 goto NoBatchingOrStreaming;
2176 }
2177
2178 // The last motion event is a move and is compatible for appending.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002179 // Do the batching magic.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002180 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002181#if DEBUG_BATCHING
2182 LOGD("Appended motion sample onto batch for most recent "
2183 "motion event for this device in the inbound queue.");
2184#endif
Jeff Brown9c3cda02010-06-15 01:31:58 -07002185 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002186 }
2187
2188 // STREAMING CASE
2189 //
2190 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002191 // Search the outbound queue for the current foreground targets to find a dispatched
2192 // motion event that is still in progress. If found, then, appen the new sample to
2193 // that event and push it out to all current targets. The logic in
2194 // prepareDispatchCycleLocked takes care of the case where some targets may
2195 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002196 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002197 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2198 const InputTarget& inputTarget = mCurrentInputTargets[i];
2199 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2200 // Skip non-foreground targets. We only want to stream if there is at
2201 // least one foreground target whose dispatch is still in progress.
2202 continue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002203 }
Jeff Brown519e0242010-09-15 15:18:56 -07002204
2205 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2206 if (connectionIndex < 0) {
2207 // Connection must no longer be valid.
2208 continue;
2209 }
2210
2211 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2212 if (connection->outboundQueue.isEmpty()) {
2213 // This foreground target has an empty outbound queue.
2214 continue;
2215 }
2216
2217 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2218 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002219 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2220 || dispatchEntry->isSplit()) {
2221 // No motion event is being dispatched, or it is being split across
2222 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002223 continue;
2224 }
2225
2226 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2227 dispatchEntry->eventEntry);
2228 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2229 || motionEntry->deviceId != deviceId
2230 || motionEntry->pointerCount != pointerCount
2231 || motionEntry->isInjected()) {
2232 // The motion event is not compatible with this move.
2233 continue;
2234 }
2235
2236 // Hurray! This foreground target is currently dispatching a move event
2237 // that we can stream onto. Append the motion sample and resume dispatch.
2238 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2239#if DEBUG_BATCHING
2240 LOGD("Appended motion sample onto batch for most recently dispatched "
2241 "motion event for this device in the outbound queues. "
2242 "Attempting to stream the motion sample.");
2243#endif
2244 nsecs_t currentTime = now();
2245 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2246 true /*resumeWithAppendedMotionSample*/);
2247
2248 runCommandsLockedInterruptible();
2249 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002250 }
2251 }
2252
2253NoBatchingOrStreaming:;
2254 }
2255
2256 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002257 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002258 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002259 xPrecision, yPrecision, downTime,
2260 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002261
Jeff Brownb88102f2010-09-08 11:49:43 -07002262 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002263 } // release lock
2264
Jeff Brownb88102f2010-09-08 11:49:43 -07002265 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002266 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002267 }
2268}
2269
Jeff Brownb6997262010-10-08 22:31:17 -07002270void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2271 uint32_t policyFlags) {
2272#if DEBUG_INBOUND_EVENT_DETAILS
2273 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2274 switchCode, switchValue, policyFlags);
2275#endif
2276
Jeff Browne20c9e02010-10-11 14:20:19 -07002277 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002278 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2279}
2280
Jeff Brown7fbdc842010-06-17 20:52:56 -07002281int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002282 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002283#if DEBUG_INBOUND_EVENT_DETAILS
2284 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002285 "syncMode=%d, timeoutMillis=%d",
2286 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002287#endif
2288
2289 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Browne20c9e02010-10-11 14:20:19 -07002290
2291 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2292 if (hasInjectionPermission(injectorPid, injectorUid)) {
2293 policyFlags |= POLICY_FLAG_TRUSTED;
2294 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002295
Jeff Brownb6997262010-10-08 22:31:17 -07002296 EventEntry* injectedEntry;
2297 switch (event->getType()) {
2298 case AINPUT_EVENT_TYPE_KEY: {
2299 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2300 int32_t action = keyEvent->getAction();
2301 if (! validateKeyEvent(action)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002302 return INPUT_EVENT_INJECTION_FAILED;
2303 }
2304
Jeff Brownb6997262010-10-08 22:31:17 -07002305 int32_t flags = keyEvent->getFlags();
Jeff Brown1f245102010-11-18 20:53:46 -08002306 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2307 policyFlags |= POLICY_FLAG_VIRTUAL;
2308 }
2309
2310 mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
2311
2312 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2313 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2314 }
Jeff Brown6ec402b2010-07-28 15:48:59 -07002315
Jeff Brownb6997262010-10-08 22:31:17 -07002316 mLock.lock();
Jeff Brown1f245102010-11-18 20:53:46 -08002317 injectedEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
2318 keyEvent->getDeviceId(), keyEvent->getSource(),
2319 policyFlags, action, flags,
2320 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
Jeff Brownb6997262010-10-08 22:31:17 -07002321 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2322 break;
2323 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002324
Jeff Brownb6997262010-10-08 22:31:17 -07002325 case AINPUT_EVENT_TYPE_MOTION: {
2326 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2327 int32_t action = motionEvent->getAction();
2328 size_t pointerCount = motionEvent->getPointerCount();
2329 const int32_t* pointerIds = motionEvent->getPointerIds();
2330 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2331 return INPUT_EVENT_INJECTION_FAILED;
2332 }
2333
2334 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Browne20c9e02010-10-11 14:20:19 -07002335 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002336
2337 mLock.lock();
2338 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2339 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2340 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2341 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2342 action, motionEvent->getFlags(),
2343 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2344 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2345 motionEvent->getDownTime(), uint32_t(pointerCount),
2346 pointerIds, samplePointerCoords);
2347 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2348 sampleEventTimes += 1;
2349 samplePointerCoords += pointerCount;
2350 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2351 }
2352 injectedEntry = motionEntry;
2353 break;
2354 }
2355
2356 default:
2357 LOGW("Cannot inject event of type %d", event->getType());
2358 return INPUT_EVENT_INJECTION_FAILED;
2359 }
2360
2361 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2362 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2363 injectionState->injectionIsAsync = true;
2364 }
2365
2366 injectionState->refCount += 1;
2367 injectedEntry->injectionState = injectionState;
2368
2369 bool needWake = enqueueInboundEventLocked(injectedEntry);
2370 mLock.unlock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002371
Jeff Brownb88102f2010-09-08 11:49:43 -07002372 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002373 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002374 }
2375
2376 int32_t injectionResult;
2377 { // acquire lock
2378 AutoMutex _l(mLock);
2379
Jeff Brown6ec402b2010-07-28 15:48:59 -07002380 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2381 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2382 } else {
2383 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002384 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002385 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2386 break;
2387 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002388
Jeff Brown7fbdc842010-06-17 20:52:56 -07002389 nsecs_t remainingTimeout = endTime - now();
2390 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002391#if DEBUG_INJECTION
2392 LOGD("injectInputEvent - Timed out waiting for injection result "
2393 "to become available.");
2394#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002395 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2396 break;
2397 }
2398
Jeff Brown6ec402b2010-07-28 15:48:59 -07002399 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2400 }
2401
2402 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2403 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002404 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002405#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002406 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002407 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002408#endif
2409 nsecs_t remainingTimeout = endTime - now();
2410 if (remainingTimeout <= 0) {
2411#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002412 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002413 "dispatches to finish.");
2414#endif
2415 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2416 break;
2417 }
2418
2419 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2420 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002421 }
2422 }
2423
Jeff Brown01ce2e92010-09-26 22:20:12 -07002424 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002425 } // release lock
2426
Jeff Brown6ec402b2010-07-28 15:48:59 -07002427#if DEBUG_INJECTION
2428 LOGD("injectInputEvent - Finished with result %d. "
2429 "injectorPid=%d, injectorUid=%d",
2430 injectionResult, injectorPid, injectorUid);
2431#endif
2432
Jeff Brown7fbdc842010-06-17 20:52:56 -07002433 return injectionResult;
2434}
2435
Jeff Brownb6997262010-10-08 22:31:17 -07002436bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2437 return injectorUid == 0
2438 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2439}
2440
Jeff Brown7fbdc842010-06-17 20:52:56 -07002441void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002442 InjectionState* injectionState = entry->injectionState;
2443 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002444#if DEBUG_INJECTION
2445 LOGD("Setting input event injection result to %d. "
2446 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002447 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002448#endif
2449
Jeff Brown01ce2e92010-09-26 22:20:12 -07002450 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002451 // Log the outcome since the injector did not wait for the injection result.
2452 switch (injectionResult) {
2453 case INPUT_EVENT_INJECTION_SUCCEEDED:
2454 LOGV("Asynchronous input event injection succeeded.");
2455 break;
2456 case INPUT_EVENT_INJECTION_FAILED:
2457 LOGW("Asynchronous input event injection failed.");
2458 break;
2459 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2460 LOGW("Asynchronous input event injection permission denied.");
2461 break;
2462 case INPUT_EVENT_INJECTION_TIMED_OUT:
2463 LOGW("Asynchronous input event injection timed out.");
2464 break;
2465 }
2466 }
2467
Jeff Brown01ce2e92010-09-26 22:20:12 -07002468 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002469 mInjectionResultAvailableCondition.broadcast();
2470 }
2471}
2472
Jeff Brown01ce2e92010-09-26 22:20:12 -07002473void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2474 InjectionState* injectionState = entry->injectionState;
2475 if (injectionState) {
2476 injectionState->pendingForegroundDispatches += 1;
2477 }
2478}
2479
Jeff Brown519e0242010-09-15 15:18:56 -07002480void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002481 InjectionState* injectionState = entry->injectionState;
2482 if (injectionState) {
2483 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002484
Jeff Brown01ce2e92010-09-26 22:20:12 -07002485 if (injectionState->pendingForegroundDispatches == 0) {
2486 mInjectionSyncFinishedCondition.broadcast();
2487 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002488 }
2489}
2490
Jeff Brown01ce2e92010-09-26 22:20:12 -07002491const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2492 for (size_t i = 0; i < mWindows.size(); i++) {
2493 const InputWindow* window = & mWindows[i];
2494 if (window->inputChannel == inputChannel) {
2495 return window;
2496 }
2497 }
2498 return NULL;
2499}
2500
Jeff Brownb88102f2010-09-08 11:49:43 -07002501void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2502#if DEBUG_FOCUS
2503 LOGD("setInputWindows");
2504#endif
2505 { // acquire lock
2506 AutoMutex _l(mLock);
2507
Jeff Brown01ce2e92010-09-26 22:20:12 -07002508 // Clear old window pointers.
Jeff Brownb6997262010-10-08 22:31:17 -07002509 sp<InputChannel> oldFocusedWindowChannel;
2510 if (mFocusedWindow) {
2511 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2512 mFocusedWindow = NULL;
2513 }
2514
Jeff Brownb88102f2010-09-08 11:49:43 -07002515 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002516
2517 // Loop over new windows and rebuild the necessary window pointers for
2518 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002519 mWindows.appendVector(inputWindows);
2520
2521 size_t numWindows = mWindows.size();
2522 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002523 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002524 if (window->hasFocus) {
2525 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002526 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002527 }
2528 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002529
Jeff Brownb6997262010-10-08 22:31:17 -07002530 if (oldFocusedWindowChannel != NULL) {
2531 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2532#if DEBUG_FOCUS
2533 LOGD("Focus left window: %s",
2534 oldFocusedWindowChannel->getName().string());
2535#endif
2536 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2537 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2538 oldFocusedWindowChannel.clear();
2539 }
2540 }
2541 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2542#if DEBUG_FOCUS
2543 LOGD("Focus entered window: %s",
2544 mFocusedWindow->inputChannel->getName().string());
2545#endif
2546 }
2547
Jeff Brown01ce2e92010-09-26 22:20:12 -07002548 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2549 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2550 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2551 if (window) {
2552 touchedWindow.window = window;
2553 i += 1;
2554 } else {
Jeff Brownb6997262010-10-08 22:31:17 -07002555#if DEBUG_FOCUS
2556 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2557#endif
Jeff Brownb6997262010-10-08 22:31:17 -07002558 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2559 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownaf48cae2010-10-15 16:20:51 -07002560 mTouchState.windows.removeAt(i);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002561 }
2562 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002563
Jeff Brownb88102f2010-09-08 11:49:43 -07002564#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002565 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002566#endif
2567 } // release lock
2568
2569 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002570 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002571}
2572
2573void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2574#if DEBUG_FOCUS
2575 LOGD("setFocusedApplication");
2576#endif
2577 { // acquire lock
2578 AutoMutex _l(mLock);
2579
2580 releaseFocusedApplicationLocked();
2581
2582 if (inputApplication) {
2583 mFocusedApplicationStorage = *inputApplication;
2584 mFocusedApplication = & mFocusedApplicationStorage;
2585 }
2586
2587#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002588 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002589#endif
2590 } // release lock
2591
2592 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002593 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002594}
2595
2596void InputDispatcher::releaseFocusedApplicationLocked() {
2597 if (mFocusedApplication) {
2598 mFocusedApplication = NULL;
2599 mFocusedApplicationStorage.handle.clear();
2600 }
2601}
2602
2603void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2604#if DEBUG_FOCUS
2605 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2606#endif
2607
2608 bool changed;
2609 { // acquire lock
2610 AutoMutex _l(mLock);
2611
2612 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brown120a4592010-10-27 18:43:51 -07002613 if (mDispatchFrozen && !frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002614 resetANRTimeoutsLocked();
2615 }
2616
Jeff Brown120a4592010-10-27 18:43:51 -07002617 if (mDispatchEnabled && !enabled) {
2618 resetAndDropEverythingLocked("dispatcher is being disabled");
2619 }
2620
Jeff Brownb88102f2010-09-08 11:49:43 -07002621 mDispatchEnabled = enabled;
2622 mDispatchFrozen = frozen;
2623 changed = true;
2624 } else {
2625 changed = false;
2626 }
2627
2628#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002629 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002630#endif
2631 } // release lock
2632
2633 if (changed) {
2634 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002635 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002636 }
2637}
2638
Jeff Browne6504122010-09-27 14:52:15 -07002639bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2640 const sp<InputChannel>& toChannel) {
2641#if DEBUG_FOCUS
2642 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2643 fromChannel->getName().string(), toChannel->getName().string());
2644#endif
2645 { // acquire lock
2646 AutoMutex _l(mLock);
2647
2648 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2649 const InputWindow* toWindow = getWindowLocked(toChannel);
2650 if (! fromWindow || ! toWindow) {
2651#if DEBUG_FOCUS
2652 LOGD("Cannot transfer focus because from or to window not found.");
2653#endif
2654 return false;
2655 }
2656 if (fromWindow == toWindow) {
2657#if DEBUG_FOCUS
2658 LOGD("Trivial transfer to same window.");
2659#endif
2660 return true;
2661 }
2662
2663 bool found = false;
2664 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2665 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2666 if (touchedWindow.window == fromWindow) {
2667 int32_t oldTargetFlags = touchedWindow.targetFlags;
2668 BitSet32 pointerIds = touchedWindow.pointerIds;
2669
2670 mTouchState.windows.removeAt(i);
2671
Jeff Brown46e75292010-11-10 16:53:45 -08002672 int32_t newTargetFlags = oldTargetFlags
2673 & (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT);
Jeff Browne6504122010-09-27 14:52:15 -07002674 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2675
2676 found = true;
2677 break;
2678 }
2679 }
2680
2681 if (! found) {
2682#if DEBUG_FOCUS
2683 LOGD("Focus transfer failed because from window did not have focus.");
2684#endif
2685 return false;
2686 }
2687
Jeff Brown9c9f1a32010-10-11 18:32:20 -07002688 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2689 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2690 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2691 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2692 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2693
2694 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2695 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2696 InputState::CANCEL_POINTER_EVENTS,
2697 "transferring touch focus from this window to another window");
2698 }
2699
Jeff Browne6504122010-09-27 14:52:15 -07002700#if DEBUG_FOCUS
2701 logDispatchStateLocked();
2702#endif
2703 } // release lock
2704
2705 // Wake up poll loop since it may need to make new input dispatching choices.
2706 mLooper->wake();
2707 return true;
2708}
2709
Jeff Brown120a4592010-10-27 18:43:51 -07002710void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2711#if DEBUG_FOCUS
2712 LOGD("Resetting and dropping all events (%s).", reason);
2713#endif
2714
2715 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2716
2717 resetKeyRepeatLocked();
2718 releasePendingEventLocked();
2719 drainInboundQueueLocked();
2720 resetTargetsLocked();
2721
2722 mTouchState.reset();
2723}
2724
Jeff Brownb88102f2010-09-08 11:49:43 -07002725void InputDispatcher::logDispatchStateLocked() {
2726 String8 dump;
2727 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002728
2729 char* text = dump.lockBuffer(dump.size());
2730 char* start = text;
2731 while (*start != '\0') {
2732 char* end = strchr(start, '\n');
2733 if (*end == '\n') {
2734 *(end++) = '\0';
2735 }
2736 LOGD("%s", start);
2737 start = end;
2738 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002739}
2740
2741void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002742 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2743 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07002744
2745 if (mFocusedApplication) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002746 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002747 mFocusedApplication->name.string(),
2748 mFocusedApplication->dispatchingTimeout / 1000000.0);
2749 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002750 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002751 }
Jeff Brownf2f487182010-10-01 17:46:21 -07002752 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002753 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f487182010-10-01 17:46:21 -07002754
2755 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2756 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2757 if (!mTouchState.windows.isEmpty()) {
2758 dump.append(INDENT "TouchedWindows:\n");
2759 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2760 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2761 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2762 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2763 touchedWindow.targetFlags);
2764 }
2765 } else {
2766 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002767 }
2768
Jeff Brownf2f487182010-10-01 17:46:21 -07002769 if (!mWindows.isEmpty()) {
2770 dump.append(INDENT "Windows:\n");
2771 for (size_t i = 0; i < mWindows.size(); i++) {
2772 const InputWindow& window = mWindows[i];
2773 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2774 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2775 "frame=[%d,%d][%d,%d], "
2776 "visibleFrame=[%d,%d][%d,%d], "
2777 "touchableArea=[%d,%d][%d,%d], "
2778 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2779 i, window.name.string(),
2780 toString(window.paused),
2781 toString(window.hasFocus),
2782 toString(window.hasWallpaper),
2783 toString(window.visible),
2784 toString(window.canReceiveKeys),
2785 window.layoutParamsFlags, window.layoutParamsType,
2786 window.layer,
2787 window.frameLeft, window.frameTop,
2788 window.frameRight, window.frameBottom,
2789 window.visibleFrameLeft, window.visibleFrameTop,
2790 window.visibleFrameRight, window.visibleFrameBottom,
2791 window.touchableAreaLeft, window.touchableAreaTop,
2792 window.touchableAreaRight, window.touchableAreaBottom,
2793 window.ownerPid, window.ownerUid,
2794 window.dispatchingTimeout / 1000000.0);
2795 }
2796 } else {
2797 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002798 }
2799
Jeff Brownf2f487182010-10-01 17:46:21 -07002800 if (!mMonitoringChannels.isEmpty()) {
2801 dump.append(INDENT "MonitoringChannels:\n");
2802 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2803 const sp<InputChannel>& channel = mMonitoringChannels[i];
2804 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2805 }
2806 } else {
2807 dump.append(INDENT "MonitoringChannels: <none>\n");
2808 }
Jeff Brown519e0242010-09-15 15:18:56 -07002809
Jeff Brownf2f487182010-10-01 17:46:21 -07002810 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2811
2812 if (!mActiveConnections.isEmpty()) {
2813 dump.append(INDENT "ActiveConnections:\n");
2814 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2815 const Connection* connection = mActiveConnections[i];
Jeff Brown76860e32010-10-25 17:37:46 -07002816 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brownb6997262010-10-08 22:31:17 -07002817 "inputState.isNeutral=%s\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07002818 i, connection->getInputChannelName(), connection->getStatusLabel(),
2819 connection->outboundQueue.count(),
Jeff Brownb6997262010-10-08 22:31:17 -07002820 toString(connection->inputState.isNeutral()));
Jeff Brownf2f487182010-10-01 17:46:21 -07002821 }
2822 } else {
2823 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002824 }
2825
2826 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002827 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002828 (mAppSwitchDueTime - now()) / 1000000.0);
2829 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002830 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002831 }
2832}
2833
2834status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002835#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07002836 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2837 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07002838#endif
2839
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002840 { // acquire lock
2841 AutoMutex _l(mLock);
2842
Jeff Brown519e0242010-09-15 15:18:56 -07002843 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002844 LOGW("Attempted to register already registered input channel '%s'",
2845 inputChannel->getName().string());
2846 return BAD_VALUE;
2847 }
2848
2849 sp<Connection> connection = new Connection(inputChannel);
2850 status_t status = connection->initialize();
2851 if (status) {
2852 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2853 inputChannel->getName().string(), status);
2854 return status;
2855 }
2856
Jeff Brown2cbecea2010-08-17 15:59:26 -07002857 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002858 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002859
Jeff Brownb88102f2010-09-08 11:49:43 -07002860 if (monitor) {
2861 mMonitoringChannels.push(inputChannel);
2862 }
2863
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002864 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07002865
Jeff Brown9c3cda02010-06-15 01:31:58 -07002866 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002867 } // release lock
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002868 return OK;
2869}
2870
2871status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002872#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07002873 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07002874#endif
2875
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002876 { // acquire lock
2877 AutoMutex _l(mLock);
2878
Jeff Brown519e0242010-09-15 15:18:56 -07002879 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002880 if (connectionIndex < 0) {
2881 LOGW("Attempted to unregister already unregistered input channel '%s'",
2882 inputChannel->getName().string());
2883 return BAD_VALUE;
2884 }
2885
2886 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2887 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2888
2889 connection->status = Connection::STATUS_ZOMBIE;
2890
Jeff Brownb88102f2010-09-08 11:49:43 -07002891 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2892 if (mMonitoringChannels[i] == inputChannel) {
2893 mMonitoringChannels.removeAt(i);
2894 break;
2895 }
2896 }
2897
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002898 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07002899
Jeff Brown7fbdc842010-06-17 20:52:56 -07002900 nsecs_t currentTime = now();
Jeff Brownb6997262010-10-08 22:31:17 -07002901 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002902
2903 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002904 } // release lock
2905
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002906 // Wake the poll loop because removing the connection may have changed the current
2907 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002908 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002909 return OK;
2910}
2911
Jeff Brown519e0242010-09-15 15:18:56 -07002912ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07002913 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2914 if (connectionIndex >= 0) {
2915 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2916 if (connection->inputChannel.get() == inputChannel.get()) {
2917 return connectionIndex;
2918 }
2919 }
2920
2921 return -1;
2922}
2923
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002924void InputDispatcher::activateConnectionLocked(Connection* connection) {
2925 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2926 if (mActiveConnections.itemAt(i) == connection) {
2927 return;
2928 }
2929 }
2930 mActiveConnections.add(connection);
2931}
2932
2933void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2934 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2935 if (mActiveConnections.itemAt(i) == connection) {
2936 mActiveConnections.removeAt(i);
2937 return;
2938 }
2939 }
2940}
2941
Jeff Brown9c3cda02010-06-15 01:31:58 -07002942void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002943 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002944}
2945
Jeff Brown9c3cda02010-06-15 01:31:58 -07002946void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown3915bb82010-11-05 15:02:16 -07002947 nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
2948 CommandEntry* commandEntry = postCommandLocked(
2949 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
2950 commandEntry->connection = connection;
2951 commandEntry->handled = handled;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002952}
2953
Jeff Brown9c3cda02010-06-15 01:31:58 -07002954void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002955 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002956 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2957 connection->getInputChannelName());
2958
Jeff Brown9c3cda02010-06-15 01:31:58 -07002959 CommandEntry* commandEntry = postCommandLocked(
2960 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002961 commandEntry->connection = connection;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002962}
2963
Jeff Brown519e0242010-09-15 15:18:56 -07002964void InputDispatcher::onANRLocked(
2965 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2966 nsecs_t eventTime, nsecs_t waitStartTime) {
2967 LOGI("Application is not responding: %s. "
2968 "%01.1fms since event, %01.1fms since wait started",
2969 getApplicationWindowLabelLocked(application, window).string(),
2970 (currentTime - eventTime) / 1000000.0,
2971 (currentTime - waitStartTime) / 1000000.0);
2972
2973 CommandEntry* commandEntry = postCommandLocked(
2974 & InputDispatcher::doNotifyANRLockedInterruptible);
2975 if (application) {
2976 commandEntry->inputApplicationHandle = application->handle;
2977 }
2978 if (window) {
2979 commandEntry->inputChannel = window->inputChannel;
2980 }
2981}
2982
Jeff Brownb88102f2010-09-08 11:49:43 -07002983void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2984 CommandEntry* commandEntry) {
2985 mLock.unlock();
2986
2987 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2988
2989 mLock.lock();
2990}
2991
Jeff Brown9c3cda02010-06-15 01:31:58 -07002992void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2993 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002994 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07002995
Jeff Brown7fbdc842010-06-17 20:52:56 -07002996 if (connection->status != Connection::STATUS_ZOMBIE) {
2997 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002998
Jeff Brown7fbdc842010-06-17 20:52:56 -07002999 mPolicy->notifyInputChannelBroken(connection->inputChannel);
3000
3001 mLock.lock();
3002 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07003003}
3004
Jeff Brown519e0242010-09-15 15:18:56 -07003005void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07003006 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07003007 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003008
Jeff Brown519e0242010-09-15 15:18:56 -07003009 nsecs_t newTimeout = mPolicy->notifyANR(
3010 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003011
Jeff Brown519e0242010-09-15 15:18:56 -07003012 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07003013
Jeff Brown519e0242010-09-15 15:18:56 -07003014 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003015}
3016
Jeff Brownb88102f2010-09-08 11:49:43 -07003017void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3018 CommandEntry* commandEntry) {
3019 KeyEntry* entry = commandEntry->keyEntry;
Jeff Brown1f245102010-11-18 20:53:46 -08003020
3021 KeyEvent event;
3022 initializeKeyEvent(&event, entry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003023
3024 mLock.unlock();
3025
3026 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
Jeff Brown1f245102010-11-18 20:53:46 -08003027 &event, entry->policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -07003028
3029 mLock.lock();
3030
3031 entry->interceptKeyResult = consumed
3032 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
3033 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3034 mAllocator.releaseKeyEntry(entry);
3035}
3036
Jeff Brown3915bb82010-11-05 15:02:16 -07003037void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3038 CommandEntry* commandEntry) {
3039 sp<Connection> connection = commandEntry->connection;
3040 bool handled = commandEntry->handled;
3041
Jeff Brown49ed71d2010-12-06 17:13:33 -08003042 if (!connection->outboundQueue.isEmpty()) {
Jeff Brown3915bb82010-11-05 15:02:16 -07003043 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
3044 if (dispatchEntry->inProgress
3045 && dispatchEntry->hasForegroundTarget()
3046 && dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3047 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003048 if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
3049 if (handled) {
3050 // If the application handled a non-fallback key, then immediately
3051 // cancel all fallback keys previously dispatched to the application.
3052 // This behavior will prevent chording with fallback keys (so they cannot
3053 // be used as modifiers) but it will ensure that fallback keys do not
3054 // get stuck. This takes care of the case where the application does not handle
3055 // the original DOWN so we generate a fallback DOWN but it does handle
3056 // the original UP in which case we would not generate the fallback UP.
3057 synthesizeCancelationEventsForConnectionLocked(connection,
3058 InputState::CANCEL_FALLBACK_EVENTS,
3059 "Application handled a non-fallback event.");
3060 } else {
3061 // If the application did not handle a non-fallback key, then ask
3062 // the policy what to do with it. We might generate a fallback key
3063 // event here.
3064 KeyEvent event;
3065 initializeKeyEvent(&event, keyEntry);
Jeff Brown3915bb82010-11-05 15:02:16 -07003066
Jeff Brown49ed71d2010-12-06 17:13:33 -08003067 mLock.unlock();
Jeff Brown3915bb82010-11-05 15:02:16 -07003068
Jeff Brown49ed71d2010-12-06 17:13:33 -08003069 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel,
3070 &event, keyEntry->policyFlags, &event);
Jeff Brown3915bb82010-11-05 15:02:16 -07003071
Jeff Brown49ed71d2010-12-06 17:13:33 -08003072 mLock.lock();
3073
3074 if (fallback) {
3075 // Restart the dispatch cycle using the fallback key.
3076 keyEntry->eventTime = event.getEventTime();
3077 keyEntry->deviceId = event.getDeviceId();
3078 keyEntry->source = event.getSource();
3079 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
3080 keyEntry->keyCode = event.getKeyCode();
3081 keyEntry->scanCode = event.getScanCode();
3082 keyEntry->metaState = event.getMetaState();
3083 keyEntry->repeatCount = event.getRepeatCount();
3084 keyEntry->downTime = event.getDownTime();
3085 keyEntry->syntheticRepeat = false;
3086
3087 dispatchEntry->inProgress = false;
3088 startDispatchCycleLocked(now(), connection);
3089 return;
3090 }
3091 }
3092 }
Jeff Brown3915bb82010-11-05 15:02:16 -07003093 }
3094 }
3095
3096 startNextDispatchCycleLocked(now(), connection);
3097}
3098
Jeff Brownb88102f2010-09-08 11:49:43 -07003099void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3100 mLock.unlock();
3101
Jeff Brown01ce2e92010-09-26 22:20:12 -07003102 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07003103
3104 mLock.lock();
3105}
3106
Jeff Brown3915bb82010-11-05 15:02:16 -07003107void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
3108 event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3109 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3110 entry->downTime, entry->eventTime);
3111}
3112
Jeff Brown519e0242010-09-15 15:18:56 -07003113void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3114 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3115 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07003116}
3117
3118void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003119 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003120 dumpDispatchStateLocked(dump);
3121}
3122
Jeff Brown9c3cda02010-06-15 01:31:58 -07003123
Jeff Brown519e0242010-09-15 15:18:56 -07003124// --- InputDispatcher::Queue ---
3125
3126template <typename T>
3127uint32_t InputDispatcher::Queue<T>::count() const {
3128 uint32_t result = 0;
3129 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3130 result += 1;
3131 }
3132 return result;
3133}
3134
3135
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003136// --- InputDispatcher::Allocator ---
3137
3138InputDispatcher::Allocator::Allocator() {
3139}
3140
Jeff Brown01ce2e92010-09-26 22:20:12 -07003141InputDispatcher::InjectionState*
3142InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3143 InjectionState* injectionState = mInjectionStatePool.alloc();
3144 injectionState->refCount = 1;
3145 injectionState->injectorPid = injectorPid;
3146 injectionState->injectorUid = injectorUid;
3147 injectionState->injectionIsAsync = false;
3148 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3149 injectionState->pendingForegroundDispatches = 0;
3150 return injectionState;
3151}
3152
Jeff Brown7fbdc842010-06-17 20:52:56 -07003153void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brownb6997262010-10-08 22:31:17 -07003154 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003155 entry->type = type;
3156 entry->refCount = 1;
3157 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07003158 entry->eventTime = eventTime;
Jeff Brownb6997262010-10-08 22:31:17 -07003159 entry->policyFlags = policyFlags;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003160 entry->injectionState = NULL;
3161}
3162
3163void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3164 if (entry->injectionState) {
3165 releaseInjectionState(entry->injectionState);
3166 entry->injectionState = NULL;
3167 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07003168}
3169
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003170InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07003171InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003172 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003173 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003174 return entry;
3175}
3176
Jeff Brown7fbdc842010-06-17 20:52:56 -07003177InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07003178 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003179 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3180 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003181 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003182 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003183
3184 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003185 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003186 entry->action = action;
3187 entry->flags = flags;
3188 entry->keyCode = keyCode;
3189 entry->scanCode = scanCode;
3190 entry->metaState = metaState;
3191 entry->repeatCount = repeatCount;
3192 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003193 entry->syntheticRepeat = false;
3194 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003195 return entry;
3196}
3197
Jeff Brown7fbdc842010-06-17 20:52:56 -07003198InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07003199 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003200 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3201 nsecs_t downTime, uint32_t pointerCount,
3202 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003203 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003204 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003205
3206 entry->eventTime = eventTime;
3207 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003208 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003209 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07003210 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003211 entry->metaState = metaState;
3212 entry->edgeFlags = edgeFlags;
3213 entry->xPrecision = xPrecision;
3214 entry->yPrecision = yPrecision;
3215 entry->downTime = downTime;
3216 entry->pointerCount = pointerCount;
3217 entry->firstSample.eventTime = eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003218 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003219 entry->lastSample = & entry->firstSample;
3220 for (uint32_t i = 0; i < pointerCount; i++) {
3221 entry->pointerIds[i] = pointerIds[i];
3222 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3223 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003224 return entry;
3225}
3226
3227InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07003228 EventEntry* eventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07003229 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003230 DispatchEntry* entry = mDispatchEntryPool.alloc();
3231 entry->eventEntry = eventEntry;
3232 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07003233 entry->targetFlags = targetFlags;
3234 entry->xOffset = xOffset;
3235 entry->yOffset = yOffset;
Jeff Brownb88102f2010-09-08 11:49:43 -07003236 entry->inProgress = false;
3237 entry->headMotionSample = NULL;
3238 entry->tailMotionSample = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003239 return entry;
3240}
3241
Jeff Brown9c3cda02010-06-15 01:31:58 -07003242InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3243 CommandEntry* entry = mCommandEntryPool.alloc();
3244 entry->command = command;
3245 return entry;
3246}
3247
Jeff Brown01ce2e92010-09-26 22:20:12 -07003248void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3249 injectionState->refCount -= 1;
3250 if (injectionState->refCount == 0) {
3251 mInjectionStatePool.free(injectionState);
3252 } else {
3253 assert(injectionState->refCount > 0);
3254 }
3255}
3256
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003257void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3258 switch (entry->type) {
3259 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3260 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3261 break;
3262 case EventEntry::TYPE_KEY:
3263 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3264 break;
3265 case EventEntry::TYPE_MOTION:
3266 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3267 break;
3268 default:
3269 assert(false);
3270 break;
3271 }
3272}
3273
3274void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3275 ConfigurationChangedEntry* entry) {
3276 entry->refCount -= 1;
3277 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003278 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003279 mConfigurationChangeEntryPool.free(entry);
3280 } else {
3281 assert(entry->refCount > 0);
3282 }
3283}
3284
3285void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3286 entry->refCount -= 1;
3287 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003288 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003289 mKeyEntryPool.free(entry);
3290 } else {
3291 assert(entry->refCount > 0);
3292 }
3293}
3294
3295void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3296 entry->refCount -= 1;
3297 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003298 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003299 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3300 MotionSample* next = sample->next;
3301 mMotionSamplePool.free(sample);
3302 sample = next;
3303 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003304 mMotionEntryPool.free(entry);
3305 } else {
3306 assert(entry->refCount > 0);
3307 }
3308}
3309
3310void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3311 releaseEventEntry(entry->eventEntry);
3312 mDispatchEntryPool.free(entry);
3313}
3314
Jeff Brown9c3cda02010-06-15 01:31:58 -07003315void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3316 mCommandEntryPool.free(entry);
3317}
3318
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003319void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003320 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003321 MotionSample* sample = mMotionSamplePool.alloc();
3322 sample->eventTime = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003323 uint32_t pointerCount = motionEntry->pointerCount;
3324 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003325 sample->pointerCoords[i] = pointerCoords[i];
3326 }
3327
3328 sample->next = NULL;
3329 motionEntry->lastSample->next = sample;
3330 motionEntry->lastSample = sample;
3331}
3332
Jeff Brown01ce2e92010-09-26 22:20:12 -07003333void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3334 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003335
Jeff Brown01ce2e92010-09-26 22:20:12 -07003336 keyEntry->dispatchInProgress = false;
3337 keyEntry->syntheticRepeat = false;
3338 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003339}
3340
3341
Jeff Brownae9fc032010-08-18 15:51:08 -07003342// --- InputDispatcher::MotionEntry ---
3343
3344uint32_t InputDispatcher::MotionEntry::countSamples() const {
3345 uint32_t count = 1;
3346 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3347 count += 1;
3348 }
3349 return count;
3350}
3351
Jeff Brownb88102f2010-09-08 11:49:43 -07003352
3353// --- InputDispatcher::InputState ---
3354
Jeff Brownb6997262010-10-08 22:31:17 -07003355InputDispatcher::InputState::InputState() {
Jeff Brownb88102f2010-09-08 11:49:43 -07003356}
3357
3358InputDispatcher::InputState::~InputState() {
3359}
3360
3361bool InputDispatcher::InputState::isNeutral() const {
3362 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3363}
3364
Jeff Brownb88102f2010-09-08 11:49:43 -07003365InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3366 const EventEntry* entry) {
3367 switch (entry->type) {
3368 case EventEntry::TYPE_KEY:
3369 return trackKey(static_cast<const KeyEntry*>(entry));
3370
3371 case EventEntry::TYPE_MOTION:
3372 return trackMotion(static_cast<const MotionEntry*>(entry));
3373
3374 default:
3375 return CONSISTENT;
3376 }
3377}
3378
3379InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3380 const KeyEntry* entry) {
3381 int32_t action = entry->action;
3382 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3383 KeyMemento& memento = mKeyMementos.editItemAt(i);
3384 if (memento.deviceId == entry->deviceId
3385 && memento.source == entry->source
3386 && memento.keyCode == entry->keyCode
3387 && memento.scanCode == entry->scanCode) {
3388 switch (action) {
3389 case AKEY_EVENT_ACTION_UP:
3390 mKeyMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003391 return CONSISTENT;
3392
3393 case AKEY_EVENT_ACTION_DOWN:
3394 return TOLERABLE;
3395
3396 default:
3397 return BROKEN;
3398 }
3399 }
3400 }
3401
3402 switch (action) {
3403 case AKEY_EVENT_ACTION_DOWN: {
3404 mKeyMementos.push();
3405 KeyMemento& memento = mKeyMementos.editTop();
3406 memento.deviceId = entry->deviceId;
3407 memento.source = entry->source;
3408 memento.keyCode = entry->keyCode;
3409 memento.scanCode = entry->scanCode;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003410 memento.flags = entry->flags;
Jeff Brownb88102f2010-09-08 11:49:43 -07003411 memento.downTime = entry->downTime;
3412 return CONSISTENT;
3413 }
3414
3415 default:
3416 return BROKEN;
3417 }
3418}
3419
3420InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3421 const MotionEntry* entry) {
3422 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3423 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3424 MotionMemento& memento = mMotionMementos.editItemAt(i);
3425 if (memento.deviceId == entry->deviceId
3426 && memento.source == entry->source) {
3427 switch (action) {
3428 case AMOTION_EVENT_ACTION_UP:
3429 case AMOTION_EVENT_ACTION_CANCEL:
3430 mMotionMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003431 return CONSISTENT;
3432
3433 case AMOTION_EVENT_ACTION_DOWN:
3434 return TOLERABLE;
3435
3436 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3437 if (entry->pointerCount == memento.pointerCount + 1) {
3438 memento.setPointers(entry);
3439 return CONSISTENT;
3440 }
3441 return BROKEN;
3442
3443 case AMOTION_EVENT_ACTION_POINTER_UP:
3444 if (entry->pointerCount == memento.pointerCount - 1) {
3445 memento.setPointers(entry);
3446 return CONSISTENT;
3447 }
3448 return BROKEN;
3449
3450 case AMOTION_EVENT_ACTION_MOVE:
3451 if (entry->pointerCount == memento.pointerCount) {
3452 return CONSISTENT;
3453 }
3454 return BROKEN;
3455
3456 default:
3457 return BROKEN;
3458 }
3459 }
3460 }
3461
3462 switch (action) {
3463 case AMOTION_EVENT_ACTION_DOWN: {
3464 mMotionMementos.push();
3465 MotionMemento& memento = mMotionMementos.editTop();
3466 memento.deviceId = entry->deviceId;
3467 memento.source = entry->source;
3468 memento.xPrecision = entry->xPrecision;
3469 memento.yPrecision = entry->yPrecision;
3470 memento.downTime = entry->downTime;
3471 memento.setPointers(entry);
3472 return CONSISTENT;
3473 }
3474
3475 default:
3476 return BROKEN;
3477 }
3478}
3479
3480void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3481 pointerCount = entry->pointerCount;
3482 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3483 pointerIds[i] = entry->pointerIds[i];
3484 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3485 }
3486}
3487
Jeff Brownb6997262010-10-08 22:31:17 -07003488void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3489 Allocator* allocator, Vector<EventEntry*>& outEvents,
3490 CancelationOptions options) {
3491 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003492 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003493 if (shouldCancelKey(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003494 outEvents.push(allocator->obtainKeyEntry(currentTime,
3495 memento.deviceId, memento.source, 0,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003496 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
Jeff Brownb6997262010-10-08 22:31:17 -07003497 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3498 mKeyMementos.removeAt(i);
3499 } else {
3500 i += 1;
3501 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003502 }
3503
Jeff Browna1160a72010-10-11 18:22:53 -07003504 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003505 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003506 if (shouldCancelMotion(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003507 outEvents.push(allocator->obtainMotionEntry(currentTime,
3508 memento.deviceId, memento.source, 0,
3509 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3510 memento.xPrecision, memento.yPrecision, memento.downTime,
3511 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3512 mMotionMementos.removeAt(i);
3513 } else {
3514 i += 1;
3515 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003516 }
3517}
3518
3519void InputDispatcher::InputState::clear() {
3520 mKeyMementos.clear();
3521 mMotionMementos.clear();
Jeff Brownb6997262010-10-08 22:31:17 -07003522}
3523
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003524void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3525 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3526 const MotionMemento& memento = mMotionMementos.itemAt(i);
3527 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3528 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3529 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3530 if (memento.deviceId == otherMemento.deviceId
3531 && memento.source == otherMemento.source) {
3532 other.mMotionMementos.removeAt(j);
3533 } else {
3534 j += 1;
3535 }
3536 }
3537 other.mMotionMementos.push(memento);
3538 }
3539 }
3540}
3541
Jeff Brown49ed71d2010-12-06 17:13:33 -08003542bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
Jeff Brownb6997262010-10-08 22:31:17 -07003543 CancelationOptions options) {
3544 switch (options) {
Jeff Brown49ed71d2010-12-06 17:13:33 -08003545 case CANCEL_ALL_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003546 case CANCEL_NON_POINTER_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003547 return true;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003548 case CANCEL_FALLBACK_EVENTS:
3549 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
3550 default:
3551 return false;
3552 }
3553}
3554
3555bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
3556 CancelationOptions options) {
3557 switch (options) {
3558 case CANCEL_ALL_EVENTS:
3559 return true;
3560 case CANCEL_POINTER_EVENTS:
3561 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
3562 case CANCEL_NON_POINTER_EVENTS:
3563 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
3564 default:
3565 return false;
Jeff Brownb6997262010-10-08 22:31:17 -07003566 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003567}
3568
3569
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003570// --- InputDispatcher::Connection ---
3571
3572InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3573 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown519e0242010-09-15 15:18:56 -07003574 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003575}
3576
3577InputDispatcher::Connection::~Connection() {
3578}
3579
3580status_t InputDispatcher::Connection::initialize() {
3581 return inputPublisher.initialize();
3582}
3583
Jeff Brown9c3cda02010-06-15 01:31:58 -07003584const char* InputDispatcher::Connection::getStatusLabel() const {
3585 switch (status) {
3586 case STATUS_NORMAL:
3587 return "NORMAL";
3588
3589 case STATUS_BROKEN:
3590 return "BROKEN";
3591
Jeff Brown9c3cda02010-06-15 01:31:58 -07003592 case STATUS_ZOMBIE:
3593 return "ZOMBIE";
3594
3595 default:
3596 return "UNKNOWN";
3597 }
3598}
3599
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003600InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3601 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07003602 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3603 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003604 if (dispatchEntry->eventEntry == eventEntry) {
3605 return dispatchEntry;
3606 }
3607 }
3608 return NULL;
3609}
3610
Jeff Brownb88102f2010-09-08 11:49:43 -07003611
Jeff Brown9c3cda02010-06-15 01:31:58 -07003612// --- InputDispatcher::CommandEntry ---
3613
Jeff Brownb88102f2010-09-08 11:49:43 -07003614InputDispatcher::CommandEntry::CommandEntry() :
3615 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003616}
3617
3618InputDispatcher::CommandEntry::~CommandEntry() {
3619}
3620
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003621
Jeff Brown01ce2e92010-09-26 22:20:12 -07003622// --- InputDispatcher::TouchState ---
3623
3624InputDispatcher::TouchState::TouchState() :
3625 down(false), split(false) {
3626}
3627
3628InputDispatcher::TouchState::~TouchState() {
3629}
3630
3631void InputDispatcher::TouchState::reset() {
3632 down = false;
3633 split = false;
3634 windows.clear();
3635}
3636
3637void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3638 down = other.down;
3639 split = other.split;
3640 windows.clear();
3641 windows.appendVector(other.windows);
3642}
3643
3644void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3645 int32_t targetFlags, BitSet32 pointerIds) {
3646 if (targetFlags & InputTarget::FLAG_SPLIT) {
3647 split = true;
3648 }
3649
3650 for (size_t i = 0; i < windows.size(); i++) {
3651 TouchedWindow& touchedWindow = windows.editItemAt(i);
3652 if (touchedWindow.window == window) {
3653 touchedWindow.targetFlags |= targetFlags;
3654 touchedWindow.pointerIds.value |= pointerIds.value;
3655 return;
3656 }
3657 }
3658
3659 windows.push();
3660
3661 TouchedWindow& touchedWindow = windows.editTop();
3662 touchedWindow.window = window;
3663 touchedWindow.targetFlags = targetFlags;
3664 touchedWindow.pointerIds = pointerIds;
3665 touchedWindow.channel = window->inputChannel;
3666}
3667
3668void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3669 for (size_t i = 0 ; i < windows.size(); ) {
3670 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3671 windows.removeAt(i);
3672 } else {
3673 i += 1;
3674 }
3675 }
3676}
3677
3678const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3679 for (size_t i = 0; i < windows.size(); i++) {
3680 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3681 return windows[i].window;
3682 }
3683 }
3684 return NULL;
3685}
3686
3687
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003688// --- InputDispatcherThread ---
3689
3690InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3691 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3692}
3693
3694InputDispatcherThread::~InputDispatcherThread() {
3695}
3696
3697bool InputDispatcherThread::threadLoop() {
3698 mDispatcher->dispatchOnce();
3699 return true;
3700}
3701
3702} // namespace android