blob: 0548e61be559e2ce7fadcd623b5c73f9cbf8ec63 [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 Brown00045a72010-12-09 18:10:30 -0800911 if (connection->status == Connection::STATUS_NORMAL) {
912 synthesizeCancelationEventsForConnectionLocked(
913 connection, InputState::CANCEL_ALL_EVENTS,
914 "application not responding");
915 }
Jeff Browndc3e0052010-09-16 11:02:16 -0700916 }
Jeff Brown519e0242010-09-15 15:18:56 -0700917 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700918 }
919}
920
Jeff Brown519e0242010-09-15 15:18:56 -0700921nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -0700922 nsecs_t currentTime) {
923 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
924 return currentTime - mInputTargetWaitStartTime;
925 }
926 return 0;
927}
928
929void InputDispatcher::resetANRTimeoutsLocked() {
930#if DEBUG_FOCUS
931 LOGD("Resetting ANR timeouts.");
932#endif
933
Jeff Brownb88102f2010-09-08 11:49:43 -0700934 // Reset input target wait timeout.
935 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
936}
937
Jeff Brown01ce2e92010-09-26 22:20:12 -0700938int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
939 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700940 mCurrentInputTargets.clear();
941
942 int32_t injectionResult;
943
944 // If there is no currently focused window and no focused application
945 // then drop the event.
946 if (! mFocusedWindow) {
947 if (mFocusedApplication) {
948#if DEBUG_FOCUS
949 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -0700950 "focused application that may eventually add a window: %s.",
951 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700952#endif
953 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
954 mFocusedApplication, NULL, nextWakeupTime);
955 goto Unresponsive;
956 }
957
958 LOGI("Dropping event because there is no focused window or focused application.");
959 injectionResult = INPUT_EVENT_INJECTION_FAILED;
960 goto Failed;
961 }
962
963 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700964 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700965 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
966 goto Failed;
967 }
968
969 // If the currently focused window is paused then keep waiting.
970 if (mFocusedWindow->paused) {
971#if DEBUG_FOCUS
972 LOGD("Waiting because focused window is paused.");
973#endif
974 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
975 mFocusedApplication, mFocusedWindow, nextWakeupTime);
976 goto Unresponsive;
977 }
978
Jeff Brown519e0242010-09-15 15:18:56 -0700979 // If the currently focused window is still working on previous events then keep waiting.
980 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
981#if DEBUG_FOCUS
982 LOGD("Waiting because focused window still processing previous input.");
983#endif
984 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
985 mFocusedApplication, mFocusedWindow, nextWakeupTime);
986 goto Unresponsive;
987 }
988
Jeff Brownb88102f2010-09-08 11:49:43 -0700989 // Success! Output targets.
990 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700991 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -0700992
993 // Done.
994Failed:
995Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -0700996 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
997 updateDispatchStatisticsLocked(currentTime, entry,
998 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -0700999#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -07001000 LOGD("findFocusedWindow finished: injectionResult=%d, "
1001 "timeSpendWaitingForApplication=%0.1fms",
1002 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001003#endif
1004 return injectionResult;
1005}
1006
Jeff Brown01ce2e92010-09-26 22:20:12 -07001007int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1008 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001009 enum InjectionPermission {
1010 INJECTION_PERMISSION_UNKNOWN,
1011 INJECTION_PERMISSION_GRANTED,
1012 INJECTION_PERMISSION_DENIED
1013 };
1014
Jeff Brownb88102f2010-09-08 11:49:43 -07001015 mCurrentInputTargets.clear();
1016
1017 nsecs_t startTime = now();
1018
1019 // For security reasons, we defer updating the touch state until we are sure that
1020 // event injection will be allowed.
1021 //
1022 // FIXME In the original code, screenWasOff could never be set to true.
1023 // The reason is that the POLICY_FLAG_WOKE_HERE
1024 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1025 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1026 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1027 // events upon which no preprocessing took place. So policyFlags was always 0.
1028 // In the new native input dispatcher we're a bit more careful about event
1029 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1030 // Unfortunately we obtain undesirable behavior.
1031 //
1032 // Here's what happens:
1033 //
1034 // When the device dims in anticipation of going to sleep, touches
1035 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1036 // the device to brighten and reset the user activity timer.
1037 // Touches on other windows (such as the launcher window)
1038 // are dropped. Then after a moment, the device goes to sleep. Oops.
1039 //
1040 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1041 // instead of POLICY_FLAG_WOKE_HERE...
1042 //
1043 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1044
1045 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001046 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001047
1048 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001049 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1050 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1051 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1052 mTempTouchState.reset();
1053 mTempTouchState.down = true;
1054 } else {
1055 mTempTouchState.copyFrom(mTouchState);
1056 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001057
Jeff Brown01ce2e92010-09-26 22:20:12 -07001058 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1059 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1060 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1061 /* Case 1: New splittable pointer going down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001062
Jeff Brown01ce2e92010-09-26 22:20:12 -07001063 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1064 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1065 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1066 const InputWindow* newTouchedWindow = NULL;
1067 const InputWindow* topErrorWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07001068
1069 // Traverse windows from front to back to find touched window and outside targets.
1070 size_t numWindows = mWindows.size();
1071 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001072 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001073 int32_t flags = window->layoutParamsFlags;
1074
1075 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1076 if (! topErrorWindow) {
1077 topErrorWindow = window;
1078 }
1079 }
1080
1081 if (window->visible) {
1082 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1083 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1084 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1085 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1086 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1087 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001088 }
1089 break; // found touched window, exit window loop
1090 }
1091 }
1092
Jeff Brown01ce2e92010-09-26 22:20:12 -07001093 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1094 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001095 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1096 if (isWindowObscuredAtPointLocked(window, x, y)) {
1097 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1098 }
1099
1100 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001101 }
1102 }
1103 }
1104
1105 // If there is an error window but it is not taking focus (typically because
1106 // it is invisible) then wait for it. Any other focused window may in
1107 // fact be in ANR state.
1108 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1109#if DEBUG_FOCUS
1110 LOGD("Waiting because system error window is pending.");
1111#endif
1112 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1113 NULL, NULL, nextWakeupTime);
1114 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1115 goto Unresponsive;
1116 }
1117
Jeff Brown01ce2e92010-09-26 22:20:12 -07001118 // Figure out whether splitting will be allowed for this window.
Jeff Brown46e75292010-11-10 16:53:45 -08001119 if (newTouchedWindow && newTouchedWindow->supportsSplitTouch()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001120 // New window supports splitting.
1121 isSplit = true;
1122 } else if (isSplit) {
1123 // New window does not support splitting but we have already split events.
1124 // Assign the pointer to the first foreground window we find.
1125 // (May be NULL which is why we put this code block before the next check.)
1126 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1127 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001128
Jeff Brownb88102f2010-09-08 11:49:43 -07001129 // If we did not find a touched window then fail.
1130 if (! newTouchedWindow) {
1131 if (mFocusedApplication) {
1132#if DEBUG_FOCUS
1133 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001134 "focused application that may eventually add a new window: %s.",
1135 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001136#endif
1137 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1138 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001139 goto Unresponsive;
1140 }
1141
1142 LOGI("Dropping event because there is no touched window or focused application.");
1143 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001144 goto Failed;
1145 }
1146
Jeff Brown19dfc832010-10-05 12:26:23 -07001147 // Set target flags.
1148 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1149 if (isSplit) {
1150 targetFlags |= InputTarget::FLAG_SPLIT;
1151 }
1152 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1153 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1154 }
1155
Jeff Brown01ce2e92010-09-26 22:20:12 -07001156 // Update the temporary touch state.
1157 BitSet32 pointerIds;
1158 if (isSplit) {
1159 uint32_t pointerId = entry->pointerIds[pointerIndex];
1160 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001161 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001162 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001163 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001164 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001165
1166 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001167 if (! mTempTouchState.down) {
Jeff Brown76860e32010-10-25 17:37:46 -07001168#if DEBUG_INPUT_DISPATCHER_POLICY
1169 LOGD("Dropping event because the pointer is not down or we previously "
1170 "dropped the pointer down event.");
1171#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001172 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001173 goto Failed;
1174 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001175 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001176
Jeff Brown01ce2e92010-09-26 22:20:12 -07001177 // Check permission to inject into all touched foreground windows and ensure there
1178 // is at least one touched foreground window.
1179 {
1180 bool haveForegroundWindow = false;
1181 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1182 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1183 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1184 haveForegroundWindow = true;
1185 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1186 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1187 injectionPermission = INJECTION_PERMISSION_DENIED;
1188 goto Failed;
1189 }
1190 }
1191 }
1192 if (! haveForegroundWindow) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001193#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown01ce2e92010-09-26 22:20:12 -07001194 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001195#endif
1196 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001197 goto Failed;
1198 }
1199
Jeff Brown01ce2e92010-09-26 22:20:12 -07001200 // Permission granted to injection into all touched foreground windows.
1201 injectionPermission = INJECTION_PERMISSION_GRANTED;
1202 }
Jeff Brown519e0242010-09-15 15:18:56 -07001203
Jeff Brown01ce2e92010-09-26 22:20:12 -07001204 // Ensure all touched foreground windows are ready for new input.
1205 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1206 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1207 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1208 // If the touched window is paused then keep waiting.
1209 if (touchedWindow.window->paused) {
1210#if DEBUG_INPUT_DISPATCHER_POLICY
1211 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001212#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001213 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1214 NULL, touchedWindow.window, nextWakeupTime);
1215 goto Unresponsive;
1216 }
1217
1218 // If the touched window is still working on previous events then keep waiting.
1219 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1220#if DEBUG_FOCUS
1221 LOGD("Waiting because touched window still processing previous input.");
1222#endif
1223 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1224 NULL, touchedWindow.window, nextWakeupTime);
1225 goto Unresponsive;
1226 }
1227 }
1228 }
1229
1230 // If this is the first pointer going down and the touched window has a wallpaper
1231 // then also add the touched wallpaper windows so they are locked in for the duration
1232 // of the touch gesture.
1233 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1234 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1235 if (foregroundWindow->hasWallpaper) {
1236 for (size_t i = 0; i < mWindows.size(); i++) {
1237 const InputWindow* window = & mWindows[i];
1238 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001239 mTempTouchState.addOrUpdateWindow(window,
1240 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001241 }
1242 }
1243 }
1244 }
1245
Jeff Brownb88102f2010-09-08 11:49:43 -07001246 // Success! Output targets.
1247 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001248
Jeff Brown01ce2e92010-09-26 22:20:12 -07001249 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1250 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1251 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1252 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001253 }
1254
Jeff Brown01ce2e92010-09-26 22:20:12 -07001255 // Drop the outside touch window since we will not care about them in the next iteration.
1256 mTempTouchState.removeOutsideTouchWindows();
1257
Jeff Brownb88102f2010-09-08 11:49:43 -07001258Failed:
1259 // Check injection permission once and for all.
1260 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001261 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001262 injectionPermission = INJECTION_PERMISSION_GRANTED;
1263 } else {
1264 injectionPermission = INJECTION_PERMISSION_DENIED;
1265 }
1266 }
1267
1268 // Update final pieces of touch state if the injector had permission.
1269 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001270 if (maskedAction == AMOTION_EVENT_ACTION_UP
1271 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1272 // All pointers up or canceled.
1273 mTempTouchState.reset();
1274 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1275 // First pointer went down.
1276 if (mTouchState.down) {
Jeff Brownb6997262010-10-08 22:31:17 -07001277#if DEBUG_FOCUS
1278 LOGD("Pointer down received while already down.");
1279#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001280 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001281 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1282 // One pointer went up.
1283 if (isSplit) {
1284 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1285 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001286
Jeff Brown01ce2e92010-09-26 22:20:12 -07001287 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1288 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1289 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1290 touchedWindow.pointerIds.clearBit(pointerId);
1291 if (touchedWindow.pointerIds.isEmpty()) {
1292 mTempTouchState.windows.removeAt(i);
1293 continue;
1294 }
1295 }
1296 i += 1;
1297 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001298 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001299 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001300
1301 // Save changes to touch state.
1302 mTouchState.copyFrom(mTempTouchState);
Jeff Brownb88102f2010-09-08 11:49:43 -07001303 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001304#if DEBUG_FOCUS
1305 LOGD("Not updating touch focus because injection was denied.");
1306#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001307 }
1308
1309Unresponsive:
Jeff Brown120a4592010-10-27 18:43:51 -07001310 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1311 mTempTouchState.reset();
1312
Jeff Brown519e0242010-09-15 15:18:56 -07001313 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1314 updateDispatchStatisticsLocked(currentTime, entry,
1315 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001316#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001317 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1318 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001319 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001320#endif
1321 return injectionResult;
1322}
1323
Jeff Brown01ce2e92010-09-26 22:20:12 -07001324void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1325 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001326 mCurrentInputTargets.push();
1327
1328 InputTarget& target = mCurrentInputTargets.editTop();
1329 target.inputChannel = window->inputChannel;
1330 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001331 target.xOffset = - window->frameLeft;
1332 target.yOffset = - window->frameTop;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001333 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001334}
1335
1336void InputDispatcher::addMonitoringTargetsLocked() {
1337 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1338 mCurrentInputTargets.push();
1339
1340 InputTarget& target = mCurrentInputTargets.editTop();
1341 target.inputChannel = mMonitoringChannels[i];
1342 target.flags = 0;
Jeff Brownb88102f2010-09-08 11:49:43 -07001343 target.xOffset = 0;
1344 target.yOffset = 0;
1345 }
1346}
1347
1348bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001349 const InjectionState* injectionState) {
1350 if (injectionState
Jeff Brownb6997262010-10-08 22:31:17 -07001351 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1352 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1353 if (window) {
1354 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1355 "with input channel %s owned by uid %d",
1356 injectionState->injectorPid, injectionState->injectorUid,
1357 window->inputChannel->getName().string(),
1358 window->ownerUid);
1359 } else {
1360 LOGW("Permission denied: injecting event from pid %d uid %d",
1361 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001362 }
Jeff Brownb6997262010-10-08 22:31:17 -07001363 return false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001364 }
1365 return true;
1366}
1367
Jeff Brown19dfc832010-10-05 12:26:23 -07001368bool InputDispatcher::isWindowObscuredAtPointLocked(
1369 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07001370 size_t numWindows = mWindows.size();
1371 for (size_t i = 0; i < numWindows; i++) {
1372 const InputWindow* other = & mWindows.itemAt(i);
1373 if (other == window) {
1374 break;
1375 }
Jeff Brown19dfc832010-10-05 12:26:23 -07001376 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001377 return true;
1378 }
1379 }
1380 return false;
1381}
1382
Jeff Brown519e0242010-09-15 15:18:56 -07001383bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1384 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1385 if (connectionIndex >= 0) {
1386 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1387 return connection->outboundQueue.isEmpty();
1388 } else {
1389 return true;
1390 }
1391}
1392
1393String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1394 const InputWindow* window) {
1395 if (application) {
1396 if (window) {
1397 String8 label(application->name);
1398 label.append(" - ");
1399 label.append(window->name);
1400 return label;
1401 } else {
1402 return application->name;
1403 }
1404 } else if (window) {
1405 return window->name;
1406 } else {
1407 return String8("<unknown application or window>");
1408 }
1409}
1410
Jeff Browne2fe69e2010-10-18 13:21:23 -07001411void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1412 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brown4d396052010-10-29 21:50:21 -07001413 switch (eventEntry->type) {
1414 case EventEntry::TYPE_MOTION: {
Jeff Browne2fe69e2010-10-18 13:21:23 -07001415 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Brown4d396052010-10-29 21:50:21 -07001416 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1417 return;
1418 }
1419
Jeff Browne2fe69e2010-10-18 13:21:23 -07001420 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
Joe Onorato1a542c72010-11-08 09:48:20 -08001421 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001422 }
Jeff Brown4d396052010-10-29 21:50:21 -07001423 break;
1424 }
1425 case EventEntry::TYPE_KEY: {
1426 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1427 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1428 return;
1429 }
1430 break;
1431 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001432 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001433
Jeff Brownb88102f2010-09-08 11:49:43 -07001434 CommandEntry* commandEntry = postCommandLocked(
1435 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Browne2fe69e2010-10-18 13:21:23 -07001436 commandEntry->eventTime = eventEntry->eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001437 commandEntry->userActivityEventType = eventType;
1438}
1439
Jeff Brown7fbdc842010-06-17 20:52:56 -07001440void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1441 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001442 bool resumeWithAppendedMotionSample) {
1443#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001444 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001445 "xOffset=%f, yOffset=%f, "
Jeff Brown83c09682010-12-23 17:50:18 -08001446 "pointerIds=0x%x, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001447 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001448 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001449 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brown83c09682010-12-23 17:50:18 -08001450 inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001451 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001452#endif
1453
Jeff Brown01ce2e92010-09-26 22:20:12 -07001454 // Make sure we are never called for streaming when splitting across multiple windows.
1455 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1456 assert(! (resumeWithAppendedMotionSample && isSplit));
1457
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001458 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001459 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001460 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb6997262010-10-08 22:31:17 -07001461#if DEBUG_DISPATCH_CYCLE
1462 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001463 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brownb6997262010-10-08 22:31:17 -07001464#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001465 return;
1466 }
1467
Jeff Brown01ce2e92010-09-26 22:20:12 -07001468 // Split a motion event if needed.
1469 if (isSplit) {
1470 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1471
1472 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1473 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1474 MotionEntry* splitMotionEntry = splitMotionEvent(
1475 originalMotionEntry, inputTarget->pointerIds);
1476#if DEBUG_FOCUS
1477 LOGD("channel '%s' ~ Split motion event.",
1478 connection->getInputChannelName());
1479 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1480#endif
1481 eventEntry = splitMotionEntry;
1482 }
1483 }
1484
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001485 // Resume the dispatch cycle with a freshly appended motion sample.
1486 // First we check that the last dispatch entry in the outbound queue is for the same
1487 // motion event to which we appended the motion sample. If we find such a dispatch
1488 // entry, and if it is currently in progress then we try to stream the new sample.
1489 bool wasEmpty = connection->outboundQueue.isEmpty();
1490
1491 if (! wasEmpty && resumeWithAppendedMotionSample) {
1492 DispatchEntry* motionEventDispatchEntry =
1493 connection->findQueuedDispatchEntryForEvent(eventEntry);
1494 if (motionEventDispatchEntry) {
1495 // If the dispatch entry is not in progress, then we must be busy dispatching an
1496 // earlier event. Not a problem, the motion event is on the outbound queue and will
1497 // be dispatched later.
1498 if (! motionEventDispatchEntry->inProgress) {
1499#if DEBUG_BATCHING
1500 LOGD("channel '%s' ~ Not streaming because the motion event has "
1501 "not yet been dispatched. "
1502 "(Waiting for earlier events to be consumed.)",
1503 connection->getInputChannelName());
1504#endif
1505 return;
1506 }
1507
1508 // If the dispatch entry is in progress but it already has a tail of pending
1509 // motion samples, then it must mean that the shared memory buffer filled up.
1510 // Not a problem, when this dispatch cycle is finished, we will eventually start
1511 // a new dispatch cycle to process the tail and that tail includes the newly
1512 // appended motion sample.
1513 if (motionEventDispatchEntry->tailMotionSample) {
1514#if DEBUG_BATCHING
1515 LOGD("channel '%s' ~ Not streaming because no new samples can "
1516 "be appended to the motion event in this dispatch cycle. "
1517 "(Waiting for next dispatch cycle to start.)",
1518 connection->getInputChannelName());
1519#endif
1520 return;
1521 }
1522
1523 // The dispatch entry is in progress and is still potentially open for streaming.
1524 // Try to stream the new motion sample. This might fail if the consumer has already
1525 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001526 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1527 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001528 status_t status = connection->inputPublisher.appendMotionSample(
1529 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1530 if (status == OK) {
1531#if DEBUG_BATCHING
1532 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1533 connection->getInputChannelName());
1534#endif
1535 return;
1536 }
1537
1538#if DEBUG_BATCHING
1539 if (status == NO_MEMORY) {
1540 LOGD("channel '%s' ~ Could not append motion sample to currently "
1541 "dispatched move event because the shared memory buffer is full. "
1542 "(Waiting for next dispatch cycle to start.)",
1543 connection->getInputChannelName());
1544 } else if (status == status_t(FAILED_TRANSACTION)) {
1545 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001546 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001547 "(Waiting for next dispatch cycle to start.)",
1548 connection->getInputChannelName());
1549 } else {
1550 LOGD("channel '%s' ~ Could not append motion sample to currently "
1551 "dispatched move event due to an error, status=%d. "
1552 "(Waiting for next dispatch cycle to start.)",
1553 connection->getInputChannelName(), status);
1554 }
1555#endif
1556 // Failed to stream. Start a new tail of pending motion samples to dispatch
1557 // in the next cycle.
1558 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1559 return;
1560 }
1561 }
1562
1563 // This is a new event.
1564 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001565 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown519e0242010-09-15 15:18:56 -07001566 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1567 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001568 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001569 }
1570
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001571 // Handle the case where we could not stream a new motion sample because the consumer has
1572 // already consumed the motion event (otherwise the corresponding dispatch entry would
1573 // still be in the outbound queue for this connection). We set the head motion sample
1574 // to the list starting with the newly appended motion sample.
1575 if (resumeWithAppendedMotionSample) {
1576#if DEBUG_BATCHING
1577 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1578 "that cannot be streamed because the motion event has already been consumed.",
1579 connection->getInputChannelName());
1580#endif
1581 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1582 dispatchEntry->headMotionSample = appendedMotionSample;
1583 }
1584
1585 // Enqueue the dispatch entry.
1586 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1587
1588 // If the outbound queue was previously empty, start the dispatch cycle going.
1589 if (wasEmpty) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001590 activateConnectionLocked(connection.get());
Jeff Brown519e0242010-09-15 15:18:56 -07001591 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001592 }
1593}
1594
Jeff Brown7fbdc842010-06-17 20:52:56 -07001595void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001596 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001597#if DEBUG_DISPATCH_CYCLE
1598 LOGD("channel '%s' ~ startDispatchCycle",
1599 connection->getInputChannelName());
1600#endif
1601
1602 assert(connection->status == Connection::STATUS_NORMAL);
1603 assert(! connection->outboundQueue.isEmpty());
1604
Jeff Brownb88102f2010-09-08 11:49:43 -07001605 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001606 assert(! dispatchEntry->inProgress);
1607
Jeff Brownb88102f2010-09-08 11:49:43 -07001608 // Mark the dispatch entry as in progress.
1609 dispatchEntry->inProgress = true;
1610
1611 // Update the connection's input state.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001612 EventEntry* eventEntry = dispatchEntry->eventEntry;
1613 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001614
1615#if FILTER_INPUT_EVENTS
1616 // Filter out inconsistent sequences of input events.
1617 // The input system may drop or inject events in a way that could violate implicit
1618 // invariants on input state and potentially cause an application to crash
1619 // or think that a key or pointer is stuck down. Technically we make no guarantees
1620 // of consistency but it would be nice to improve on this where possible.
1621 // XXX: This code is a proof of concept only. Not ready for prime time.
1622 if (consistency == InputState::TOLERABLE) {
1623#if DEBUG_DISPATCH_CYCLE
1624 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1625 "current input state but that is likely to be tolerated by the application.",
1626 connection->getInputChannelName());
1627#endif
1628 } else if (consistency == InputState::BROKEN) {
1629 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1630 "current input state and that is likely to cause the application to crash.",
1631 connection->getInputChannelName());
1632 startNextDispatchCycleLocked(currentTime, connection);
1633 return;
1634 }
1635#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001636
1637 // Publish the event.
1638 status_t status;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001639 switch (eventEntry->type) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001640 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001641 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001642
1643 // Apply target flags.
1644 int32_t action = keyEntry->action;
1645 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001646
1647 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001648 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001649 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1650 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1651 keyEntry->eventTime);
1652
1653 if (status) {
1654 LOGE("channel '%s' ~ Could not publish key event, "
1655 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001656 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001657 return;
1658 }
1659 break;
1660 }
1661
1662 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001663 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001664
1665 // Apply target flags.
1666 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001667 int32_t flags = motionEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001668 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001669 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001670 }
Jeff Brown85a31762010-09-01 17:01:00 -07001671 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1672 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1673 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001674
1675 // If headMotionSample is non-NULL, then it points to the first new sample that we
1676 // were unable to dispatch during the previous cycle so we resume dispatching from
1677 // that point in the list of motion samples.
1678 // Otherwise, we just start from the first sample of the motion event.
1679 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1680 if (! firstMotionSample) {
1681 firstMotionSample = & motionEntry->firstSample;
1682 }
1683
Jeff Brownd3616592010-07-16 17:21:06 -07001684 // Set the X and Y offset depending on the input source.
1685 float xOffset, yOffset;
1686 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1687 xOffset = dispatchEntry->xOffset;
1688 yOffset = dispatchEntry->yOffset;
1689 } else {
1690 xOffset = 0.0f;
1691 yOffset = 0.0f;
1692 }
1693
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001694 // Publish the motion event and the first motion sample.
1695 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07001696 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownd3616592010-07-16 17:21:06 -07001697 xOffset, yOffset,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001698 motionEntry->xPrecision, motionEntry->yPrecision,
1699 motionEntry->downTime, firstMotionSample->eventTime,
1700 motionEntry->pointerCount, motionEntry->pointerIds,
1701 firstMotionSample->pointerCoords);
1702
1703 if (status) {
1704 LOGE("channel '%s' ~ Could not publish motion event, "
1705 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001706 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001707 return;
1708 }
1709
1710 // Append additional motion samples.
1711 MotionSample* nextMotionSample = firstMotionSample->next;
1712 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1713 status = connection->inputPublisher.appendMotionSample(
1714 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1715 if (status == NO_MEMORY) {
1716#if DEBUG_DISPATCH_CYCLE
1717 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1718 "be sent in the next dispatch cycle.",
1719 connection->getInputChannelName());
1720#endif
1721 break;
1722 }
1723 if (status != OK) {
1724 LOGE("channel '%s' ~ Could not append motion sample "
1725 "for a reason other than out of memory, status=%d",
1726 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001727 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001728 return;
1729 }
1730 }
1731
1732 // Remember the next motion sample that we could not dispatch, in case we ran out
1733 // of space in the shared memory buffer.
1734 dispatchEntry->tailMotionSample = nextMotionSample;
1735 break;
1736 }
1737
1738 default: {
1739 assert(false);
1740 }
1741 }
1742
1743 // Send the dispatch signal.
1744 status = connection->inputPublisher.sendDispatchSignal();
1745 if (status) {
1746 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1747 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001748 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001749 return;
1750 }
1751
1752 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001753 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001754 connection->lastDispatchTime = currentTime;
1755
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001756 // Notify other system components.
1757 onDispatchCycleStartedLocked(currentTime, connection);
1758}
1759
Jeff Brown7fbdc842010-06-17 20:52:56 -07001760void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown3915bb82010-11-05 15:02:16 -07001761 const sp<Connection>& connection, bool handled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001762#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001763 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown3915bb82010-11-05 15:02:16 -07001764 "%01.1fms since dispatch, handled=%s",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001765 connection->getInputChannelName(),
1766 connection->getEventLatencyMillis(currentTime),
Jeff Brown3915bb82010-11-05 15:02:16 -07001767 connection->getDispatchLatencyMillis(currentTime),
1768 toString(handled));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001769#endif
1770
Jeff Brown9c3cda02010-06-15 01:31:58 -07001771 if (connection->status == Connection::STATUS_BROKEN
1772 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001773 return;
1774 }
1775
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001776 // Reset the publisher since the event has been consumed.
1777 // We do this now so that the publisher can release some of its internal resources
1778 // while waiting for the next dispatch cycle to begin.
1779 status_t status = connection->inputPublisher.reset();
1780 if (status) {
1781 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1782 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001783 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001784 return;
1785 }
1786
Jeff Brown3915bb82010-11-05 15:02:16 -07001787 // Notify other system components and prepare to start the next dispatch cycle.
1788 onDispatchCycleFinishedLocked(currentTime, connection, handled);
Jeff Brownb88102f2010-09-08 11:49:43 -07001789}
1790
1791void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1792 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001793 // Start the next dispatch cycle for this connection.
1794 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001795 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001796 if (dispatchEntry->inProgress) {
1797 // Finish or resume current event in progress.
1798 if (dispatchEntry->tailMotionSample) {
1799 // We have a tail of undispatched motion samples.
1800 // Reuse the same DispatchEntry and start a new cycle.
1801 dispatchEntry->inProgress = false;
1802 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1803 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07001804 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001805 return;
1806 }
1807 // Finished.
1808 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07001809 if (dispatchEntry->hasForegroundTarget()) {
1810 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001811 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001812 mAllocator.releaseDispatchEntry(dispatchEntry);
1813 } else {
1814 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07001815 // progress event, which means we actually aborted it.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001816 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07001817 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001818 return;
1819 }
1820 }
1821
1822 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07001823 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001824}
1825
Jeff Brownb6997262010-10-08 22:31:17 -07001826void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1827 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001828#if DEBUG_DISPATCH_CYCLE
Jeff Brown83c09682010-12-23 17:50:18 -08001829 LOGD("channel '%s' ~ abortBrokenDispatchCycle",
1830 connection->getInputChannelName());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001831#endif
1832
Jeff Brownb88102f2010-09-08 11:49:43 -07001833 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07001834 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001835
Jeff Brownb6997262010-10-08 22:31:17 -07001836 // The connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07001837 // Ignore already broken or zombie connections.
Jeff Brownb6997262010-10-08 22:31:17 -07001838 if (connection->status == Connection::STATUS_NORMAL) {
1839 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001840
Jeff Brownb6997262010-10-08 22:31:17 -07001841 // Notify other system components.
1842 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001843 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001844}
1845
Jeff Brown519e0242010-09-15 15:18:56 -07001846void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1847 while (! connection->outboundQueue.isEmpty()) {
1848 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1849 if (dispatchEntry->hasForegroundTarget()) {
1850 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001851 }
1852 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001853 }
1854
Jeff Brown519e0242010-09-15 15:18:56 -07001855 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07001856}
1857
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001858int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001859 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1860
1861 { // acquire lock
1862 AutoMutex _l(d->mLock);
1863
1864 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1865 if (connectionIndex < 0) {
1866 LOGE("Received spurious receive callback for unknown input channel. "
1867 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001868 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001869 }
1870
Jeff Brown7fbdc842010-06-17 20:52:56 -07001871 nsecs_t currentTime = now();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001872
1873 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001874 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001875 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1876 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brownb6997262010-10-08 22:31:17 -07001877 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001878 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001879 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001880 }
1881
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001882 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001883 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1884 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001885 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001886 }
1887
Jeff Brown3915bb82010-11-05 15:02:16 -07001888 bool handled = false;
Jeff Brown49ed71d2010-12-06 17:13:33 -08001889 status_t status = connection->inputPublisher.receiveFinishedSignal(&handled);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001890 if (status) {
1891 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1892 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001893 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001894 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001895 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001896 }
1897
Jeff Brown3915bb82010-11-05 15:02:16 -07001898 d->finishDispatchCycleLocked(currentTime, connection, handled);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001899 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001900 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001901 } // release lock
1902}
1903
Jeff Brownb6997262010-10-08 22:31:17 -07001904void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1905 InputState::CancelationOptions options, const char* reason) {
1906 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1907 synthesizeCancelationEventsForConnectionLocked(
1908 mConnectionsByReceiveFd.valueAt(i), options, reason);
1909 }
1910}
1911
1912void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1913 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1914 const char* reason) {
1915 ssize_t index = getConnectionIndexLocked(channel);
1916 if (index >= 0) {
1917 synthesizeCancelationEventsForConnectionLocked(
1918 mConnectionsByReceiveFd.valueAt(index), options, reason);
1919 }
1920}
1921
1922void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1923 const sp<Connection>& connection, InputState::CancelationOptions options,
1924 const char* reason) {
1925 nsecs_t currentTime = now();
1926
1927 mTempCancelationEvents.clear();
1928 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1929 mTempCancelationEvents, options);
1930
1931 if (! mTempCancelationEvents.isEmpty()
1932 && connection->status != Connection::STATUS_BROKEN) {
1933#if DEBUG_OUTBOUND_EVENT_DETAILS
1934 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1935 "with reality: %s, options=%d.",
1936 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1937#endif
1938 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1939 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1940 switch (cancelationEventEntry->type) {
1941 case EventEntry::TYPE_KEY:
1942 logOutboundKeyDetailsLocked("cancel - ",
1943 static_cast<KeyEntry*>(cancelationEventEntry));
1944 break;
1945 case EventEntry::TYPE_MOTION:
1946 logOutboundMotionDetailsLocked("cancel - ",
1947 static_cast<MotionEntry*>(cancelationEventEntry));
1948 break;
1949 }
1950
1951 int32_t xOffset, yOffset;
1952 const InputWindow* window = getWindowLocked(connection->inputChannel);
1953 if (window) {
1954 xOffset = -window->frameLeft;
1955 yOffset = -window->frameTop;
1956 } else {
1957 xOffset = 0;
1958 yOffset = 0;
1959 }
1960
1961 DispatchEntry* cancelationDispatchEntry =
1962 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1963 0, xOffset, yOffset);
1964 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1965
1966 mAllocator.releaseEventEntry(cancelationEventEntry);
1967 }
1968
1969 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1970 startDispatchCycleLocked(currentTime, connection);
1971 }
1972 }
1973}
1974
Jeff Brown01ce2e92010-09-26 22:20:12 -07001975InputDispatcher::MotionEntry*
1976InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1977 assert(pointerIds.value != 0);
1978
1979 uint32_t splitPointerIndexMap[MAX_POINTERS];
1980 int32_t splitPointerIds[MAX_POINTERS];
1981 PointerCoords splitPointerCoords[MAX_POINTERS];
1982
1983 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1984 uint32_t splitPointerCount = 0;
1985
1986 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1987 originalPointerIndex++) {
1988 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1989 if (pointerIds.hasBit(pointerId)) {
1990 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1991 splitPointerIds[splitPointerCount] = pointerId;
1992 splitPointerCoords[splitPointerCount] =
1993 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1994 splitPointerCount += 1;
1995 }
1996 }
1997 assert(splitPointerCount == pointerIds.count());
1998
1999 int32_t action = originalMotionEntry->action;
2000 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2001 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2002 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2003 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2004 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2005 if (pointerIds.hasBit(pointerId)) {
2006 if (pointerIds.count() == 1) {
2007 // The first/last pointer went down/up.
2008 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2009 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07002010 } else {
2011 // A secondary pointer went down/up.
2012 uint32_t splitPointerIndex = 0;
2013 while (pointerId != splitPointerIds[splitPointerIndex]) {
2014 splitPointerIndex += 1;
2015 }
2016 action = maskedAction | (splitPointerIndex
2017 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002018 }
2019 } else {
2020 // An unrelated pointer changed.
2021 action = AMOTION_EVENT_ACTION_MOVE;
2022 }
2023 }
2024
2025 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2026 originalMotionEntry->eventTime,
2027 originalMotionEntry->deviceId,
2028 originalMotionEntry->source,
2029 originalMotionEntry->policyFlags,
2030 action,
2031 originalMotionEntry->flags,
2032 originalMotionEntry->metaState,
2033 originalMotionEntry->edgeFlags,
2034 originalMotionEntry->xPrecision,
2035 originalMotionEntry->yPrecision,
2036 originalMotionEntry->downTime,
2037 splitPointerCount, splitPointerIds, splitPointerCoords);
2038
2039 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2040 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2041 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2042 splitPointerIndex++) {
2043 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2044 splitPointerCoords[splitPointerIndex] =
2045 originalMotionSample->pointerCoords[originalPointerIndex];
2046 }
2047
2048 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2049 splitPointerCoords);
2050 }
2051
2052 return splitMotionEntry;
2053}
2054
Jeff Brown9c3cda02010-06-15 01:31:58 -07002055void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002056#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07002057 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002058#endif
2059
Jeff Brownb88102f2010-09-08 11:49:43 -07002060 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002061 { // acquire lock
2062 AutoMutex _l(mLock);
2063
Jeff Brown7fbdc842010-06-17 20:52:56 -07002064 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07002065 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002066 } // release lock
2067
Jeff Brownb88102f2010-09-08 11:49:43 -07002068 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002069 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002070 }
2071}
2072
Jeff Brownc5ed5912010-07-14 18:48:53 -07002073void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002074 uint32_t policyFlags, int32_t action, int32_t flags,
2075 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2076#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002077 LOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002078 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07002079 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002080 keyCode, scanCode, metaState, downTime);
2081#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002082 if (! validateKeyEvent(action)) {
2083 return;
2084 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002085
Jeff Brown1f245102010-11-18 20:53:46 -08002086 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2087 policyFlags |= POLICY_FLAG_VIRTUAL;
2088 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2089 }
2090
Jeff Browne20c9e02010-10-11 14:20:19 -07002091 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown1f245102010-11-18 20:53:46 -08002092
2093 KeyEvent event;
2094 event.initialize(deviceId, source, action, flags, keyCode, scanCode,
2095 metaState, 0, downTime, eventTime);
2096
2097 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
2098
2099 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2100 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2101 }
Jeff Brownb6997262010-10-08 22:31:17 -07002102
Jeff Brownb88102f2010-09-08 11:49:43 -07002103 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002104 { // acquire lock
2105 AutoMutex _l(mLock);
2106
Jeff Brown7fbdc842010-06-17 20:52:56 -07002107 int32_t repeatCount = 0;
2108 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002109 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002110 metaState, repeatCount, downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002111
Jeff Brownb88102f2010-09-08 11:49:43 -07002112 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002113 } // release lock
2114
Jeff Brownb88102f2010-09-08 11:49:43 -07002115 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002116 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002117 }
2118}
2119
Jeff Brownc5ed5912010-07-14 18:48:53 -07002120void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002121 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002122 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2123 float xPrecision, float yPrecision, nsecs_t downTime) {
2124#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002125 LOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002126 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2127 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2128 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002129 xPrecision, yPrecision, downTime);
2130 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002131 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002132 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002133 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002134 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown8d608662010-08-30 03:02:23 -07002135 pointerCoords[i].pressure, pointerCoords[i].size,
2136 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2137 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2138 pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002139 }
2140#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002141 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2142 return;
2143 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002144
Jeff Browne20c9e02010-10-11 14:20:19 -07002145 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002146 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2147
Jeff Brownb88102f2010-09-08 11:49:43 -07002148 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002149 { // acquire lock
2150 AutoMutex _l(mLock);
2151
2152 // Attempt batching and streaming of move events.
Jeff Brownc5ed5912010-07-14 18:48:53 -07002153 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002154 // BATCHING CASE
2155 //
2156 // Try to append a move sample to the tail of the inbound queue for this device.
2157 // Give up if we encounter a non-move motion event for this device since that
2158 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002159 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2160 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002161 if (entry->type != EventEntry::TYPE_MOTION) {
2162 // Keep looking for motion events.
2163 continue;
2164 }
2165
2166 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2167 if (motionEntry->deviceId != deviceId) {
2168 // Keep looking for this device.
2169 continue;
2170 }
2171
Jeff Brownc5ed5912010-07-14 18:48:53 -07002172 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown7fbdc842010-06-17 20:52:56 -07002173 || motionEntry->pointerCount != pointerCount
2174 || motionEntry->isInjected()) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002175 // Last motion event in the queue for this device is not compatible for
2176 // appending new samples. Stop here.
2177 goto NoBatchingOrStreaming;
2178 }
2179
2180 // The last motion event is a move and is compatible for appending.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002181 // Do the batching magic.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002182 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002183#if DEBUG_BATCHING
2184 LOGD("Appended motion sample onto batch for most recent "
2185 "motion event for this device in the inbound queue.");
2186#endif
Jeff Brown9c3cda02010-06-15 01:31:58 -07002187 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002188 }
2189
2190 // STREAMING CASE
2191 //
2192 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002193 // Search the outbound queue for the current foreground targets to find a dispatched
2194 // motion event that is still in progress. If found, then, appen the new sample to
2195 // that event and push it out to all current targets. The logic in
2196 // prepareDispatchCycleLocked takes care of the case where some targets may
2197 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002198 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002199 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2200 const InputTarget& inputTarget = mCurrentInputTargets[i];
2201 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2202 // Skip non-foreground targets. We only want to stream if there is at
2203 // least one foreground target whose dispatch is still in progress.
2204 continue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002205 }
Jeff Brown519e0242010-09-15 15:18:56 -07002206
2207 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2208 if (connectionIndex < 0) {
2209 // Connection must no longer be valid.
2210 continue;
2211 }
2212
2213 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2214 if (connection->outboundQueue.isEmpty()) {
2215 // This foreground target has an empty outbound queue.
2216 continue;
2217 }
2218
2219 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2220 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002221 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2222 || dispatchEntry->isSplit()) {
2223 // No motion event is being dispatched, or it is being split across
2224 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002225 continue;
2226 }
2227
2228 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2229 dispatchEntry->eventEntry);
2230 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2231 || motionEntry->deviceId != deviceId
2232 || motionEntry->pointerCount != pointerCount
2233 || motionEntry->isInjected()) {
2234 // The motion event is not compatible with this move.
2235 continue;
2236 }
2237
2238 // Hurray! This foreground target is currently dispatching a move event
2239 // that we can stream onto. Append the motion sample and resume dispatch.
2240 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2241#if DEBUG_BATCHING
2242 LOGD("Appended motion sample onto batch for most recently dispatched "
2243 "motion event for this device in the outbound queues. "
2244 "Attempting to stream the motion sample.");
2245#endif
2246 nsecs_t currentTime = now();
2247 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2248 true /*resumeWithAppendedMotionSample*/);
2249
2250 runCommandsLockedInterruptible();
2251 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002252 }
2253 }
2254
2255NoBatchingOrStreaming:;
2256 }
2257
2258 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002259 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002260 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002261 xPrecision, yPrecision, downTime,
2262 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002263
Jeff Brownb88102f2010-09-08 11:49:43 -07002264 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002265 } // release lock
2266
Jeff Brownb88102f2010-09-08 11:49:43 -07002267 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002268 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002269 }
2270}
2271
Jeff Brownb6997262010-10-08 22:31:17 -07002272void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2273 uint32_t policyFlags) {
2274#if DEBUG_INBOUND_EVENT_DETAILS
2275 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2276 switchCode, switchValue, policyFlags);
2277#endif
2278
Jeff Browne20c9e02010-10-11 14:20:19 -07002279 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002280 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2281}
2282
Jeff Brown7fbdc842010-06-17 20:52:56 -07002283int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002284 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002285#if DEBUG_INBOUND_EVENT_DETAILS
2286 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002287 "syncMode=%d, timeoutMillis=%d",
2288 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002289#endif
2290
2291 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Browne20c9e02010-10-11 14:20:19 -07002292
2293 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2294 if (hasInjectionPermission(injectorPid, injectorUid)) {
2295 policyFlags |= POLICY_FLAG_TRUSTED;
2296 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002297
Jeff Brownb6997262010-10-08 22:31:17 -07002298 EventEntry* injectedEntry;
2299 switch (event->getType()) {
2300 case AINPUT_EVENT_TYPE_KEY: {
2301 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2302 int32_t action = keyEvent->getAction();
2303 if (! validateKeyEvent(action)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002304 return INPUT_EVENT_INJECTION_FAILED;
2305 }
2306
Jeff Brownb6997262010-10-08 22:31:17 -07002307 int32_t flags = keyEvent->getFlags();
Jeff Brown1f245102010-11-18 20:53:46 -08002308 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2309 policyFlags |= POLICY_FLAG_VIRTUAL;
2310 }
2311
2312 mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
2313
2314 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2315 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2316 }
Jeff Brown6ec402b2010-07-28 15:48:59 -07002317
Jeff Brownb6997262010-10-08 22:31:17 -07002318 mLock.lock();
Jeff Brown1f245102010-11-18 20:53:46 -08002319 injectedEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
2320 keyEvent->getDeviceId(), keyEvent->getSource(),
2321 policyFlags, action, flags,
2322 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
Jeff Brownb6997262010-10-08 22:31:17 -07002323 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2324 break;
2325 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002326
Jeff Brownb6997262010-10-08 22:31:17 -07002327 case AINPUT_EVENT_TYPE_MOTION: {
2328 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2329 int32_t action = motionEvent->getAction();
2330 size_t pointerCount = motionEvent->getPointerCount();
2331 const int32_t* pointerIds = motionEvent->getPointerIds();
2332 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2333 return INPUT_EVENT_INJECTION_FAILED;
2334 }
2335
2336 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Browne20c9e02010-10-11 14:20:19 -07002337 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002338
2339 mLock.lock();
2340 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2341 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2342 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2343 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2344 action, motionEvent->getFlags(),
2345 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2346 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2347 motionEvent->getDownTime(), uint32_t(pointerCount),
2348 pointerIds, samplePointerCoords);
2349 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2350 sampleEventTimes += 1;
2351 samplePointerCoords += pointerCount;
2352 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2353 }
2354 injectedEntry = motionEntry;
2355 break;
2356 }
2357
2358 default:
2359 LOGW("Cannot inject event of type %d", event->getType());
2360 return INPUT_EVENT_INJECTION_FAILED;
2361 }
2362
2363 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2364 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2365 injectionState->injectionIsAsync = true;
2366 }
2367
2368 injectionState->refCount += 1;
2369 injectedEntry->injectionState = injectionState;
2370
2371 bool needWake = enqueueInboundEventLocked(injectedEntry);
2372 mLock.unlock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002373
Jeff Brownb88102f2010-09-08 11:49:43 -07002374 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002375 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002376 }
2377
2378 int32_t injectionResult;
2379 { // acquire lock
2380 AutoMutex _l(mLock);
2381
Jeff Brown6ec402b2010-07-28 15:48:59 -07002382 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2383 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2384 } else {
2385 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002386 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002387 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2388 break;
2389 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002390
Jeff Brown7fbdc842010-06-17 20:52:56 -07002391 nsecs_t remainingTimeout = endTime - now();
2392 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002393#if DEBUG_INJECTION
2394 LOGD("injectInputEvent - Timed out waiting for injection result "
2395 "to become available.");
2396#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002397 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2398 break;
2399 }
2400
Jeff Brown6ec402b2010-07-28 15:48:59 -07002401 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2402 }
2403
2404 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2405 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002406 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002407#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002408 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002409 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002410#endif
2411 nsecs_t remainingTimeout = endTime - now();
2412 if (remainingTimeout <= 0) {
2413#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002414 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002415 "dispatches to finish.");
2416#endif
2417 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2418 break;
2419 }
2420
2421 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2422 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002423 }
2424 }
2425
Jeff Brown01ce2e92010-09-26 22:20:12 -07002426 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002427 } // release lock
2428
Jeff Brown6ec402b2010-07-28 15:48:59 -07002429#if DEBUG_INJECTION
2430 LOGD("injectInputEvent - Finished with result %d. "
2431 "injectorPid=%d, injectorUid=%d",
2432 injectionResult, injectorPid, injectorUid);
2433#endif
2434
Jeff Brown7fbdc842010-06-17 20:52:56 -07002435 return injectionResult;
2436}
2437
Jeff Brownb6997262010-10-08 22:31:17 -07002438bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2439 return injectorUid == 0
2440 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2441}
2442
Jeff Brown7fbdc842010-06-17 20:52:56 -07002443void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002444 InjectionState* injectionState = entry->injectionState;
2445 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002446#if DEBUG_INJECTION
2447 LOGD("Setting input event injection result to %d. "
2448 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002449 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002450#endif
2451
Jeff Brown01ce2e92010-09-26 22:20:12 -07002452 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002453 // Log the outcome since the injector did not wait for the injection result.
2454 switch (injectionResult) {
2455 case INPUT_EVENT_INJECTION_SUCCEEDED:
2456 LOGV("Asynchronous input event injection succeeded.");
2457 break;
2458 case INPUT_EVENT_INJECTION_FAILED:
2459 LOGW("Asynchronous input event injection failed.");
2460 break;
2461 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2462 LOGW("Asynchronous input event injection permission denied.");
2463 break;
2464 case INPUT_EVENT_INJECTION_TIMED_OUT:
2465 LOGW("Asynchronous input event injection timed out.");
2466 break;
2467 }
2468 }
2469
Jeff Brown01ce2e92010-09-26 22:20:12 -07002470 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002471 mInjectionResultAvailableCondition.broadcast();
2472 }
2473}
2474
Jeff Brown01ce2e92010-09-26 22:20:12 -07002475void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2476 InjectionState* injectionState = entry->injectionState;
2477 if (injectionState) {
2478 injectionState->pendingForegroundDispatches += 1;
2479 }
2480}
2481
Jeff Brown519e0242010-09-15 15:18:56 -07002482void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002483 InjectionState* injectionState = entry->injectionState;
2484 if (injectionState) {
2485 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002486
Jeff Brown01ce2e92010-09-26 22:20:12 -07002487 if (injectionState->pendingForegroundDispatches == 0) {
2488 mInjectionSyncFinishedCondition.broadcast();
2489 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002490 }
2491}
2492
Jeff Brown01ce2e92010-09-26 22:20:12 -07002493const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2494 for (size_t i = 0; i < mWindows.size(); i++) {
2495 const InputWindow* window = & mWindows[i];
2496 if (window->inputChannel == inputChannel) {
2497 return window;
2498 }
2499 }
2500 return NULL;
2501}
2502
Jeff Brownb88102f2010-09-08 11:49:43 -07002503void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2504#if DEBUG_FOCUS
2505 LOGD("setInputWindows");
2506#endif
2507 { // acquire lock
2508 AutoMutex _l(mLock);
2509
Jeff Brown01ce2e92010-09-26 22:20:12 -07002510 // Clear old window pointers.
Jeff Brownb6997262010-10-08 22:31:17 -07002511 sp<InputChannel> oldFocusedWindowChannel;
2512 if (mFocusedWindow) {
2513 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2514 mFocusedWindow = NULL;
2515 }
2516
Jeff Brownb88102f2010-09-08 11:49:43 -07002517 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002518
2519 // Loop over new windows and rebuild the necessary window pointers for
2520 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002521 mWindows.appendVector(inputWindows);
2522
2523 size_t numWindows = mWindows.size();
2524 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002525 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002526 if (window->hasFocus) {
2527 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002528 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002529 }
2530 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002531
Jeff Brownb6997262010-10-08 22:31:17 -07002532 if (oldFocusedWindowChannel != NULL) {
2533 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2534#if DEBUG_FOCUS
2535 LOGD("Focus left window: %s",
2536 oldFocusedWindowChannel->getName().string());
2537#endif
2538 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2539 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2540 oldFocusedWindowChannel.clear();
2541 }
2542 }
2543 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2544#if DEBUG_FOCUS
2545 LOGD("Focus entered window: %s",
2546 mFocusedWindow->inputChannel->getName().string());
2547#endif
2548 }
2549
Jeff Brown01ce2e92010-09-26 22:20:12 -07002550 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2551 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2552 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2553 if (window) {
2554 touchedWindow.window = window;
2555 i += 1;
2556 } else {
Jeff Brownb6997262010-10-08 22:31:17 -07002557#if DEBUG_FOCUS
2558 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2559#endif
Jeff Brownb6997262010-10-08 22:31:17 -07002560 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2561 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownaf48cae2010-10-15 16:20:51 -07002562 mTouchState.windows.removeAt(i);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002563 }
2564 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002565
Jeff Brownb88102f2010-09-08 11:49:43 -07002566#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002567 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002568#endif
2569 } // release lock
2570
2571 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002572 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002573}
2574
2575void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2576#if DEBUG_FOCUS
2577 LOGD("setFocusedApplication");
2578#endif
2579 { // acquire lock
2580 AutoMutex _l(mLock);
2581
2582 releaseFocusedApplicationLocked();
2583
2584 if (inputApplication) {
2585 mFocusedApplicationStorage = *inputApplication;
2586 mFocusedApplication = & mFocusedApplicationStorage;
2587 }
2588
2589#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002590 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002591#endif
2592 } // release lock
2593
2594 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002595 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002596}
2597
2598void InputDispatcher::releaseFocusedApplicationLocked() {
2599 if (mFocusedApplication) {
2600 mFocusedApplication = NULL;
2601 mFocusedApplicationStorage.handle.clear();
2602 }
2603}
2604
2605void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2606#if DEBUG_FOCUS
2607 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2608#endif
2609
2610 bool changed;
2611 { // acquire lock
2612 AutoMutex _l(mLock);
2613
2614 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brown120a4592010-10-27 18:43:51 -07002615 if (mDispatchFrozen && !frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002616 resetANRTimeoutsLocked();
2617 }
2618
Jeff Brown120a4592010-10-27 18:43:51 -07002619 if (mDispatchEnabled && !enabled) {
2620 resetAndDropEverythingLocked("dispatcher is being disabled");
2621 }
2622
Jeff Brownb88102f2010-09-08 11:49:43 -07002623 mDispatchEnabled = enabled;
2624 mDispatchFrozen = frozen;
2625 changed = true;
2626 } else {
2627 changed = false;
2628 }
2629
2630#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002631 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002632#endif
2633 } // release lock
2634
2635 if (changed) {
2636 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002637 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002638 }
2639}
2640
Jeff Browne6504122010-09-27 14:52:15 -07002641bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2642 const sp<InputChannel>& toChannel) {
2643#if DEBUG_FOCUS
2644 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2645 fromChannel->getName().string(), toChannel->getName().string());
2646#endif
2647 { // acquire lock
2648 AutoMutex _l(mLock);
2649
2650 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2651 const InputWindow* toWindow = getWindowLocked(toChannel);
2652 if (! fromWindow || ! toWindow) {
2653#if DEBUG_FOCUS
2654 LOGD("Cannot transfer focus because from or to window not found.");
2655#endif
2656 return false;
2657 }
2658 if (fromWindow == toWindow) {
2659#if DEBUG_FOCUS
2660 LOGD("Trivial transfer to same window.");
2661#endif
2662 return true;
2663 }
2664
2665 bool found = false;
2666 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2667 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2668 if (touchedWindow.window == fromWindow) {
2669 int32_t oldTargetFlags = touchedWindow.targetFlags;
2670 BitSet32 pointerIds = touchedWindow.pointerIds;
2671
2672 mTouchState.windows.removeAt(i);
2673
Jeff Brown46e75292010-11-10 16:53:45 -08002674 int32_t newTargetFlags = oldTargetFlags
2675 & (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT);
Jeff Browne6504122010-09-27 14:52:15 -07002676 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2677
2678 found = true;
2679 break;
2680 }
2681 }
2682
2683 if (! found) {
2684#if DEBUG_FOCUS
2685 LOGD("Focus transfer failed because from window did not have focus.");
2686#endif
2687 return false;
2688 }
2689
Jeff Brown9c9f1a32010-10-11 18:32:20 -07002690 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2691 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2692 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2693 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2694 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2695
2696 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2697 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2698 InputState::CANCEL_POINTER_EVENTS,
2699 "transferring touch focus from this window to another window");
2700 }
2701
Jeff Browne6504122010-09-27 14:52:15 -07002702#if DEBUG_FOCUS
2703 logDispatchStateLocked();
2704#endif
2705 } // release lock
2706
2707 // Wake up poll loop since it may need to make new input dispatching choices.
2708 mLooper->wake();
2709 return true;
2710}
2711
Jeff Brown120a4592010-10-27 18:43:51 -07002712void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2713#if DEBUG_FOCUS
2714 LOGD("Resetting and dropping all events (%s).", reason);
2715#endif
2716
2717 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2718
2719 resetKeyRepeatLocked();
2720 releasePendingEventLocked();
2721 drainInboundQueueLocked();
2722 resetTargetsLocked();
2723
2724 mTouchState.reset();
2725}
2726
Jeff Brownb88102f2010-09-08 11:49:43 -07002727void InputDispatcher::logDispatchStateLocked() {
2728 String8 dump;
2729 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002730
2731 char* text = dump.lockBuffer(dump.size());
2732 char* start = text;
2733 while (*start != '\0') {
2734 char* end = strchr(start, '\n');
2735 if (*end == '\n') {
2736 *(end++) = '\0';
2737 }
2738 LOGD("%s", start);
2739 start = end;
2740 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002741}
2742
2743void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002744 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2745 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07002746
2747 if (mFocusedApplication) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002748 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002749 mFocusedApplication->name.string(),
2750 mFocusedApplication->dispatchingTimeout / 1000000.0);
2751 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002752 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002753 }
Jeff Brownf2f487182010-10-01 17:46:21 -07002754 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002755 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f487182010-10-01 17:46:21 -07002756
2757 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2758 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2759 if (!mTouchState.windows.isEmpty()) {
2760 dump.append(INDENT "TouchedWindows:\n");
2761 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2762 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2763 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2764 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2765 touchedWindow.targetFlags);
2766 }
2767 } else {
2768 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002769 }
2770
Jeff Brownf2f487182010-10-01 17:46:21 -07002771 if (!mWindows.isEmpty()) {
2772 dump.append(INDENT "Windows:\n");
2773 for (size_t i = 0; i < mWindows.size(); i++) {
2774 const InputWindow& window = mWindows[i];
2775 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2776 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2777 "frame=[%d,%d][%d,%d], "
2778 "visibleFrame=[%d,%d][%d,%d], "
2779 "touchableArea=[%d,%d][%d,%d], "
2780 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2781 i, window.name.string(),
2782 toString(window.paused),
2783 toString(window.hasFocus),
2784 toString(window.hasWallpaper),
2785 toString(window.visible),
2786 toString(window.canReceiveKeys),
2787 window.layoutParamsFlags, window.layoutParamsType,
2788 window.layer,
2789 window.frameLeft, window.frameTop,
2790 window.frameRight, window.frameBottom,
2791 window.visibleFrameLeft, window.visibleFrameTop,
2792 window.visibleFrameRight, window.visibleFrameBottom,
2793 window.touchableAreaLeft, window.touchableAreaTop,
2794 window.touchableAreaRight, window.touchableAreaBottom,
2795 window.ownerPid, window.ownerUid,
2796 window.dispatchingTimeout / 1000000.0);
2797 }
2798 } else {
2799 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002800 }
2801
Jeff Brownf2f487182010-10-01 17:46:21 -07002802 if (!mMonitoringChannels.isEmpty()) {
2803 dump.append(INDENT "MonitoringChannels:\n");
2804 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2805 const sp<InputChannel>& channel = mMonitoringChannels[i];
2806 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2807 }
2808 } else {
2809 dump.append(INDENT "MonitoringChannels: <none>\n");
2810 }
Jeff Brown519e0242010-09-15 15:18:56 -07002811
Jeff Brownf2f487182010-10-01 17:46:21 -07002812 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2813
2814 if (!mActiveConnections.isEmpty()) {
2815 dump.append(INDENT "ActiveConnections:\n");
2816 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2817 const Connection* connection = mActiveConnections[i];
Jeff Brown76860e32010-10-25 17:37:46 -07002818 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brownb6997262010-10-08 22:31:17 -07002819 "inputState.isNeutral=%s\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07002820 i, connection->getInputChannelName(), connection->getStatusLabel(),
2821 connection->outboundQueue.count(),
Jeff Brownb6997262010-10-08 22:31:17 -07002822 toString(connection->inputState.isNeutral()));
Jeff Brownf2f487182010-10-01 17:46:21 -07002823 }
2824 } else {
2825 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002826 }
2827
2828 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002829 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002830 (mAppSwitchDueTime - now()) / 1000000.0);
2831 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002832 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002833 }
2834}
2835
2836status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002837#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07002838 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2839 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07002840#endif
2841
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002842 { // acquire lock
2843 AutoMutex _l(mLock);
2844
Jeff Brown519e0242010-09-15 15:18:56 -07002845 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002846 LOGW("Attempted to register already registered input channel '%s'",
2847 inputChannel->getName().string());
2848 return BAD_VALUE;
2849 }
2850
2851 sp<Connection> connection = new Connection(inputChannel);
2852 status_t status = connection->initialize();
2853 if (status) {
2854 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2855 inputChannel->getName().string(), status);
2856 return status;
2857 }
2858
Jeff Brown2cbecea2010-08-17 15:59:26 -07002859 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002860 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002861
Jeff Brownb88102f2010-09-08 11:49:43 -07002862 if (monitor) {
2863 mMonitoringChannels.push(inputChannel);
2864 }
2865
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002866 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07002867
Jeff Brown9c3cda02010-06-15 01:31:58 -07002868 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002869 } // release lock
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002870 return OK;
2871}
2872
2873status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002874#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07002875 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07002876#endif
2877
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002878 { // acquire lock
2879 AutoMutex _l(mLock);
2880
Jeff Brown519e0242010-09-15 15:18:56 -07002881 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002882 if (connectionIndex < 0) {
2883 LOGW("Attempted to unregister already unregistered input channel '%s'",
2884 inputChannel->getName().string());
2885 return BAD_VALUE;
2886 }
2887
2888 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2889 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2890
2891 connection->status = Connection::STATUS_ZOMBIE;
2892
Jeff Brownb88102f2010-09-08 11:49:43 -07002893 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2894 if (mMonitoringChannels[i] == inputChannel) {
2895 mMonitoringChannels.removeAt(i);
2896 break;
2897 }
2898 }
2899
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002900 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07002901
Jeff Brown7fbdc842010-06-17 20:52:56 -07002902 nsecs_t currentTime = now();
Jeff Brownb6997262010-10-08 22:31:17 -07002903 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002904
2905 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002906 } // release lock
2907
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002908 // Wake the poll loop because removing the connection may have changed the current
2909 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002910 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002911 return OK;
2912}
2913
Jeff Brown519e0242010-09-15 15:18:56 -07002914ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07002915 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2916 if (connectionIndex >= 0) {
2917 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2918 if (connection->inputChannel.get() == inputChannel.get()) {
2919 return connectionIndex;
2920 }
2921 }
2922
2923 return -1;
2924}
2925
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002926void InputDispatcher::activateConnectionLocked(Connection* connection) {
2927 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2928 if (mActiveConnections.itemAt(i) == connection) {
2929 return;
2930 }
2931 }
2932 mActiveConnections.add(connection);
2933}
2934
2935void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2936 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2937 if (mActiveConnections.itemAt(i) == connection) {
2938 mActiveConnections.removeAt(i);
2939 return;
2940 }
2941 }
2942}
2943
Jeff Brown9c3cda02010-06-15 01:31:58 -07002944void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002945 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002946}
2947
Jeff Brown9c3cda02010-06-15 01:31:58 -07002948void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown3915bb82010-11-05 15:02:16 -07002949 nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
2950 CommandEntry* commandEntry = postCommandLocked(
2951 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
2952 commandEntry->connection = connection;
2953 commandEntry->handled = handled;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002954}
2955
Jeff Brown9c3cda02010-06-15 01:31:58 -07002956void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002957 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002958 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2959 connection->getInputChannelName());
2960
Jeff Brown9c3cda02010-06-15 01:31:58 -07002961 CommandEntry* commandEntry = postCommandLocked(
2962 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002963 commandEntry->connection = connection;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002964}
2965
Jeff Brown519e0242010-09-15 15:18:56 -07002966void InputDispatcher::onANRLocked(
2967 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2968 nsecs_t eventTime, nsecs_t waitStartTime) {
2969 LOGI("Application is not responding: %s. "
2970 "%01.1fms since event, %01.1fms since wait started",
2971 getApplicationWindowLabelLocked(application, window).string(),
2972 (currentTime - eventTime) / 1000000.0,
2973 (currentTime - waitStartTime) / 1000000.0);
2974
2975 CommandEntry* commandEntry = postCommandLocked(
2976 & InputDispatcher::doNotifyANRLockedInterruptible);
2977 if (application) {
2978 commandEntry->inputApplicationHandle = application->handle;
2979 }
2980 if (window) {
2981 commandEntry->inputChannel = window->inputChannel;
2982 }
2983}
2984
Jeff Brownb88102f2010-09-08 11:49:43 -07002985void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2986 CommandEntry* commandEntry) {
2987 mLock.unlock();
2988
2989 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2990
2991 mLock.lock();
2992}
2993
Jeff Brown9c3cda02010-06-15 01:31:58 -07002994void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2995 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002996 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07002997
Jeff Brown7fbdc842010-06-17 20:52:56 -07002998 if (connection->status != Connection::STATUS_ZOMBIE) {
2999 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003000
Jeff Brown7fbdc842010-06-17 20:52:56 -07003001 mPolicy->notifyInputChannelBroken(connection->inputChannel);
3002
3003 mLock.lock();
3004 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07003005}
3006
Jeff Brown519e0242010-09-15 15:18:56 -07003007void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07003008 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07003009 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003010
Jeff Brown519e0242010-09-15 15:18:56 -07003011 nsecs_t newTimeout = mPolicy->notifyANR(
3012 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003013
Jeff Brown519e0242010-09-15 15:18:56 -07003014 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07003015
Jeff Brown519e0242010-09-15 15:18:56 -07003016 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003017}
3018
Jeff Brownb88102f2010-09-08 11:49:43 -07003019void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3020 CommandEntry* commandEntry) {
3021 KeyEntry* entry = commandEntry->keyEntry;
Jeff Brown1f245102010-11-18 20:53:46 -08003022
3023 KeyEvent event;
3024 initializeKeyEvent(&event, entry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003025
3026 mLock.unlock();
3027
3028 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
Jeff Brown1f245102010-11-18 20:53:46 -08003029 &event, entry->policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -07003030
3031 mLock.lock();
3032
3033 entry->interceptKeyResult = consumed
3034 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
3035 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3036 mAllocator.releaseKeyEntry(entry);
3037}
3038
Jeff Brown3915bb82010-11-05 15:02:16 -07003039void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3040 CommandEntry* commandEntry) {
3041 sp<Connection> connection = commandEntry->connection;
3042 bool handled = commandEntry->handled;
3043
Jeff Brown49ed71d2010-12-06 17:13:33 -08003044 if (!connection->outboundQueue.isEmpty()) {
Jeff Brown3915bb82010-11-05 15:02:16 -07003045 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
3046 if (dispatchEntry->inProgress
3047 && dispatchEntry->hasForegroundTarget()
3048 && dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3049 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003050 if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
3051 if (handled) {
3052 // If the application handled a non-fallback key, then immediately
3053 // cancel all fallback keys previously dispatched to the application.
3054 // This behavior will prevent chording with fallback keys (so they cannot
3055 // be used as modifiers) but it will ensure that fallback keys do not
3056 // get stuck. This takes care of the case where the application does not handle
3057 // the original DOWN so we generate a fallback DOWN but it does handle
3058 // the original UP in which case we would not generate the fallback UP.
3059 synthesizeCancelationEventsForConnectionLocked(connection,
3060 InputState::CANCEL_FALLBACK_EVENTS,
Jeff Brown00045a72010-12-09 18:10:30 -08003061 "application handled a non-fallback event, canceling all fallback events");
Jeff Brown49ed71d2010-12-06 17:13:33 -08003062 } else {
3063 // If the application did not handle a non-fallback key, then ask
3064 // the policy what to do with it. We might generate a fallback key
3065 // event here.
3066 KeyEvent event;
3067 initializeKeyEvent(&event, keyEntry);
Jeff Brown3915bb82010-11-05 15:02:16 -07003068
Jeff Brown49ed71d2010-12-06 17:13:33 -08003069 mLock.unlock();
Jeff Brown3915bb82010-11-05 15:02:16 -07003070
Jeff Brown49ed71d2010-12-06 17:13:33 -08003071 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel,
3072 &event, keyEntry->policyFlags, &event);
Jeff Brown3915bb82010-11-05 15:02:16 -07003073
Jeff Brown49ed71d2010-12-06 17:13:33 -08003074 mLock.lock();
3075
Jeff Brown00045a72010-12-09 18:10:30 -08003076 if (connection->status != Connection::STATUS_NORMAL) {
3077 return;
3078 }
3079
3080 assert(connection->outboundQueue.headSentinel.next == dispatchEntry);
3081
Jeff Brown49ed71d2010-12-06 17:13:33 -08003082 if (fallback) {
3083 // Restart the dispatch cycle using the fallback key.
3084 keyEntry->eventTime = event.getEventTime();
3085 keyEntry->deviceId = event.getDeviceId();
3086 keyEntry->source = event.getSource();
3087 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
3088 keyEntry->keyCode = event.getKeyCode();
3089 keyEntry->scanCode = event.getScanCode();
3090 keyEntry->metaState = event.getMetaState();
3091 keyEntry->repeatCount = event.getRepeatCount();
3092 keyEntry->downTime = event.getDownTime();
3093 keyEntry->syntheticRepeat = false;
3094
3095 dispatchEntry->inProgress = false;
3096 startDispatchCycleLocked(now(), connection);
3097 return;
3098 }
3099 }
3100 }
Jeff Brown3915bb82010-11-05 15:02:16 -07003101 }
3102 }
3103
3104 startNextDispatchCycleLocked(now(), connection);
3105}
3106
Jeff Brownb88102f2010-09-08 11:49:43 -07003107void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3108 mLock.unlock();
3109
Jeff Brown01ce2e92010-09-26 22:20:12 -07003110 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07003111
3112 mLock.lock();
3113}
3114
Jeff Brown3915bb82010-11-05 15:02:16 -07003115void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
3116 event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3117 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3118 entry->downTime, entry->eventTime);
3119}
3120
Jeff Brown519e0242010-09-15 15:18:56 -07003121void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3122 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3123 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07003124}
3125
3126void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003127 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003128 dumpDispatchStateLocked(dump);
3129}
3130
Jeff Brown9c3cda02010-06-15 01:31:58 -07003131
Jeff Brown519e0242010-09-15 15:18:56 -07003132// --- InputDispatcher::Queue ---
3133
3134template <typename T>
3135uint32_t InputDispatcher::Queue<T>::count() const {
3136 uint32_t result = 0;
3137 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3138 result += 1;
3139 }
3140 return result;
3141}
3142
3143
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003144// --- InputDispatcher::Allocator ---
3145
3146InputDispatcher::Allocator::Allocator() {
3147}
3148
Jeff Brown01ce2e92010-09-26 22:20:12 -07003149InputDispatcher::InjectionState*
3150InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3151 InjectionState* injectionState = mInjectionStatePool.alloc();
3152 injectionState->refCount = 1;
3153 injectionState->injectorPid = injectorPid;
3154 injectionState->injectorUid = injectorUid;
3155 injectionState->injectionIsAsync = false;
3156 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3157 injectionState->pendingForegroundDispatches = 0;
3158 return injectionState;
3159}
3160
Jeff Brown7fbdc842010-06-17 20:52:56 -07003161void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brownb6997262010-10-08 22:31:17 -07003162 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003163 entry->type = type;
3164 entry->refCount = 1;
3165 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07003166 entry->eventTime = eventTime;
Jeff Brownb6997262010-10-08 22:31:17 -07003167 entry->policyFlags = policyFlags;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003168 entry->injectionState = NULL;
3169}
3170
3171void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3172 if (entry->injectionState) {
3173 releaseInjectionState(entry->injectionState);
3174 entry->injectionState = NULL;
3175 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07003176}
3177
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003178InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07003179InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003180 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003181 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003182 return entry;
3183}
3184
Jeff Brown7fbdc842010-06-17 20:52:56 -07003185InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07003186 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003187 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3188 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003189 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003190 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003191
3192 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003193 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003194 entry->action = action;
3195 entry->flags = flags;
3196 entry->keyCode = keyCode;
3197 entry->scanCode = scanCode;
3198 entry->metaState = metaState;
3199 entry->repeatCount = repeatCount;
3200 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003201 entry->syntheticRepeat = false;
3202 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003203 return entry;
3204}
3205
Jeff Brown7fbdc842010-06-17 20:52:56 -07003206InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07003207 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003208 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3209 nsecs_t downTime, uint32_t pointerCount,
3210 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003211 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003212 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003213
3214 entry->eventTime = eventTime;
3215 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003216 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003217 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07003218 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003219 entry->metaState = metaState;
3220 entry->edgeFlags = edgeFlags;
3221 entry->xPrecision = xPrecision;
3222 entry->yPrecision = yPrecision;
3223 entry->downTime = downTime;
3224 entry->pointerCount = pointerCount;
3225 entry->firstSample.eventTime = eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003226 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003227 entry->lastSample = & entry->firstSample;
3228 for (uint32_t i = 0; i < pointerCount; i++) {
3229 entry->pointerIds[i] = pointerIds[i];
3230 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3231 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003232 return entry;
3233}
3234
3235InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07003236 EventEntry* eventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07003237 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003238 DispatchEntry* entry = mDispatchEntryPool.alloc();
3239 entry->eventEntry = eventEntry;
3240 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07003241 entry->targetFlags = targetFlags;
3242 entry->xOffset = xOffset;
3243 entry->yOffset = yOffset;
Jeff Brownb88102f2010-09-08 11:49:43 -07003244 entry->inProgress = false;
3245 entry->headMotionSample = NULL;
3246 entry->tailMotionSample = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003247 return entry;
3248}
3249
Jeff Brown9c3cda02010-06-15 01:31:58 -07003250InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3251 CommandEntry* entry = mCommandEntryPool.alloc();
3252 entry->command = command;
3253 return entry;
3254}
3255
Jeff Brown01ce2e92010-09-26 22:20:12 -07003256void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3257 injectionState->refCount -= 1;
3258 if (injectionState->refCount == 0) {
3259 mInjectionStatePool.free(injectionState);
3260 } else {
3261 assert(injectionState->refCount > 0);
3262 }
3263}
3264
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003265void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3266 switch (entry->type) {
3267 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3268 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3269 break;
3270 case EventEntry::TYPE_KEY:
3271 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3272 break;
3273 case EventEntry::TYPE_MOTION:
3274 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3275 break;
3276 default:
3277 assert(false);
3278 break;
3279 }
3280}
3281
3282void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3283 ConfigurationChangedEntry* entry) {
3284 entry->refCount -= 1;
3285 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003286 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003287 mConfigurationChangeEntryPool.free(entry);
3288 } else {
3289 assert(entry->refCount > 0);
3290 }
3291}
3292
3293void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3294 entry->refCount -= 1;
3295 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003296 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003297 mKeyEntryPool.free(entry);
3298 } else {
3299 assert(entry->refCount > 0);
3300 }
3301}
3302
3303void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3304 entry->refCount -= 1;
3305 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003306 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003307 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3308 MotionSample* next = sample->next;
3309 mMotionSamplePool.free(sample);
3310 sample = next;
3311 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003312 mMotionEntryPool.free(entry);
3313 } else {
3314 assert(entry->refCount > 0);
3315 }
3316}
3317
3318void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3319 releaseEventEntry(entry->eventEntry);
3320 mDispatchEntryPool.free(entry);
3321}
3322
Jeff Brown9c3cda02010-06-15 01:31:58 -07003323void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3324 mCommandEntryPool.free(entry);
3325}
3326
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003327void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003328 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003329 MotionSample* sample = mMotionSamplePool.alloc();
3330 sample->eventTime = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003331 uint32_t pointerCount = motionEntry->pointerCount;
3332 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003333 sample->pointerCoords[i] = pointerCoords[i];
3334 }
3335
3336 sample->next = NULL;
3337 motionEntry->lastSample->next = sample;
3338 motionEntry->lastSample = sample;
3339}
3340
Jeff Brown01ce2e92010-09-26 22:20:12 -07003341void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3342 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003343
Jeff Brown01ce2e92010-09-26 22:20:12 -07003344 keyEntry->dispatchInProgress = false;
3345 keyEntry->syntheticRepeat = false;
3346 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003347}
3348
3349
Jeff Brownae9fc032010-08-18 15:51:08 -07003350// --- InputDispatcher::MotionEntry ---
3351
3352uint32_t InputDispatcher::MotionEntry::countSamples() const {
3353 uint32_t count = 1;
3354 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3355 count += 1;
3356 }
3357 return count;
3358}
3359
Jeff Brownb88102f2010-09-08 11:49:43 -07003360
3361// --- InputDispatcher::InputState ---
3362
Jeff Brownb6997262010-10-08 22:31:17 -07003363InputDispatcher::InputState::InputState() {
Jeff Brownb88102f2010-09-08 11:49:43 -07003364}
3365
3366InputDispatcher::InputState::~InputState() {
3367}
3368
3369bool InputDispatcher::InputState::isNeutral() const {
3370 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3371}
3372
Jeff Brownb88102f2010-09-08 11:49:43 -07003373InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3374 const EventEntry* entry) {
3375 switch (entry->type) {
3376 case EventEntry::TYPE_KEY:
3377 return trackKey(static_cast<const KeyEntry*>(entry));
3378
3379 case EventEntry::TYPE_MOTION:
3380 return trackMotion(static_cast<const MotionEntry*>(entry));
3381
3382 default:
3383 return CONSISTENT;
3384 }
3385}
3386
3387InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3388 const KeyEntry* entry) {
3389 int32_t action = entry->action;
3390 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3391 KeyMemento& memento = mKeyMementos.editItemAt(i);
3392 if (memento.deviceId == entry->deviceId
3393 && memento.source == entry->source
3394 && memento.keyCode == entry->keyCode
3395 && memento.scanCode == entry->scanCode) {
3396 switch (action) {
3397 case AKEY_EVENT_ACTION_UP:
3398 mKeyMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003399 return CONSISTENT;
3400
3401 case AKEY_EVENT_ACTION_DOWN:
3402 return TOLERABLE;
3403
3404 default:
3405 return BROKEN;
3406 }
3407 }
3408 }
3409
3410 switch (action) {
3411 case AKEY_EVENT_ACTION_DOWN: {
3412 mKeyMementos.push();
3413 KeyMemento& memento = mKeyMementos.editTop();
3414 memento.deviceId = entry->deviceId;
3415 memento.source = entry->source;
3416 memento.keyCode = entry->keyCode;
3417 memento.scanCode = entry->scanCode;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003418 memento.flags = entry->flags;
Jeff Brownb88102f2010-09-08 11:49:43 -07003419 memento.downTime = entry->downTime;
3420 return CONSISTENT;
3421 }
3422
3423 default:
3424 return BROKEN;
3425 }
3426}
3427
3428InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3429 const MotionEntry* entry) {
3430 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3431 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3432 MotionMemento& memento = mMotionMementos.editItemAt(i);
3433 if (memento.deviceId == entry->deviceId
3434 && memento.source == entry->source) {
3435 switch (action) {
3436 case AMOTION_EVENT_ACTION_UP:
3437 case AMOTION_EVENT_ACTION_CANCEL:
3438 mMotionMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003439 return CONSISTENT;
3440
3441 case AMOTION_EVENT_ACTION_DOWN:
3442 return TOLERABLE;
3443
3444 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3445 if (entry->pointerCount == memento.pointerCount + 1) {
3446 memento.setPointers(entry);
3447 return CONSISTENT;
3448 }
3449 return BROKEN;
3450
3451 case AMOTION_EVENT_ACTION_POINTER_UP:
3452 if (entry->pointerCount == memento.pointerCount - 1) {
3453 memento.setPointers(entry);
3454 return CONSISTENT;
3455 }
3456 return BROKEN;
3457
3458 case AMOTION_EVENT_ACTION_MOVE:
3459 if (entry->pointerCount == memento.pointerCount) {
3460 return CONSISTENT;
3461 }
3462 return BROKEN;
3463
3464 default:
3465 return BROKEN;
3466 }
3467 }
3468 }
3469
3470 switch (action) {
3471 case AMOTION_EVENT_ACTION_DOWN: {
3472 mMotionMementos.push();
3473 MotionMemento& memento = mMotionMementos.editTop();
3474 memento.deviceId = entry->deviceId;
3475 memento.source = entry->source;
3476 memento.xPrecision = entry->xPrecision;
3477 memento.yPrecision = entry->yPrecision;
3478 memento.downTime = entry->downTime;
3479 memento.setPointers(entry);
3480 return CONSISTENT;
3481 }
3482
3483 default:
3484 return BROKEN;
3485 }
3486}
3487
3488void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3489 pointerCount = entry->pointerCount;
3490 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3491 pointerIds[i] = entry->pointerIds[i];
3492 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3493 }
3494}
3495
Jeff Brownb6997262010-10-08 22:31:17 -07003496void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3497 Allocator* allocator, Vector<EventEntry*>& outEvents,
3498 CancelationOptions options) {
3499 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003500 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003501 if (shouldCancelKey(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003502 outEvents.push(allocator->obtainKeyEntry(currentTime,
3503 memento.deviceId, memento.source, 0,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003504 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
Jeff Brownb6997262010-10-08 22:31:17 -07003505 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3506 mKeyMementos.removeAt(i);
3507 } else {
3508 i += 1;
3509 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003510 }
3511
Jeff Browna1160a72010-10-11 18:22:53 -07003512 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003513 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003514 if (shouldCancelMotion(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003515 outEvents.push(allocator->obtainMotionEntry(currentTime,
3516 memento.deviceId, memento.source, 0,
3517 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3518 memento.xPrecision, memento.yPrecision, memento.downTime,
3519 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3520 mMotionMementos.removeAt(i);
3521 } else {
3522 i += 1;
3523 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003524 }
3525}
3526
3527void InputDispatcher::InputState::clear() {
3528 mKeyMementos.clear();
3529 mMotionMementos.clear();
Jeff Brownb6997262010-10-08 22:31:17 -07003530}
3531
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003532void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3533 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3534 const MotionMemento& memento = mMotionMementos.itemAt(i);
3535 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3536 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3537 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3538 if (memento.deviceId == otherMemento.deviceId
3539 && memento.source == otherMemento.source) {
3540 other.mMotionMementos.removeAt(j);
3541 } else {
3542 j += 1;
3543 }
3544 }
3545 other.mMotionMementos.push(memento);
3546 }
3547 }
3548}
3549
Jeff Brown49ed71d2010-12-06 17:13:33 -08003550bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
Jeff Brownb6997262010-10-08 22:31:17 -07003551 CancelationOptions options) {
3552 switch (options) {
Jeff Brown49ed71d2010-12-06 17:13:33 -08003553 case CANCEL_ALL_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003554 case CANCEL_NON_POINTER_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003555 return true;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003556 case CANCEL_FALLBACK_EVENTS:
3557 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
3558 default:
3559 return false;
3560 }
3561}
3562
3563bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
3564 CancelationOptions options) {
3565 switch (options) {
3566 case CANCEL_ALL_EVENTS:
3567 return true;
3568 case CANCEL_POINTER_EVENTS:
3569 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
3570 case CANCEL_NON_POINTER_EVENTS:
3571 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
3572 default:
3573 return false;
Jeff Brownb6997262010-10-08 22:31:17 -07003574 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003575}
3576
3577
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003578// --- InputDispatcher::Connection ---
3579
3580InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3581 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown519e0242010-09-15 15:18:56 -07003582 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003583}
3584
3585InputDispatcher::Connection::~Connection() {
3586}
3587
3588status_t InputDispatcher::Connection::initialize() {
3589 return inputPublisher.initialize();
3590}
3591
Jeff Brown9c3cda02010-06-15 01:31:58 -07003592const char* InputDispatcher::Connection::getStatusLabel() const {
3593 switch (status) {
3594 case STATUS_NORMAL:
3595 return "NORMAL";
3596
3597 case STATUS_BROKEN:
3598 return "BROKEN";
3599
Jeff Brown9c3cda02010-06-15 01:31:58 -07003600 case STATUS_ZOMBIE:
3601 return "ZOMBIE";
3602
3603 default:
3604 return "UNKNOWN";
3605 }
3606}
3607
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003608InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3609 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07003610 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3611 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003612 if (dispatchEntry->eventEntry == eventEntry) {
3613 return dispatchEntry;
3614 }
3615 }
3616 return NULL;
3617}
3618
Jeff Brownb88102f2010-09-08 11:49:43 -07003619
Jeff Brown9c3cda02010-06-15 01:31:58 -07003620// --- InputDispatcher::CommandEntry ---
3621
Jeff Brownb88102f2010-09-08 11:49:43 -07003622InputDispatcher::CommandEntry::CommandEntry() :
3623 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003624}
3625
3626InputDispatcher::CommandEntry::~CommandEntry() {
3627}
3628
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003629
Jeff Brown01ce2e92010-09-26 22:20:12 -07003630// --- InputDispatcher::TouchState ---
3631
3632InputDispatcher::TouchState::TouchState() :
3633 down(false), split(false) {
3634}
3635
3636InputDispatcher::TouchState::~TouchState() {
3637}
3638
3639void InputDispatcher::TouchState::reset() {
3640 down = false;
3641 split = false;
3642 windows.clear();
3643}
3644
3645void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3646 down = other.down;
3647 split = other.split;
3648 windows.clear();
3649 windows.appendVector(other.windows);
3650}
3651
3652void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3653 int32_t targetFlags, BitSet32 pointerIds) {
3654 if (targetFlags & InputTarget::FLAG_SPLIT) {
3655 split = true;
3656 }
3657
3658 for (size_t i = 0; i < windows.size(); i++) {
3659 TouchedWindow& touchedWindow = windows.editItemAt(i);
3660 if (touchedWindow.window == window) {
3661 touchedWindow.targetFlags |= targetFlags;
3662 touchedWindow.pointerIds.value |= pointerIds.value;
3663 return;
3664 }
3665 }
3666
3667 windows.push();
3668
3669 TouchedWindow& touchedWindow = windows.editTop();
3670 touchedWindow.window = window;
3671 touchedWindow.targetFlags = targetFlags;
3672 touchedWindow.pointerIds = pointerIds;
3673 touchedWindow.channel = window->inputChannel;
3674}
3675
3676void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3677 for (size_t i = 0 ; i < windows.size(); ) {
3678 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3679 windows.removeAt(i);
3680 } else {
3681 i += 1;
3682 }
3683 }
3684}
3685
3686const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3687 for (size_t i = 0; i < windows.size(); i++) {
3688 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3689 return windows[i].window;
3690 }
3691 }
3692 return NULL;
3693}
3694
3695
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003696// --- InputDispatcherThread ---
3697
3698InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3699 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3700}
3701
3702InputDispatcherThread::~InputDispatcherThread() {
3703}
3704
3705bool InputDispatcherThread::threadLoop() {
3706 mDispatcher->dispatchOnce();
3707 return true;
3708}
3709
3710} // namespace android