blob: 7ddb3c75ee2c260f082d510bb45ad2188010ae6a [file] [log] [blame]
Jeff Browne839a582010-04-22 18:58:52 -07001//
2// Copyright 2010 The Android Open Source Project
3//
4// The input dispatcher.
5//
6#define LOG_TAG "InputDispatcher"
7
8//#define LOG_NDEBUG 0
9
10// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown50de30a2010-06-22 01:27:15 -070011#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Browne839a582010-04-22 18:58:52 -070012
13// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown50de30a2010-06-22 01:27:15 -070014#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Browne839a582010-04-22 18:58:52 -070015
16// Log debug messages about batching.
Jeff Brown50de30a2010-06-22 01:27:15 -070017#define DEBUG_BATCHING 0
Jeff Browne839a582010-04-22 18:58:52 -070018
19// Log debug messages about the dispatch cycle.
Jeff Brown50de30a2010-06-22 01:27:15 -070020#define DEBUG_DISPATCH_CYCLE 0
Jeff Browne839a582010-04-22 18:58:52 -070021
Jeff Brown54bc2812010-06-15 01:31:58 -070022// Log debug messages about registrations.
Jeff Brown50de30a2010-06-22 01:27:15 -070023#define DEBUG_REGISTRATION 0
Jeff Brown54bc2812010-06-15 01:31:58 -070024
Jeff Browne839a582010-04-22 18:58:52 -070025// Log debug messages about performance statistics.
Jeff Brown50de30a2010-06-22 01:27:15 -070026#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Browne839a582010-04-22 18:58:52 -070027
Jeff Brown51d45a72010-06-17 20:52:56 -070028// Log debug messages about input event injection.
Jeff Brown50de30a2010-06-22 01:27:15 -070029#define DEBUG_INJECTION 0
Jeff Brown51d45a72010-06-17 20:52:56 -070030
Jeff Brown542412c2010-08-18 15:51:08 -070031// Log debug messages about input event throttling.
32#define DEBUG_THROTTLING 0
33
Jeff Browna665ca82010-09-08 11:49:43 -070034// Log debug messages about input focus tracking.
35#define DEBUG_FOCUS 0
36
37// Log debug messages about the app switch latency optimization.
38#define DEBUG_APP_SWITCH 0
39
Jeff Browne839a582010-04-22 18:58:52 -070040#include <cutils/log.h>
41#include <ui/InputDispatcher.h>
Jeff Browna665ca82010-09-08 11:49:43 -070042#include <ui/PowerManager.h>
Jeff Browne839a582010-04-22 18:58:52 -070043
44#include <stddef.h>
45#include <unistd.h>
Jeff Browne839a582010-04-22 18:58:52 -070046#include <errno.h>
47#include <limits.h>
Jeff Browne839a582010-04-22 18:58:52 -070048
Jeff Brown2806e382010-10-01 17:46:21 -070049#define INDENT " "
50#define INDENT2 " "
51
Jeff Browne839a582010-04-22 18:58:52 -070052namespace android {
53
Jeff Browna665ca82010-09-08 11:49:43 -070054// 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 Browne839a582010-04-22 18:58:52 -070063
Jeff Brown51d45a72010-06-17 20:52:56 -070064static inline nsecs_t now() {
65 return systemTime(SYSTEM_TIME_MONOTONIC);
66}
67
Jeff Browna665ca82010-09-08 11:49:43 -070068static inline const char* toString(bool value) {
69 return value ? "true" : "false";
70}
71
Jeff Brownd1b0a2b2010-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 Brown90f0cee2010-10-08 22:31:17 -070095static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brownd1b0a2b2010-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 Brownd1b0a2b2010-09-26 22:20:12 -0700101 case AMOTION_EVENT_ACTION_OUTSIDE:
102 return true;
Jeff Brown90f0cee2010-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 Brownd1b0a2b2010-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 Brown90f0cee2010-10-08 22:31:17 -0700115 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brownd1b0a2b2010-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 Brown3c3cc622010-10-20 15:33:38 -0700124 BitSet32 pointerIdBits;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700125 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brown3c3cc622010-10-20 15:33:38 -0700126 int32_t id = pointerIds[i];
127 if (id < 0 || id > MAX_POINTER_ID) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700128 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
Jeff Brown3c3cc622010-10-20 15:33:38 -0700129 id, MAX_POINTER_ID);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700130 return false;
131 }
Jeff Brown3c3cc622010-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 Brownd1b0a2b2010-09-26 22:20:12 -0700137 }
138 return true;
139}
140
Jeff Browna665ca82010-09-08 11:49:43 -0700141
142// --- InputWindow ---
143
Jeff Browna665ca82010-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 Brown35cf0e92010-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 Browne68d9e02010-10-15 00:54:27 -0700156 || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
157 || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
Jeff Brown35cf0e92010-10-05 12:26:23 -0700158}
159
Jeff Browna665ca82010-09-08 11:49:43 -0700160
Jeff Browne839a582010-04-22 18:58:52 -0700161// --- InputDispatcher ---
162
Jeff Brown54bc2812010-06-15 01:31:58 -0700163InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Browna665ca82010-09-08 11:49:43 -0700164 mPolicy(policy),
165 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
166 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700167 mFocusedWindow(NULL),
Jeff Browna665ca82010-09-08 11:49:43 -0700168 mFocusedApplication(NULL),
169 mCurrentInputTargetsValid(false),
170 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown59abe7e2010-09-13 23:17:30 -0700171 mLooper = new Looper(false);
Jeff Browne839a582010-04-22 18:58:52 -0700172
Jeff Browna665ca82010-09-08 11:49:43 -0700173 mInboundQueue.headSentinel.refCount = -1;
174 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
175 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Browne839a582010-04-22 18:58:52 -0700176
Jeff Browna665ca82010-09-08 11:49:43 -0700177 mInboundQueue.tailSentinel.refCount = -1;
178 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
179 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Browne839a582010-04-22 18:58:52 -0700180
181 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown54bc2812010-06-15 01:31:58 -0700182
Jeff Brown542412c2010-08-18 15:51:08 -0700183 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
184 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
185 mThrottleState.lastDeviceId = -1;
186
187#if DEBUG_THROTTLING
188 mThrottleState.originalSampleCount = 0;
189 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
190#endif
Jeff Browne839a582010-04-22 18:58:52 -0700191}
192
193InputDispatcher::~InputDispatcher() {
Jeff Browna665ca82010-09-08 11:49:43 -0700194 { // acquire lock
195 AutoMutex _l(mLock);
196
197 resetKeyRepeatLocked();
Jeff Brownd8816c32010-09-16 14:07:33 -0700198 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700199 drainInboundQueueLocked();
200 }
Jeff Browne839a582010-04-22 18:58:52 -0700201
202 while (mConnectionsByReceiveFd.size() != 0) {
203 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
204 }
Jeff Browne839a582010-04-22 18:58:52 -0700205}
206
207void InputDispatcher::dispatchOnce() {
Jeff Brown54bc2812010-06-15 01:31:58 -0700208 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brown61ce3982010-09-07 10:44:57 -0700209 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Browne839a582010-04-22 18:58:52 -0700210
Jeff Browne839a582010-04-22 18:58:52 -0700211 nsecs_t nextWakeupTime = LONG_LONG_MAX;
212 { // acquire lock
213 AutoMutex _l(mLock);
Jeff Browna665ca82010-09-08 11:49:43 -0700214 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Browne839a582010-04-22 18:58:52 -0700215
Jeff Browna665ca82010-09-08 11:49:43 -0700216 if (runCommandsLockedInterruptible()) {
217 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Browne839a582010-04-22 18:58:52 -0700218 }
Jeff Browne839a582010-04-22 18:58:52 -0700219 } // release lock
220
Jeff Browna665ca82010-09-08 11:49:43 -0700221 // Wait for callback or timeout or wake. (make sure we round up, not down)
222 nsecs_t currentTime = now();
223 int32_t timeoutMillis;
224 if (nextWakeupTime > currentTime) {
225 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
226 timeout = (timeout + 999999LL) / 1000000LL;
227 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
228 } else {
229 timeoutMillis = 0;
230 }
231
Jeff Brown59abe7e2010-09-13 23:17:30 -0700232 mLooper->pollOnce(timeoutMillis);
Jeff Browna665ca82010-09-08 11:49:43 -0700233}
234
235void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
236 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
237 nsecs_t currentTime = now();
238
239 // Reset the key repeat timer whenever we disallow key events, even if the next event
240 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
241 // out of sleep.
242 if (keyRepeatTimeout < 0) {
243 resetKeyRepeatLocked();
244 }
245
Jeff Browna665ca82010-09-08 11:49:43 -0700246 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
247 if (mDispatchFrozen) {
248#if DEBUG_FOCUS
249 LOGD("Dispatch frozen. Waiting some more.");
250#endif
251 return;
252 }
253
254 // Optimize latency of app switches.
255 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
256 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
257 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
258 if (mAppSwitchDueTime < *nextWakeupTime) {
259 *nextWakeupTime = mAppSwitchDueTime;
260 }
261
Jeff Browna665ca82010-09-08 11:49:43 -0700262 // Ready to start a new event.
263 // If we don't already have a pending event, go grab one.
264 if (! mPendingEvent) {
265 if (mInboundQueue.isEmpty()) {
266 if (isAppSwitchDue) {
267 // The inbound queue is empty so the app switch key we were waiting
268 // for will never arrive. Stop waiting for it.
269 resetPendingAppSwitchLocked(false);
270 isAppSwitchDue = false;
271 }
272
273 // Synthesize a key repeat if appropriate.
274 if (mKeyRepeatState.lastKeyEntry) {
275 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
276 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
277 } else {
278 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
279 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
280 }
281 }
282 }
283 if (! mPendingEvent) {
284 return;
285 }
286 } else {
287 // Inbound queue has at least one entry.
288 EventEntry* entry = mInboundQueue.headSentinel.next;
289
290 // Throttle the entry if it is a move event and there are no
291 // other events behind it in the queue. Due to movement batching, additional
292 // samples may be appended to this event by the time the throttling timeout
293 // expires.
294 // TODO Make this smarter and consider throttling per device independently.
Jeff Brown90f0cee2010-10-08 22:31:17 -0700295 if (entry->type == EventEntry::TYPE_MOTION
296 && !isAppSwitchDue
297 && mDispatchEnabled
298 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
299 && !entry->isInjected()) {
Jeff Browna665ca82010-09-08 11:49:43 -0700300 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
301 int32_t deviceId = motionEntry->deviceId;
302 uint32_t source = motionEntry->source;
303 if (! isAppSwitchDue
304 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
305 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
306 && deviceId == mThrottleState.lastDeviceId
307 && source == mThrottleState.lastSource) {
308 nsecs_t nextTime = mThrottleState.lastEventTime
309 + mThrottleState.minTimeBetweenEvents;
310 if (currentTime < nextTime) {
311 // Throttle it!
312#if DEBUG_THROTTLING
313 LOGD("Throttling - Delaying motion event for "
314 "device 0x%x, source 0x%08x by up to %0.3fms.",
315 deviceId, source, (nextTime - currentTime) * 0.000001);
316#endif
317 if (nextTime < *nextWakeupTime) {
318 *nextWakeupTime = nextTime;
319 }
320 if (mThrottleState.originalSampleCount == 0) {
321 mThrottleState.originalSampleCount =
322 motionEntry->countSamples();
323 }
324 return;
325 }
326 }
327
328#if DEBUG_THROTTLING
329 if (mThrottleState.originalSampleCount != 0) {
330 uint32_t count = motionEntry->countSamples();
331 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
332 count - mThrottleState.originalSampleCount,
333 mThrottleState.originalSampleCount, count);
334 mThrottleState.originalSampleCount = 0;
335 }
336#endif
337
338 mThrottleState.lastEventTime = entry->eventTime < currentTime
339 ? entry->eventTime : currentTime;
340 mThrottleState.lastDeviceId = deviceId;
341 mThrottleState.lastSource = source;
342 }
343
344 mInboundQueue.dequeue(entry);
345 mPendingEvent = entry;
346 }
Jeff Brownef3a8232010-10-18 13:21:23 -0700347
348 // Poke user activity for this event.
349 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
350 pokeUserActivityLocked(mPendingEvent);
351 }
Jeff Browna665ca82010-09-08 11:49:43 -0700352 }
353
354 // Now we have an event to dispatch.
355 assert(mPendingEvent != NULL);
Jeff Brownd8816c32010-09-16 14:07:33 -0700356 bool done = false;
Jeff Brown90f0cee2010-10-08 22:31:17 -0700357 DropReason dropReason = DROP_REASON_NOT_DROPPED;
358 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
359 dropReason = DROP_REASON_POLICY;
360 } else if (!mDispatchEnabled) {
361 dropReason = DROP_REASON_DISABLED;
362 }
Jeff Browna665ca82010-09-08 11:49:43 -0700363 switch (mPendingEvent->type) {
364 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
365 ConfigurationChangedEntry* typedEntry =
366 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brownd8816c32010-09-16 14:07:33 -0700367 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700368 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Browna665ca82010-09-08 11:49:43 -0700369 break;
370 }
371
372 case EventEntry::TYPE_KEY: {
373 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700374 if (isAppSwitchDue) {
375 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700376 resetPendingAppSwitchLocked(true);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700377 isAppSwitchDue = false;
378 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
379 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700380 }
381 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700382 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Brown33d54ce2010-10-11 14:20:19 -0700383 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700384 break;
385 }
386
387 case EventEntry::TYPE_MOTION: {
388 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700389 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
390 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700391 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700392 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Brown33d54ce2010-10-11 14:20:19 -0700393 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700394 break;
395 }
396
397 default:
398 assert(false);
Jeff Browna665ca82010-09-08 11:49:43 -0700399 break;
400 }
401
Jeff Brownd8816c32010-09-16 14:07:33 -0700402 if (done) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700403 if (dropReason != DROP_REASON_NOT_DROPPED) {
404 dropInboundEventLocked(mPendingEvent, dropReason);
405 }
406
Jeff Brownd8816c32010-09-16 14:07:33 -0700407 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700408 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
409 }
410}
411
412bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
413 bool needWake = mInboundQueue.isEmpty();
414 mInboundQueue.enqueueAtTail(entry);
415
416 switch (entry->type) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700417 case EventEntry::TYPE_KEY: {
418 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
419 if (isAppSwitchKeyEventLocked(keyEntry)) {
420 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
421 mAppSwitchSawKeyDown = true;
422 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
423 if (mAppSwitchSawKeyDown) {
424#if DEBUG_APP_SWITCH
425 LOGD("App switch is pending!");
426#endif
427 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
428 mAppSwitchSawKeyDown = false;
429 needWake = true;
430 }
431 }
432 }
Jeff Browna665ca82010-09-08 11:49:43 -0700433 break;
434 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700435 }
Jeff Browna665ca82010-09-08 11:49:43 -0700436
437 return needWake;
438}
439
Jeff Brown90f0cee2010-10-08 22:31:17 -0700440void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
441 const char* reason;
442 switch (dropReason) {
443 case DROP_REASON_POLICY:
Jeff Brown33d54ce2010-10-11 14:20:19 -0700444#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Browna8ed8562010-10-11 23:32:49 -0700445 LOGD("Dropped event because policy consumed it.");
Jeff Brown33d54ce2010-10-11 14:20:19 -0700446#endif
Jeff Browna8ed8562010-10-11 23:32:49 -0700447 reason = "inbound event was dropped because the policy consumed it";
Jeff Brown90f0cee2010-10-08 22:31:17 -0700448 break;
449 case DROP_REASON_DISABLED:
450 LOGI("Dropped event because input dispatch is disabled.");
451 reason = "inbound event was dropped because input dispatch is disabled";
452 break;
453 case DROP_REASON_APP_SWITCH:
454 LOGI("Dropped event because of pending overdue app switch.");
455 reason = "inbound event was dropped because of pending overdue app switch";
456 break;
457 default:
458 assert(false);
459 return;
460 }
461
462 switch (entry->type) {
463 case EventEntry::TYPE_KEY:
464 synthesizeCancelationEventsForAllConnectionsLocked(
465 InputState::CANCEL_NON_POINTER_EVENTS, reason);
466 break;
467 case EventEntry::TYPE_MOTION: {
468 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
469 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
470 synthesizeCancelationEventsForAllConnectionsLocked(
471 InputState::CANCEL_POINTER_EVENTS, reason);
472 } else {
473 synthesizeCancelationEventsForAllConnectionsLocked(
474 InputState::CANCEL_NON_POINTER_EVENTS, reason);
475 }
476 break;
477 }
478 }
479}
480
481bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Browna665ca82010-09-08 11:49:43 -0700482 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
483}
484
Jeff Brown90f0cee2010-10-08 22:31:17 -0700485bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
486 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
487 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Brown33d54ce2010-10-11 14:20:19 -0700488 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brown90f0cee2010-10-08 22:31:17 -0700489 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
490}
491
Jeff Browna665ca82010-09-08 11:49:43 -0700492bool InputDispatcher::isAppSwitchPendingLocked() {
493 return mAppSwitchDueTime != LONG_LONG_MAX;
494}
495
Jeff Browna665ca82010-09-08 11:49:43 -0700496void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
497 mAppSwitchDueTime = LONG_LONG_MAX;
498
499#if DEBUG_APP_SWITCH
500 if (handled) {
501 LOGD("App switch has arrived.");
502 } else {
503 LOGD("App switch was abandoned.");
504 }
505#endif
Jeff Browne839a582010-04-22 18:58:52 -0700506}
507
Jeff Brown54bc2812010-06-15 01:31:58 -0700508bool InputDispatcher::runCommandsLockedInterruptible() {
509 if (mCommandQueue.isEmpty()) {
510 return false;
511 }
Jeff Browne839a582010-04-22 18:58:52 -0700512
Jeff Brown54bc2812010-06-15 01:31:58 -0700513 do {
514 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
515
516 Command command = commandEntry->command;
517 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
518
Jeff Brown51d45a72010-06-17 20:52:56 -0700519 commandEntry->connection.clear();
Jeff Brown54bc2812010-06-15 01:31:58 -0700520 mAllocator.releaseCommandEntry(commandEntry);
521 } while (! mCommandQueue.isEmpty());
522 return true;
Jeff Browne839a582010-04-22 18:58:52 -0700523}
524
Jeff Brown54bc2812010-06-15 01:31:58 -0700525InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
526 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
527 mCommandQueue.enqueueAtTail(commandEntry);
528 return commandEntry;
529}
530
Jeff Browna665ca82010-09-08 11:49:43 -0700531void InputDispatcher::drainInboundQueueLocked() {
532 while (! mInboundQueue.isEmpty()) {
533 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brownd8816c32010-09-16 14:07:33 -0700534 releaseInboundEventLocked(entry);
Jeff Browne839a582010-04-22 18:58:52 -0700535 }
Jeff Browne839a582010-04-22 18:58:52 -0700536}
537
Jeff Brownd8816c32010-09-16 14:07:33 -0700538void InputDispatcher::releasePendingEventLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700539 if (mPendingEvent) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700540 releaseInboundEventLocked(mPendingEvent);
Jeff Browna665ca82010-09-08 11:49:43 -0700541 mPendingEvent = NULL;
542 }
543}
544
Jeff Brownd8816c32010-09-16 14:07:33 -0700545void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700546 InjectionState* injectionState = entry->injectionState;
547 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Browna665ca82010-09-08 11:49:43 -0700548#if DEBUG_DISPATCH_CYCLE
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700549 LOGD("Injected inbound event was dropped.");
Jeff Browna665ca82010-09-08 11:49:43 -0700550#endif
551 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
552 }
553 mAllocator.releaseEventEntry(entry);
554}
555
Jeff Browna665ca82010-09-08 11:49:43 -0700556void InputDispatcher::resetKeyRepeatLocked() {
557 if (mKeyRepeatState.lastKeyEntry) {
558 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
559 mKeyRepeatState.lastKeyEntry = NULL;
560 }
561}
562
563InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brown61ce3982010-09-07 10:44:57 -0700564 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown50de30a2010-06-22 01:27:15 -0700565 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
566
Jeff Brown50de30a2010-06-22 01:27:15 -0700567 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown33d54ce2010-10-11 14:20:19 -0700568 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
569 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Browne839a582010-04-22 18:58:52 -0700570 if (entry->refCount == 1) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700571 mAllocator.recycleKeyEntry(entry);
Jeff Brown51d45a72010-06-17 20:52:56 -0700572 entry->eventTime = currentTime;
Jeff Brown51d45a72010-06-17 20:52:56 -0700573 entry->policyFlags = policyFlags;
Jeff Browne839a582010-04-22 18:58:52 -0700574 entry->repeatCount += 1;
575 } else {
Jeff Brown51d45a72010-06-17 20:52:56 -0700576 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700577 entry->deviceId, entry->source, policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700578 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brownf16c26d2010-07-02 15:37:36 -0700579 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Browne839a582010-04-22 18:58:52 -0700580
581 mKeyRepeatState.lastKeyEntry = newEntry;
582 mAllocator.releaseKeyEntry(entry);
583
584 entry = newEntry;
585 }
Jeff Browna665ca82010-09-08 11:49:43 -0700586 entry->syntheticRepeat = true;
587
588 // Increment reference count since we keep a reference to the event in
589 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
590 entry->refCount += 1;
Jeff Browne839a582010-04-22 18:58:52 -0700591
Jeff Brownf16c26d2010-07-02 15:37:36 -0700592 if (entry->repeatCount == 1) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700593 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brownf16c26d2010-07-02 15:37:36 -0700594 }
595
Jeff Brown61ce3982010-09-07 10:44:57 -0700596 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Browna665ca82010-09-08 11:49:43 -0700597 return entry;
Jeff Browne839a582010-04-22 18:58:52 -0700598}
599
Jeff Browna665ca82010-09-08 11:49:43 -0700600bool InputDispatcher::dispatchConfigurationChangedLocked(
601 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Browne839a582010-04-22 18:58:52 -0700602#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Browna665ca82010-09-08 11:49:43 -0700603 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
604#endif
605
606 // Reset key repeating in case a keyboard device was added or removed or something.
607 resetKeyRepeatLocked();
608
609 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
610 CommandEntry* commandEntry = postCommandLocked(
611 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
612 commandEntry->eventTime = entry->eventTime;
613 return true;
614}
615
616bool InputDispatcher::dispatchKeyLocked(
617 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brown33d54ce2010-10-11 14:20:19 -0700618 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brown92988aa2010-11-02 17:58:22 -0700619 // Preprocessing.
620 if (! entry->dispatchInProgress) {
621 if (entry->repeatCount == 0
622 && entry->action == AKEY_EVENT_ACTION_DOWN
623 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
624 && !entry->isInjected()) {
625 if (mKeyRepeatState.lastKeyEntry
626 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
627 // We have seen two identical key downs in a row which indicates that the device
628 // driver is automatically generating key repeats itself. We take note of the
629 // repeat here, but we disable our own next key repeat timer since it is clear that
630 // we will not need to synthesize key repeats ourselves.
631 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
632 resetKeyRepeatLocked();
633 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
634 } else {
635 // Not a repeat. Save key down state in case we do see a repeat later.
636 resetKeyRepeatLocked();
637 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
638 }
639 mKeyRepeatState.lastKeyEntry = entry;
640 entry->refCount += 1;
641 } else if (! entry->syntheticRepeat) {
642 resetKeyRepeatLocked();
643 }
644
645 entry->dispatchInProgress = true;
646 resetTargetsLocked();
647
648 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
649 }
650
Jeff Brownd8816c32010-09-16 14:07:33 -0700651 // Give the policy a chance to intercept the key.
652 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Brown33d54ce2010-10-11 14:20:19 -0700653 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700654 CommandEntry* commandEntry = postCommandLocked(
655 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Brown33d54ce2010-10-11 14:20:19 -0700656 if (mFocusedWindow) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700657 commandEntry->inputChannel = mFocusedWindow->inputChannel;
658 }
659 commandEntry->keyEntry = entry;
660 entry->refCount += 1;
661 return false; // wait for the command to run
662 } else {
663 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
664 }
665 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Brown33d54ce2010-10-11 14:20:19 -0700666 if (*dropReason == DROP_REASON_NOT_DROPPED) {
667 *dropReason = DROP_REASON_POLICY;
668 }
Jeff Brownd8816c32010-09-16 14:07:33 -0700669 }
670
671 // Clean up if dropping the event.
Jeff Brown33d54ce2010-10-11 14:20:19 -0700672 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700673 resetTargetsLocked();
Jeff Browna8ed8562010-10-11 23:32:49 -0700674 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
675 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brownd8816c32010-09-16 14:07:33 -0700676 return true;
677 }
678
Jeff Browna665ca82010-09-08 11:49:43 -0700679 // Identify targets.
680 if (! mCurrentInputTargetsValid) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700681 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
682 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700683 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
684 return false;
685 }
686
687 setInjectionResultLocked(entry, injectionResult);
688 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
689 return true;
690 }
691
692 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700693 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700694 }
695
696 // Dispatch the key.
697 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Browna665ca82010-09-08 11:49:43 -0700698 return true;
699}
700
701void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
702#if DEBUG_OUTBOUND_EVENT_DETAILS
703 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
704 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
Jeff Brown92988aa2010-11-02 17:58:22 -0700705 "repeatCount=%d, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700706 prefix,
707 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
708 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Jeff Brown92988aa2010-11-02 17:58:22 -0700709 entry->repeatCount, entry->downTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700710#endif
711}
712
713bool InputDispatcher::dispatchMotionLocked(
Jeff Brown33d54ce2010-10-11 14:20:19 -0700714 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brown92988aa2010-11-02 17:58:22 -0700715 // Preprocessing.
716 if (! entry->dispatchInProgress) {
717 entry->dispatchInProgress = true;
718 resetTargetsLocked();
719
720 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
721 }
722
Jeff Brownd8816c32010-09-16 14:07:33 -0700723 // Clean up if dropping the event.
Jeff Brown33d54ce2010-10-11 14:20:19 -0700724 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700725 resetTargetsLocked();
Jeff Browna8ed8562010-10-11 23:32:49 -0700726 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
727 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brownd8816c32010-09-16 14:07:33 -0700728 return true;
729 }
730
Jeff Browna665ca82010-09-08 11:49:43 -0700731 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
732
733 // Identify targets.
734 if (! mCurrentInputTargetsValid) {
Jeff Browna665ca82010-09-08 11:49:43 -0700735 int32_t injectionResult;
736 if (isPointerEvent) {
737 // Pointer event. (eg. touchscreen)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700738 injectionResult = findTouchedWindowTargetsLocked(currentTime,
739 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700740 } else {
741 // Non touch event. (eg. trackball)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700742 injectionResult = findFocusedWindowTargetsLocked(currentTime,
743 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700744 }
745 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
746 return false;
747 }
748
749 setInjectionResultLocked(entry, injectionResult);
750 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
751 return true;
752 }
753
754 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700755 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700756 }
757
758 // Dispatch the motion.
759 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Browna665ca82010-09-08 11:49:43 -0700760 return true;
761}
762
763
764void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
765#if DEBUG_OUTBOUND_EVENT_DETAILS
766 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700767 "action=0x%x, flags=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700768 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700769 prefix,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700770 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
771 entry->action, entry->flags,
Jeff Browne839a582010-04-22 18:58:52 -0700772 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
773 entry->downTime);
774
775 // Print the most recent sample that we have available, this may change due to batching.
776 size_t sampleCount = 1;
Jeff Browna665ca82010-09-08 11:49:43 -0700777 const MotionSample* sample = & entry->firstSample;
Jeff Browne839a582010-04-22 18:58:52 -0700778 for (; sample->next != NULL; sample = sample->next) {
779 sampleCount += 1;
780 }
781 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -0700782 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700783 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -0700784 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -0700785 i, entry->pointerIds[i],
Jeff Brown38a7fab2010-08-30 03:02:23 -0700786 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
787 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
788 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
789 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
790 sample->pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -0700791 }
792
793 // Keep in mind that due to batching, it is possible for the number of samples actually
794 // dispatched to change before the application finally consumed them.
Jeff Brown5c1ed842010-07-14 18:48:53 -0700795 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -0700796 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
797 }
798#endif
Jeff Browne839a582010-04-22 18:58:52 -0700799}
800
801void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
802 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
803#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700804 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700805 "resumeWithAppendedMotionSample=%s",
Jeff Browna665ca82010-09-08 11:49:43 -0700806 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -0700807#endif
808
Jeff Brown54bc2812010-06-15 01:31:58 -0700809 assert(eventEntry->dispatchInProgress); // should already have been set to true
810
Jeff Brownef3a8232010-10-18 13:21:23 -0700811 pokeUserActivityLocked(eventEntry);
812
Jeff Browne839a582010-04-22 18:58:52 -0700813 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
814 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
815
Jeff Brown53a415e2010-09-15 15:18:56 -0700816 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -0700817 if (connectionIndex >= 0) {
818 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown51d45a72010-06-17 20:52:56 -0700819 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -0700820 resumeWithAppendedMotionSample);
821 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700822#if DEBUG_FOCUS
823 LOGD("Dropping event delivery to target with channel '%s' because it "
824 "is no longer registered with the input dispatcher.",
Jeff Browne839a582010-04-22 18:58:52 -0700825 inputTarget.inputChannel->getName().string());
Jeff Brown90f0cee2010-10-08 22:31:17 -0700826#endif
Jeff Browne839a582010-04-22 18:58:52 -0700827 }
828 }
829}
830
Jeff Brownd8816c32010-09-16 14:07:33 -0700831void InputDispatcher::resetTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700832 mCurrentInputTargetsValid = false;
833 mCurrentInputTargets.clear();
Jeff Browna665ca82010-09-08 11:49:43 -0700834 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
835}
836
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700837void InputDispatcher::commitTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700838 mCurrentInputTargetsValid = true;
839}
840
841int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
842 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
843 nsecs_t* nextWakeupTime) {
844 if (application == NULL && window == NULL) {
845 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
846#if DEBUG_FOCUS
847 LOGD("Waiting for system to become ready for input.");
848#endif
849 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
850 mInputTargetWaitStartTime = currentTime;
851 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
852 mInputTargetWaitTimeoutExpired = false;
853 }
854 } else {
855 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
856#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700857 LOGD("Waiting for application to become ready for input: %s",
858 getApplicationWindowLabelLocked(application, window).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700859#endif
860 nsecs_t timeout = window ? window->dispatchingTimeout :
861 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
862
863 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
864 mInputTargetWaitStartTime = currentTime;
865 mInputTargetWaitTimeoutTime = currentTime + timeout;
866 mInputTargetWaitTimeoutExpired = false;
867 }
868 }
869
870 if (mInputTargetWaitTimeoutExpired) {
871 return INPUT_EVENT_INJECTION_TIMED_OUT;
872 }
873
874 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown53a415e2010-09-15 15:18:56 -0700875 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700876
877 // Force poll loop to wake up immediately on next iteration once we get the
878 // ANR response back from the policy.
879 *nextWakeupTime = LONG_LONG_MIN;
880 return INPUT_EVENT_INJECTION_PENDING;
881 } else {
882 // Force poll loop to wake up when timeout is due.
883 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
884 *nextWakeupTime = mInputTargetWaitTimeoutTime;
885 }
886 return INPUT_EVENT_INJECTION_PENDING;
887 }
888}
889
Jeff Brown53a415e2010-09-15 15:18:56 -0700890void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
891 const sp<InputChannel>& inputChannel) {
Jeff Browna665ca82010-09-08 11:49:43 -0700892 if (newTimeout > 0) {
893 // Extend the timeout.
894 mInputTargetWaitTimeoutTime = now() + newTimeout;
895 } else {
896 // Give up.
897 mInputTargetWaitTimeoutExpired = true;
Jeff Brown53a415e2010-09-15 15:18:56 -0700898
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700899 // Release the touch targets.
900 mTouchState.reset();
Jeff Brown405a1d32010-09-16 12:31:46 -0700901
Jeff Brown53a415e2010-09-15 15:18:56 -0700902 // Input state will not be realistic. Mark it out of sync.
Jeff Brown40ad4702010-09-16 11:02:16 -0700903 if (inputChannel.get()) {
904 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
905 if (connectionIndex >= 0) {
906 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700907 synthesizeCancelationEventsForConnectionLocked(
908 connection, InputState::CANCEL_ALL_EVENTS,
909 "application not responding");
Jeff Brown40ad4702010-09-16 11:02:16 -0700910 }
Jeff Brown53a415e2010-09-15 15:18:56 -0700911 }
Jeff Browna665ca82010-09-08 11:49:43 -0700912 }
913}
914
Jeff Brown53a415e2010-09-15 15:18:56 -0700915nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Browna665ca82010-09-08 11:49:43 -0700916 nsecs_t currentTime) {
917 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
918 return currentTime - mInputTargetWaitStartTime;
919 }
920 return 0;
921}
922
923void InputDispatcher::resetANRTimeoutsLocked() {
924#if DEBUG_FOCUS
925 LOGD("Resetting ANR timeouts.");
926#endif
927
Jeff Browna665ca82010-09-08 11:49:43 -0700928 // Reset input target wait timeout.
929 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
930}
931
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700932int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
933 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -0700934 mCurrentInputTargets.clear();
935
936 int32_t injectionResult;
937
938 // If there is no currently focused window and no focused application
939 // then drop the event.
940 if (! mFocusedWindow) {
941 if (mFocusedApplication) {
942#if DEBUG_FOCUS
943 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -0700944 "focused application that may eventually add a window: %s.",
945 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700946#endif
947 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
948 mFocusedApplication, NULL, nextWakeupTime);
949 goto Unresponsive;
950 }
951
952 LOGI("Dropping event because there is no focused window or focused application.");
953 injectionResult = INPUT_EVENT_INJECTION_FAILED;
954 goto Failed;
955 }
956
957 // Check permissions.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700958 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700959 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
960 goto Failed;
961 }
962
963 // If the currently focused window is paused then keep waiting.
964 if (mFocusedWindow->paused) {
965#if DEBUG_FOCUS
966 LOGD("Waiting because focused window is paused.");
967#endif
968 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
969 mFocusedApplication, mFocusedWindow, nextWakeupTime);
970 goto Unresponsive;
971 }
972
Jeff Brown53a415e2010-09-15 15:18:56 -0700973 // If the currently focused window is still working on previous events then keep waiting.
974 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
975#if DEBUG_FOCUS
976 LOGD("Waiting because focused window still processing previous input.");
977#endif
978 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
979 mFocusedApplication, mFocusedWindow, nextWakeupTime);
980 goto Unresponsive;
981 }
982
Jeff Browna665ca82010-09-08 11:49:43 -0700983 // Success! Output targets.
984 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700985 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -0700986
987 // Done.
988Failed:
989Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -0700990 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
991 updateDispatchStatisticsLocked(currentTime, entry,
992 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -0700993#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700994 LOGD("findFocusedWindow finished: injectionResult=%d, "
995 "timeSpendWaitingForApplication=%0.1fms",
996 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -0700997#endif
998 return injectionResult;
999}
1000
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001001int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1002 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -07001003 enum InjectionPermission {
1004 INJECTION_PERMISSION_UNKNOWN,
1005 INJECTION_PERMISSION_GRANTED,
1006 INJECTION_PERMISSION_DENIED
1007 };
1008
Jeff Browna665ca82010-09-08 11:49:43 -07001009 mCurrentInputTargets.clear();
1010
1011 nsecs_t startTime = now();
1012
1013 // For security reasons, we defer updating the touch state until we are sure that
1014 // event injection will be allowed.
1015 //
1016 // FIXME In the original code, screenWasOff could never be set to true.
1017 // The reason is that the POLICY_FLAG_WOKE_HERE
1018 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1019 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1020 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1021 // events upon which no preprocessing took place. So policyFlags was always 0.
1022 // In the new native input dispatcher we're a bit more careful about event
1023 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1024 // Unfortunately we obtain undesirable behavior.
1025 //
1026 // Here's what happens:
1027 //
1028 // When the device dims in anticipation of going to sleep, touches
1029 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1030 // the device to brighten and reset the user activity timer.
1031 // Touches on other windows (such as the launcher window)
1032 // are dropped. Then after a moment, the device goes to sleep. Oops.
1033 //
1034 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1035 // instead of POLICY_FLAG_WOKE_HERE...
1036 //
1037 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1038
1039 int32_t action = entry->action;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001040 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Browna665ca82010-09-08 11:49:43 -07001041
1042 // Update the touch state as needed based on the properties of the touch event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001043 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1044 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1045 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1046 mTempTouchState.reset();
1047 mTempTouchState.down = true;
1048 } else {
1049 mTempTouchState.copyFrom(mTouchState);
1050 }
Jeff Browna665ca82010-09-08 11:49:43 -07001051
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001052 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1053 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1054 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1055 /* Case 1: New splittable pointer going down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001056
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001057 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1058 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1059 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1060 const InputWindow* newTouchedWindow = NULL;
1061 const InputWindow* topErrorWindow = NULL;
Jeff Browna665ca82010-09-08 11:49:43 -07001062
1063 // Traverse windows from front to back to find touched window and outside targets.
1064 size_t numWindows = mWindows.size();
1065 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001066 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07001067 int32_t flags = window->layoutParamsFlags;
1068
1069 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1070 if (! topErrorWindow) {
1071 topErrorWindow = window;
1072 }
1073 }
1074
1075 if (window->visible) {
1076 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1077 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1078 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1079 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1080 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1081 newTouchedWindow = window;
Jeff Browna665ca82010-09-08 11:49:43 -07001082 }
1083 break; // found touched window, exit window loop
1084 }
1085 }
1086
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001087 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1088 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001089 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1090 if (isWindowObscuredAtPointLocked(window, x, y)) {
1091 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1092 }
1093
1094 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -07001095 }
1096 }
1097 }
1098
1099 // If there is an error window but it is not taking focus (typically because
1100 // it is invisible) then wait for it. Any other focused window may in
1101 // fact be in ANR state.
1102 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1103#if DEBUG_FOCUS
1104 LOGD("Waiting because system error window is pending.");
1105#endif
1106 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1107 NULL, NULL, nextWakeupTime);
1108 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1109 goto Unresponsive;
1110 }
1111
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001112 // Figure out whether splitting will be allowed for this window.
Jeff Brown3c2450f2010-09-28 13:24:41 -07001113 if (newTouchedWindow
1114 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001115 // New window supports splitting.
1116 isSplit = true;
1117 } else if (isSplit) {
1118 // New window does not support splitting but we have already split events.
1119 // Assign the pointer to the first foreground window we find.
1120 // (May be NULL which is why we put this code block before the next check.)
1121 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1122 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001123
Jeff Browna665ca82010-09-08 11:49:43 -07001124 // If we did not find a touched window then fail.
1125 if (! newTouchedWindow) {
1126 if (mFocusedApplication) {
1127#if DEBUG_FOCUS
1128 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -07001129 "focused application that may eventually add a new window: %s.",
1130 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -07001131#endif
1132 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1133 mFocusedApplication, NULL, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -07001134 goto Unresponsive;
1135 }
1136
1137 LOGI("Dropping event because there is no touched window or focused application.");
1138 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001139 goto Failed;
1140 }
1141
Jeff Brown35cf0e92010-10-05 12:26:23 -07001142 // Set target flags.
1143 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1144 if (isSplit) {
1145 targetFlags |= InputTarget::FLAG_SPLIT;
1146 }
1147 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1148 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1149 }
1150
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001151 // Update the temporary touch state.
1152 BitSet32 pointerIds;
1153 if (isSplit) {
1154 uint32_t pointerId = entry->pointerIds[pointerIndex];
1155 pointerIds.markBit(pointerId);
Jeff Browna665ca82010-09-08 11:49:43 -07001156 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001157 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001158 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001159 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001160
1161 // If the pointer is not currently down, then ignore the event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001162 if (! mTempTouchState.down) {
Jeff Brown53f291e2010-10-25 17:37:46 -07001163#if DEBUG_INPUT_DISPATCHER_POLICY
1164 LOGD("Dropping event because the pointer is not down or we previously "
1165 "dropped the pointer down event.");
1166#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001167 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001168 goto Failed;
1169 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001170 }
Jeff Browna665ca82010-09-08 11:49:43 -07001171
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001172 // Check permission to inject into all touched foreground windows and ensure there
1173 // is at least one touched foreground window.
1174 {
1175 bool haveForegroundWindow = false;
1176 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1177 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1178 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1179 haveForegroundWindow = true;
1180 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1181 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1182 injectionPermission = INJECTION_PERMISSION_DENIED;
1183 goto Failed;
1184 }
1185 }
1186 }
1187 if (! haveForegroundWindow) {
Jeff Browna665ca82010-09-08 11:49:43 -07001188#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001189 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Browna665ca82010-09-08 11:49:43 -07001190#endif
1191 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001192 goto Failed;
1193 }
1194
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001195 // Permission granted to injection into all touched foreground windows.
1196 injectionPermission = INJECTION_PERMISSION_GRANTED;
1197 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001198
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001199 // Ensure all touched foreground windows are ready for new input.
1200 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1201 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1202 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1203 // If the touched window is paused then keep waiting.
1204 if (touchedWindow.window->paused) {
1205#if DEBUG_INPUT_DISPATCHER_POLICY
1206 LOGD("Waiting because touched window is paused.");
Jeff Brown53a415e2010-09-15 15:18:56 -07001207#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001208 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1209 NULL, touchedWindow.window, nextWakeupTime);
1210 goto Unresponsive;
1211 }
1212
1213 // If the touched window is still working on previous events then keep waiting.
1214 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1215#if DEBUG_FOCUS
1216 LOGD("Waiting because touched window still processing previous input.");
1217#endif
1218 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1219 NULL, touchedWindow.window, nextWakeupTime);
1220 goto Unresponsive;
1221 }
1222 }
1223 }
1224
1225 // If this is the first pointer going down and the touched window has a wallpaper
1226 // then also add the touched wallpaper windows so they are locked in for the duration
1227 // of the touch gesture.
1228 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1229 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1230 if (foregroundWindow->hasWallpaper) {
1231 for (size_t i = 0; i < mWindows.size(); i++) {
1232 const InputWindow* window = & mWindows[i];
1233 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001234 mTempTouchState.addOrUpdateWindow(window,
1235 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001236 }
1237 }
1238 }
1239 }
1240
Jeff Browna665ca82010-09-08 11:49:43 -07001241 // Success! Output targets.
1242 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Browna665ca82010-09-08 11:49:43 -07001243
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001244 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1245 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1246 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1247 touchedWindow.pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001248 }
1249
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001250 // Drop the outside touch window since we will not care about them in the next iteration.
1251 mTempTouchState.removeOutsideTouchWindows();
1252
Jeff Browna665ca82010-09-08 11:49:43 -07001253Failed:
1254 // Check injection permission once and for all.
1255 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001256 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001257 injectionPermission = INJECTION_PERMISSION_GRANTED;
1258 } else {
1259 injectionPermission = INJECTION_PERMISSION_DENIED;
1260 }
1261 }
1262
1263 // Update final pieces of touch state if the injector had permission.
1264 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001265 if (maskedAction == AMOTION_EVENT_ACTION_UP
1266 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1267 // All pointers up or canceled.
1268 mTempTouchState.reset();
1269 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1270 // First pointer went down.
1271 if (mTouchState.down) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001272#if DEBUG_FOCUS
1273 LOGD("Pointer down received while already down.");
1274#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001275 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001276 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1277 // One pointer went up.
1278 if (isSplit) {
1279 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1280 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Browna665ca82010-09-08 11:49:43 -07001281
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001282 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1283 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1284 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1285 touchedWindow.pointerIds.clearBit(pointerId);
1286 if (touchedWindow.pointerIds.isEmpty()) {
1287 mTempTouchState.windows.removeAt(i);
1288 continue;
1289 }
1290 }
1291 i += 1;
1292 }
Jeff Browna665ca82010-09-08 11:49:43 -07001293 }
Jeff Browna665ca82010-09-08 11:49:43 -07001294 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001295
1296 // Save changes to touch state.
1297 mTouchState.copyFrom(mTempTouchState);
Jeff Browna665ca82010-09-08 11:49:43 -07001298 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001299#if DEBUG_FOCUS
1300 LOGD("Not updating touch focus because injection was denied.");
1301#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001302 }
1303
1304Unresponsive:
Jeff Brownfef5b042010-10-27 18:43:51 -07001305 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1306 mTempTouchState.reset();
1307
Jeff Brown53a415e2010-09-15 15:18:56 -07001308 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1309 updateDispatchStatisticsLocked(currentTime, entry,
1310 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001311#if DEBUG_FOCUS
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001312 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1313 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown53a415e2010-09-15 15:18:56 -07001314 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001315#endif
1316 return injectionResult;
1317}
1318
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001319void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1320 BitSet32 pointerIds) {
Jeff Browna665ca82010-09-08 11:49:43 -07001321 mCurrentInputTargets.push();
1322
1323 InputTarget& target = mCurrentInputTargets.editTop();
1324 target.inputChannel = window->inputChannel;
1325 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001326 target.xOffset = - window->frameLeft;
1327 target.yOffset = - window->frameTop;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001328 target.pointerIds = pointerIds;
Jeff Browna665ca82010-09-08 11:49:43 -07001329}
1330
1331void InputDispatcher::addMonitoringTargetsLocked() {
1332 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1333 mCurrentInputTargets.push();
1334
1335 InputTarget& target = mCurrentInputTargets.editTop();
1336 target.inputChannel = mMonitoringChannels[i];
1337 target.flags = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07001338 target.xOffset = 0;
1339 target.yOffset = 0;
1340 }
1341}
1342
1343bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001344 const InjectionState* injectionState) {
1345 if (injectionState
Jeff Brown90f0cee2010-10-08 22:31:17 -07001346 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1347 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1348 if (window) {
1349 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1350 "with input channel %s owned by uid %d",
1351 injectionState->injectorPid, injectionState->injectorUid,
1352 window->inputChannel->getName().string(),
1353 window->ownerUid);
1354 } else {
1355 LOGW("Permission denied: injecting event from pid %d uid %d",
1356 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-09-08 11:49:43 -07001357 }
Jeff Brown90f0cee2010-10-08 22:31:17 -07001358 return false;
Jeff Browna665ca82010-09-08 11:49:43 -07001359 }
1360 return true;
1361}
1362
Jeff Brown35cf0e92010-10-05 12:26:23 -07001363bool InputDispatcher::isWindowObscuredAtPointLocked(
1364 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Browna665ca82010-09-08 11:49:43 -07001365 size_t numWindows = mWindows.size();
1366 for (size_t i = 0; i < numWindows; i++) {
1367 const InputWindow* other = & mWindows.itemAt(i);
1368 if (other == window) {
1369 break;
1370 }
Jeff Brown35cf0e92010-10-05 12:26:23 -07001371 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001372 return true;
1373 }
1374 }
1375 return false;
1376}
1377
Jeff Brown53a415e2010-09-15 15:18:56 -07001378bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1379 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1380 if (connectionIndex >= 0) {
1381 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1382 return connection->outboundQueue.isEmpty();
1383 } else {
1384 return true;
1385 }
1386}
1387
1388String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1389 const InputWindow* window) {
1390 if (application) {
1391 if (window) {
1392 String8 label(application->name);
1393 label.append(" - ");
1394 label.append(window->name);
1395 return label;
1396 } else {
1397 return application->name;
1398 }
1399 } else if (window) {
1400 return window->name;
1401 } else {
1402 return String8("<unknown application or window>");
1403 }
1404}
1405
Jeff Brownef3a8232010-10-18 13:21:23 -07001406void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1407 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brownfd749c62010-10-29 21:50:21 -07001408 switch (eventEntry->type) {
1409 case EventEntry::TYPE_MOTION: {
Jeff Brownef3a8232010-10-18 13:21:23 -07001410 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Brownfd749c62010-10-29 21:50:21 -07001411 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1412 return;
1413 }
1414
Jeff Brownef3a8232010-10-18 13:21:23 -07001415 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
Joe Onoratod94206c2010-11-08 09:48:20 -08001416 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001417 }
Jeff Brownfd749c62010-10-29 21:50:21 -07001418 break;
1419 }
1420 case EventEntry::TYPE_KEY: {
1421 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1422 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1423 return;
1424 }
1425 break;
1426 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001427 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001428
Jeff Browna665ca82010-09-08 11:49:43 -07001429 CommandEntry* commandEntry = postCommandLocked(
1430 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Brownef3a8232010-10-18 13:21:23 -07001431 commandEntry->eventTime = eventEntry->eventTime;
Jeff Browna665ca82010-09-08 11:49:43 -07001432 commandEntry->userActivityEventType = eventType;
1433}
1434
Jeff Brown51d45a72010-06-17 20:52:56 -07001435void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1436 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -07001437 bool resumeWithAppendedMotionSample) {
1438#if DEBUG_DISPATCH_CYCLE
Jeff Brown53a415e2010-09-15 15:18:56 -07001439 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001440 "xOffset=%f, yOffset=%f, "
1441 "windowType=%d, pointerIds=0x%x, "
1442 "resumeWithAppendedMotionSample=%s",
Jeff Brown53a415e2010-09-15 15:18:56 -07001443 connection->getInputChannelName(), inputTarget->flags,
Jeff Browne839a582010-04-22 18:58:52 -07001444 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001445 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Browna665ca82010-09-08 11:49:43 -07001446 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -07001447#endif
1448
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001449 // Make sure we are never called for streaming when splitting across multiple windows.
1450 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1451 assert(! (resumeWithAppendedMotionSample && isSplit));
1452
Jeff Browne839a582010-04-22 18:58:52 -07001453 // Skip this event if the connection status is not normal.
Jeff Brown53a415e2010-09-15 15:18:56 -07001454 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Browne839a582010-04-22 18:58:52 -07001455 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001456#if DEBUG_DISPATCH_CYCLE
1457 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Browna665ca82010-09-08 11:49:43 -07001458 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown90f0cee2010-10-08 22:31:17 -07001459#endif
Jeff Browne839a582010-04-22 18:58:52 -07001460 return;
1461 }
1462
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001463 // Split a motion event if needed.
1464 if (isSplit) {
1465 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1466
1467 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1468 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1469 MotionEntry* splitMotionEntry = splitMotionEvent(
1470 originalMotionEntry, inputTarget->pointerIds);
1471#if DEBUG_FOCUS
1472 LOGD("channel '%s' ~ Split motion event.",
1473 connection->getInputChannelName());
1474 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1475#endif
1476 eventEntry = splitMotionEntry;
1477 }
1478 }
1479
Jeff Browne839a582010-04-22 18:58:52 -07001480 // Resume the dispatch cycle with a freshly appended motion sample.
1481 // First we check that the last dispatch entry in the outbound queue is for the same
1482 // motion event to which we appended the motion sample. If we find such a dispatch
1483 // entry, and if it is currently in progress then we try to stream the new sample.
1484 bool wasEmpty = connection->outboundQueue.isEmpty();
1485
1486 if (! wasEmpty && resumeWithAppendedMotionSample) {
1487 DispatchEntry* motionEventDispatchEntry =
1488 connection->findQueuedDispatchEntryForEvent(eventEntry);
1489 if (motionEventDispatchEntry) {
1490 // If the dispatch entry is not in progress, then we must be busy dispatching an
1491 // earlier event. Not a problem, the motion event is on the outbound queue and will
1492 // be dispatched later.
1493 if (! motionEventDispatchEntry->inProgress) {
1494#if DEBUG_BATCHING
1495 LOGD("channel '%s' ~ Not streaming because the motion event has "
1496 "not yet been dispatched. "
1497 "(Waiting for earlier events to be consumed.)",
1498 connection->getInputChannelName());
1499#endif
1500 return;
1501 }
1502
1503 // If the dispatch entry is in progress but it already has a tail of pending
1504 // motion samples, then it must mean that the shared memory buffer filled up.
1505 // Not a problem, when this dispatch cycle is finished, we will eventually start
1506 // a new dispatch cycle to process the tail and that tail includes the newly
1507 // appended motion sample.
1508 if (motionEventDispatchEntry->tailMotionSample) {
1509#if DEBUG_BATCHING
1510 LOGD("channel '%s' ~ Not streaming because no new samples can "
1511 "be appended to the motion event in this dispatch cycle. "
1512 "(Waiting for next dispatch cycle to start.)",
1513 connection->getInputChannelName());
1514#endif
1515 return;
1516 }
1517
1518 // The dispatch entry is in progress and is still potentially open for streaming.
1519 // Try to stream the new motion sample. This might fail if the consumer has already
1520 // consumed the motion event (or if the channel is broken).
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001521 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1522 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Browne839a582010-04-22 18:58:52 -07001523 status_t status = connection->inputPublisher.appendMotionSample(
1524 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1525 if (status == OK) {
1526#if DEBUG_BATCHING
1527 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1528 connection->getInputChannelName());
1529#endif
1530 return;
1531 }
1532
1533#if DEBUG_BATCHING
1534 if (status == NO_MEMORY) {
1535 LOGD("channel '%s' ~ Could not append motion sample to currently "
1536 "dispatched move event because the shared memory buffer is full. "
1537 "(Waiting for next dispatch cycle to start.)",
1538 connection->getInputChannelName());
1539 } else if (status == status_t(FAILED_TRANSACTION)) {
1540 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown50de30a2010-06-22 01:27:15 -07001541 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-04-22 18:58:52 -07001542 "(Waiting for next dispatch cycle to start.)",
1543 connection->getInputChannelName());
1544 } else {
1545 LOGD("channel '%s' ~ Could not append motion sample to currently "
1546 "dispatched move event due to an error, status=%d. "
1547 "(Waiting for next dispatch cycle to start.)",
1548 connection->getInputChannelName(), status);
1549 }
1550#endif
1551 // Failed to stream. Start a new tail of pending motion samples to dispatch
1552 // in the next cycle.
1553 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1554 return;
1555 }
1556 }
1557
1558 // This is a new event.
1559 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Browna665ca82010-09-08 11:49:43 -07001560 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown53a415e2010-09-15 15:18:56 -07001561 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1562 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001563 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001564 }
1565
Jeff Browne839a582010-04-22 18:58:52 -07001566 // Handle the case where we could not stream a new motion sample because the consumer has
1567 // already consumed the motion event (otherwise the corresponding dispatch entry would
1568 // still be in the outbound queue for this connection). We set the head motion sample
1569 // to the list starting with the newly appended motion sample.
1570 if (resumeWithAppendedMotionSample) {
1571#if DEBUG_BATCHING
1572 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1573 "that cannot be streamed because the motion event has already been consumed.",
1574 connection->getInputChannelName());
1575#endif
1576 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1577 dispatchEntry->headMotionSample = appendedMotionSample;
1578 }
1579
1580 // Enqueue the dispatch entry.
1581 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1582
1583 // If the outbound queue was previously empty, start the dispatch cycle going.
1584 if (wasEmpty) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001585 activateConnectionLocked(connection.get());
Jeff Brown53a415e2010-09-15 15:18:56 -07001586 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001587 }
1588}
1589
Jeff Brown51d45a72010-06-17 20:52:56 -07001590void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown53a415e2010-09-15 15:18:56 -07001591 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001592#if DEBUG_DISPATCH_CYCLE
1593 LOGD("channel '%s' ~ startDispatchCycle",
1594 connection->getInputChannelName());
1595#endif
1596
1597 assert(connection->status == Connection::STATUS_NORMAL);
1598 assert(! connection->outboundQueue.isEmpty());
1599
Jeff Browna665ca82010-09-08 11:49:43 -07001600 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001601 assert(! dispatchEntry->inProgress);
1602
Jeff Browna665ca82010-09-08 11:49:43 -07001603 // Mark the dispatch entry as in progress.
1604 dispatchEntry->inProgress = true;
1605
1606 // Update the connection's input state.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001607 EventEntry* eventEntry = dispatchEntry->eventEntry;
1608 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001609
1610#if FILTER_INPUT_EVENTS
1611 // Filter out inconsistent sequences of input events.
1612 // The input system may drop or inject events in a way that could violate implicit
1613 // invariants on input state and potentially cause an application to crash
1614 // or think that a key or pointer is stuck down. Technically we make no guarantees
1615 // of consistency but it would be nice to improve on this where possible.
1616 // XXX: This code is a proof of concept only. Not ready for prime time.
1617 if (consistency == InputState::TOLERABLE) {
1618#if DEBUG_DISPATCH_CYCLE
1619 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1620 "current input state but that is likely to be tolerated by the application.",
1621 connection->getInputChannelName());
1622#endif
1623 } else if (consistency == InputState::BROKEN) {
1624 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1625 "current input state and that is likely to cause the application to crash.",
1626 connection->getInputChannelName());
1627 startNextDispatchCycleLocked(currentTime, connection);
1628 return;
1629 }
1630#endif
Jeff Browne839a582010-04-22 18:58:52 -07001631
1632 // Publish the event.
1633 status_t status;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001634 switch (eventEntry->type) {
Jeff Browne839a582010-04-22 18:58:52 -07001635 case EventEntry::TYPE_KEY: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001636 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001637
1638 // Apply target flags.
1639 int32_t action = keyEntry->action;
1640 int32_t flags = keyEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001641
1642 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001643 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-04-22 18:58:52 -07001644 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1645 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1646 keyEntry->eventTime);
1647
1648 if (status) {
1649 LOGE("channel '%s' ~ Could not publish key event, "
1650 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001651 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001652 return;
1653 }
1654 break;
1655 }
1656
1657 case EventEntry::TYPE_MOTION: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001658 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001659
1660 // Apply target flags.
1661 int32_t action = motionEntry->action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07001662 int32_t flags = motionEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001663 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001664 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -07001665 }
Jeff Brownaf30ff62010-09-01 17:01:00 -07001666 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1667 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1668 }
Jeff Browne839a582010-04-22 18:58:52 -07001669
1670 // If headMotionSample is non-NULL, then it points to the first new sample that we
1671 // were unable to dispatch during the previous cycle so we resume dispatching from
1672 // that point in the list of motion samples.
1673 // Otherwise, we just start from the first sample of the motion event.
1674 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1675 if (! firstMotionSample) {
1676 firstMotionSample = & motionEntry->firstSample;
1677 }
1678
Jeff Brownf26db0d2010-07-16 17:21:06 -07001679 // Set the X and Y offset depending on the input source.
1680 float xOffset, yOffset;
1681 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1682 xOffset = dispatchEntry->xOffset;
1683 yOffset = dispatchEntry->yOffset;
1684 } else {
1685 xOffset = 0.0f;
1686 yOffset = 0.0f;
1687 }
1688
Jeff Browne839a582010-04-22 18:58:52 -07001689 // Publish the motion event and the first motion sample.
1690 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001691 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -07001692 xOffset, yOffset,
Jeff Browne839a582010-04-22 18:58:52 -07001693 motionEntry->xPrecision, motionEntry->yPrecision,
1694 motionEntry->downTime, firstMotionSample->eventTime,
1695 motionEntry->pointerCount, motionEntry->pointerIds,
1696 firstMotionSample->pointerCoords);
1697
1698 if (status) {
1699 LOGE("channel '%s' ~ Could not publish motion event, "
1700 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001701 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001702 return;
1703 }
1704
1705 // Append additional motion samples.
1706 MotionSample* nextMotionSample = firstMotionSample->next;
1707 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1708 status = connection->inputPublisher.appendMotionSample(
1709 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1710 if (status == NO_MEMORY) {
1711#if DEBUG_DISPATCH_CYCLE
1712 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1713 "be sent in the next dispatch cycle.",
1714 connection->getInputChannelName());
1715#endif
1716 break;
1717 }
1718 if (status != OK) {
1719 LOGE("channel '%s' ~ Could not append motion sample "
1720 "for a reason other than out of memory, status=%d",
1721 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001722 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001723 return;
1724 }
1725 }
1726
1727 // Remember the next motion sample that we could not dispatch, in case we ran out
1728 // of space in the shared memory buffer.
1729 dispatchEntry->tailMotionSample = nextMotionSample;
1730 break;
1731 }
1732
1733 default: {
1734 assert(false);
1735 }
1736 }
1737
1738 // Send the dispatch signal.
1739 status = connection->inputPublisher.sendDispatchSignal();
1740 if (status) {
1741 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1742 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001743 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001744 return;
1745 }
1746
1747 // Record information about the newly started dispatch cycle.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001748 connection->lastEventTime = eventEntry->eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07001749 connection->lastDispatchTime = currentTime;
1750
Jeff Browne839a582010-04-22 18:58:52 -07001751 // Notify other system components.
1752 onDispatchCycleStartedLocked(currentTime, connection);
1753}
1754
Jeff Brown51d45a72010-06-17 20:52:56 -07001755void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown81499912010-11-05 15:02:16 -07001756 const sp<Connection>& connection, bool handled) {
Jeff Browne839a582010-04-22 18:58:52 -07001757#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001758 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown81499912010-11-05 15:02:16 -07001759 "%01.1fms since dispatch, handled=%s",
Jeff Browne839a582010-04-22 18:58:52 -07001760 connection->getInputChannelName(),
1761 connection->getEventLatencyMillis(currentTime),
Jeff Brown81499912010-11-05 15:02:16 -07001762 connection->getDispatchLatencyMillis(currentTime),
1763 toString(handled));
Jeff Browne839a582010-04-22 18:58:52 -07001764#endif
1765
Jeff Brown54bc2812010-06-15 01:31:58 -07001766 if (connection->status == Connection::STATUS_BROKEN
1767 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001768 return;
1769 }
1770
Jeff Browne839a582010-04-22 18:58:52 -07001771 // Reset the publisher since the event has been consumed.
1772 // We do this now so that the publisher can release some of its internal resources
1773 // while waiting for the next dispatch cycle to begin.
1774 status_t status = connection->inputPublisher.reset();
1775 if (status) {
1776 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1777 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001778 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001779 return;
1780 }
1781
Jeff Brown81499912010-11-05 15:02:16 -07001782 // Notify other system components and prepare to start the next dispatch cycle.
1783 onDispatchCycleFinishedLocked(currentTime, connection, handled);
Jeff Browna665ca82010-09-08 11:49:43 -07001784}
1785
1786void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1787 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001788 // Start the next dispatch cycle for this connection.
1789 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001790 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001791 if (dispatchEntry->inProgress) {
1792 // Finish or resume current event in progress.
1793 if (dispatchEntry->tailMotionSample) {
1794 // We have a tail of undispatched motion samples.
1795 // Reuse the same DispatchEntry and start a new cycle.
1796 dispatchEntry->inProgress = false;
1797 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1798 dispatchEntry->tailMotionSample = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07001799 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001800 return;
1801 }
1802 // Finished.
1803 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001804 if (dispatchEntry->hasForegroundTarget()) {
1805 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001806 }
Jeff Browne839a582010-04-22 18:58:52 -07001807 mAllocator.releaseDispatchEntry(dispatchEntry);
1808 } else {
1809 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown53a415e2010-09-15 15:18:56 -07001810 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001811 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001812 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001813 return;
1814 }
1815 }
1816
1817 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001818 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001819}
1820
Jeff Brown90f0cee2010-10-08 22:31:17 -07001821void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1822 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001823#if DEBUG_DISPATCH_CYCLE
Jeff Brown90f0cee2010-10-08 22:31:17 -07001824 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001825 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001826#endif
1827
Jeff Browna665ca82010-09-08 11:49:43 -07001828 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001829 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001830
Jeff Brown90f0cee2010-10-08 22:31:17 -07001831 // The connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001832 // Ignore already broken or zombie connections.
Jeff Brown90f0cee2010-10-08 22:31:17 -07001833 if (connection->status == Connection::STATUS_NORMAL) {
1834 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001835
Jeff Brown90f0cee2010-10-08 22:31:17 -07001836 // Notify other system components.
1837 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001838 }
Jeff Browne839a582010-04-22 18:58:52 -07001839}
1840
Jeff Brown53a415e2010-09-15 15:18:56 -07001841void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1842 while (! connection->outboundQueue.isEmpty()) {
1843 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1844 if (dispatchEntry->hasForegroundTarget()) {
1845 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001846 }
1847 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001848 }
1849
Jeff Brown53a415e2010-09-15 15:18:56 -07001850 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001851}
1852
Jeff Brown59abe7e2010-09-13 23:17:30 -07001853int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-04-22 18:58:52 -07001854 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1855
1856 { // acquire lock
1857 AutoMutex _l(d->mLock);
1858
1859 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1860 if (connectionIndex < 0) {
1861 LOGE("Received spurious receive callback for unknown input channel. "
1862 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001863 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001864 }
1865
Jeff Brown51d45a72010-06-17 20:52:56 -07001866 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001867
1868 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001869 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-04-22 18:58:52 -07001870 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1871 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001872 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001873 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001874 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001875 }
1876
Jeff Brown59abe7e2010-09-13 23:17:30 -07001877 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001878 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1879 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001880 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001881 }
1882
Jeff Brown81499912010-11-05 15:02:16 -07001883 bool handled = false;
1884 status_t status = connection->inputPublisher.receiveFinishedSignal(handled);
Jeff Browne839a582010-04-22 18:58:52 -07001885 if (status) {
1886 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1887 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001888 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001889 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001890 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001891 }
1892
Jeff Brown81499912010-11-05 15:02:16 -07001893 d->finishDispatchCycleLocked(currentTime, connection, handled);
Jeff Brown54bc2812010-06-15 01:31:58 -07001894 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001895 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001896 } // release lock
1897}
1898
Jeff Brown90f0cee2010-10-08 22:31:17 -07001899void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1900 InputState::CancelationOptions options, const char* reason) {
1901 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1902 synthesizeCancelationEventsForConnectionLocked(
1903 mConnectionsByReceiveFd.valueAt(i), options, reason);
1904 }
1905}
1906
1907void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1908 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1909 const char* reason) {
1910 ssize_t index = getConnectionIndexLocked(channel);
1911 if (index >= 0) {
1912 synthesizeCancelationEventsForConnectionLocked(
1913 mConnectionsByReceiveFd.valueAt(index), options, reason);
1914 }
1915}
1916
1917void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1918 const sp<Connection>& connection, InputState::CancelationOptions options,
1919 const char* reason) {
1920 nsecs_t currentTime = now();
1921
1922 mTempCancelationEvents.clear();
1923 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1924 mTempCancelationEvents, options);
1925
1926 if (! mTempCancelationEvents.isEmpty()
1927 && connection->status != Connection::STATUS_BROKEN) {
1928#if DEBUG_OUTBOUND_EVENT_DETAILS
1929 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1930 "with reality: %s, options=%d.",
1931 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1932#endif
1933 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1934 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1935 switch (cancelationEventEntry->type) {
1936 case EventEntry::TYPE_KEY:
1937 logOutboundKeyDetailsLocked("cancel - ",
1938 static_cast<KeyEntry*>(cancelationEventEntry));
1939 break;
1940 case EventEntry::TYPE_MOTION:
1941 logOutboundMotionDetailsLocked("cancel - ",
1942 static_cast<MotionEntry*>(cancelationEventEntry));
1943 break;
1944 }
1945
1946 int32_t xOffset, yOffset;
1947 const InputWindow* window = getWindowLocked(connection->inputChannel);
1948 if (window) {
1949 xOffset = -window->frameLeft;
1950 yOffset = -window->frameTop;
1951 } else {
1952 xOffset = 0;
1953 yOffset = 0;
1954 }
1955
1956 DispatchEntry* cancelationDispatchEntry =
1957 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1958 0, xOffset, yOffset);
1959 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1960
1961 mAllocator.releaseEventEntry(cancelationEventEntry);
1962 }
1963
1964 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1965 startDispatchCycleLocked(currentTime, connection);
1966 }
1967 }
1968}
1969
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001970InputDispatcher::MotionEntry*
1971InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1972 assert(pointerIds.value != 0);
1973
1974 uint32_t splitPointerIndexMap[MAX_POINTERS];
1975 int32_t splitPointerIds[MAX_POINTERS];
1976 PointerCoords splitPointerCoords[MAX_POINTERS];
1977
1978 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1979 uint32_t splitPointerCount = 0;
1980
1981 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1982 originalPointerIndex++) {
1983 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1984 if (pointerIds.hasBit(pointerId)) {
1985 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1986 splitPointerIds[splitPointerCount] = pointerId;
1987 splitPointerCoords[splitPointerCount] =
1988 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1989 splitPointerCount += 1;
1990 }
1991 }
1992 assert(splitPointerCount == pointerIds.count());
1993
1994 int32_t action = originalMotionEntry->action;
1995 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1996 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
1997 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1998 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
1999 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2000 if (pointerIds.hasBit(pointerId)) {
2001 if (pointerIds.count() == 1) {
2002 // The first/last pointer went down/up.
2003 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2004 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brownffb16d62010-09-27 16:35:11 -07002005 } else {
2006 // A secondary pointer went down/up.
2007 uint32_t splitPointerIndex = 0;
2008 while (pointerId != splitPointerIds[splitPointerIndex]) {
2009 splitPointerIndex += 1;
2010 }
2011 action = maskedAction | (splitPointerIndex
2012 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002013 }
2014 } else {
2015 // An unrelated pointer changed.
2016 action = AMOTION_EVENT_ACTION_MOVE;
2017 }
2018 }
2019
2020 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2021 originalMotionEntry->eventTime,
2022 originalMotionEntry->deviceId,
2023 originalMotionEntry->source,
2024 originalMotionEntry->policyFlags,
2025 action,
2026 originalMotionEntry->flags,
2027 originalMotionEntry->metaState,
2028 originalMotionEntry->edgeFlags,
2029 originalMotionEntry->xPrecision,
2030 originalMotionEntry->yPrecision,
2031 originalMotionEntry->downTime,
2032 splitPointerCount, splitPointerIds, splitPointerCoords);
2033
2034 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2035 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2036 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2037 splitPointerIndex++) {
2038 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2039 splitPointerCoords[splitPointerIndex] =
2040 originalMotionSample->pointerCoords[originalPointerIndex];
2041 }
2042
2043 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2044 splitPointerCoords);
2045 }
2046
2047 return splitMotionEntry;
2048}
2049
Jeff Brown54bc2812010-06-15 01:31:58 -07002050void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002051#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -07002052 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07002053#endif
2054
Jeff Browna665ca82010-09-08 11:49:43 -07002055 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002056 { // acquire lock
2057 AutoMutex _l(mLock);
2058
Jeff Brown51d45a72010-06-17 20:52:56 -07002059 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browna665ca82010-09-08 11:49:43 -07002060 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002061 } // release lock
2062
Jeff Browna665ca82010-09-08 11:49:43 -07002063 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002064 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002065 }
2066}
2067
Jeff Brown5c1ed842010-07-14 18:48:53 -07002068void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -07002069 uint32_t policyFlags, int32_t action, int32_t flags,
2070 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2071#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002072 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07002073 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07002074 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -07002075 keyCode, scanCode, metaState, downTime);
2076#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002077 if (! validateKeyEvent(action)) {
2078 return;
2079 }
Jeff Browne839a582010-04-22 18:58:52 -07002080
Jeff Brown33d54ce2010-10-11 14:20:19 -07002081 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002082 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2083 keyCode, scanCode, /*byref*/ policyFlags);
2084
Jeff Browna665ca82010-09-08 11:49:43 -07002085 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002086 { // acquire lock
2087 AutoMutex _l(mLock);
2088
Jeff Brown51d45a72010-06-17 20:52:56 -07002089 int32_t repeatCount = 0;
2090 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002091 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07002092 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07002093
Jeff Browna665ca82010-09-08 11:49:43 -07002094 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002095 } // release lock
2096
Jeff Browna665ca82010-09-08 11:49:43 -07002097 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002098 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002099 }
2100}
2101
Jeff Brown5c1ed842010-07-14 18:48:53 -07002102void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002103 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002104 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2105 float xPrecision, float yPrecision, nsecs_t downTime) {
2106#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002107 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002108 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2109 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2110 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002111 xPrecision, yPrecision, downTime);
2112 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07002113 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002114 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07002115 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07002116 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-08-30 03:02:23 -07002117 pointerCoords[i].pressure, pointerCoords[i].size,
2118 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2119 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2120 pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -07002121 }
2122#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002123 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2124 return;
2125 }
Jeff Browne839a582010-04-22 18:58:52 -07002126
Jeff Brown33d54ce2010-10-11 14:20:19 -07002127 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002128 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2129
Jeff Browna665ca82010-09-08 11:49:43 -07002130 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002131 { // acquire lock
2132 AutoMutex _l(mLock);
2133
2134 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07002135 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07002136 // BATCHING CASE
2137 //
2138 // Try to append a move sample to the tail of the inbound queue for this device.
2139 // Give up if we encounter a non-move motion event for this device since that
2140 // means we cannot append any new samples until a new motion event has started.
Jeff Browna665ca82010-09-08 11:49:43 -07002141 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2142 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07002143 if (entry->type != EventEntry::TYPE_MOTION) {
2144 // Keep looking for motion events.
2145 continue;
2146 }
2147
2148 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2149 if (motionEntry->deviceId != deviceId) {
2150 // Keep looking for this device.
2151 continue;
2152 }
2153
Jeff Brown5c1ed842010-07-14 18:48:53 -07002154 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07002155 || motionEntry->pointerCount != pointerCount
2156 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07002157 // Last motion event in the queue for this device is not compatible for
2158 // appending new samples. Stop here.
2159 goto NoBatchingOrStreaming;
2160 }
2161
2162 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07002163 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07002164 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002165#if DEBUG_BATCHING
2166 LOGD("Appended motion sample onto batch for most recent "
2167 "motion event for this device in the inbound queue.");
2168#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07002169 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002170 }
2171
2172 // STREAMING CASE
2173 //
2174 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07002175 // Search the outbound queue for the current foreground targets to find a dispatched
2176 // motion event that is still in progress. If found, then, appen the new sample to
2177 // that event and push it out to all current targets. The logic in
2178 // prepareDispatchCycleLocked takes care of the case where some targets may
2179 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown54bc2812010-06-15 01:31:58 -07002180 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002181 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2182 const InputTarget& inputTarget = mCurrentInputTargets[i];
2183 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2184 // Skip non-foreground targets. We only want to stream if there is at
2185 // least one foreground target whose dispatch is still in progress.
2186 continue;
Jeff Browne839a582010-04-22 18:58:52 -07002187 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002188
2189 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2190 if (connectionIndex < 0) {
2191 // Connection must no longer be valid.
2192 continue;
2193 }
2194
2195 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2196 if (connection->outboundQueue.isEmpty()) {
2197 // This foreground target has an empty outbound queue.
2198 continue;
2199 }
2200
2201 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2202 if (! dispatchEntry->inProgress
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002203 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2204 || dispatchEntry->isSplit()) {
2205 // No motion event is being dispatched, or it is being split across
2206 // windows in which case we cannot stream.
Jeff Brown53a415e2010-09-15 15:18:56 -07002207 continue;
2208 }
2209
2210 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2211 dispatchEntry->eventEntry);
2212 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2213 || motionEntry->deviceId != deviceId
2214 || motionEntry->pointerCount != pointerCount
2215 || motionEntry->isInjected()) {
2216 // The motion event is not compatible with this move.
2217 continue;
2218 }
2219
2220 // Hurray! This foreground target is currently dispatching a move event
2221 // that we can stream onto. Append the motion sample and resume dispatch.
2222 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2223#if DEBUG_BATCHING
2224 LOGD("Appended motion sample onto batch for most recently dispatched "
2225 "motion event for this device in the outbound queues. "
2226 "Attempting to stream the motion sample.");
2227#endif
2228 nsecs_t currentTime = now();
2229 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2230 true /*resumeWithAppendedMotionSample*/);
2231
2232 runCommandsLockedInterruptible();
2233 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002234 }
2235 }
2236
2237NoBatchingOrStreaming:;
2238 }
2239
2240 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07002241 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002242 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002243 xPrecision, yPrecision, downTime,
2244 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002245
Jeff Browna665ca82010-09-08 11:49:43 -07002246 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002247 } // release lock
2248
Jeff Browna665ca82010-09-08 11:49:43 -07002249 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002250 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002251 }
2252}
2253
Jeff Brown90f0cee2010-10-08 22:31:17 -07002254void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2255 uint32_t policyFlags) {
2256#if DEBUG_INBOUND_EVENT_DETAILS
2257 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2258 switchCode, switchValue, policyFlags);
2259#endif
2260
Jeff Brown33d54ce2010-10-11 14:20:19 -07002261 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002262 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2263}
2264
Jeff Brown51d45a72010-06-17 20:52:56 -07002265int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07002266 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002267#if DEBUG_INBOUND_EVENT_DETAILS
2268 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002269 "syncMode=%d, timeoutMillis=%d",
2270 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07002271#endif
2272
2273 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brown33d54ce2010-10-11 14:20:19 -07002274
2275 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2276 if (hasInjectionPermission(injectorPid, injectorUid)) {
2277 policyFlags |= POLICY_FLAG_TRUSTED;
2278 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002279
Jeff Brown90f0cee2010-10-08 22:31:17 -07002280 EventEntry* injectedEntry;
2281 switch (event->getType()) {
2282 case AINPUT_EVENT_TYPE_KEY: {
2283 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2284 int32_t action = keyEvent->getAction();
2285 if (! validateKeyEvent(action)) {
Jeff Browna665ca82010-09-08 11:49:43 -07002286 return INPUT_EVENT_INJECTION_FAILED;
2287 }
2288
Jeff Brown90f0cee2010-10-08 22:31:17 -07002289 nsecs_t eventTime = keyEvent->getEventTime();
2290 int32_t deviceId = keyEvent->getDeviceId();
2291 int32_t flags = keyEvent->getFlags();
2292 int32_t keyCode = keyEvent->getKeyCode();
2293 int32_t scanCode = keyEvent->getScanCode();
Jeff Brown33d54ce2010-10-11 14:20:19 -07002294 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2295 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002296
Jeff Brown90f0cee2010-10-08 22:31:17 -07002297 mLock.lock();
2298 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2299 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2300 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2301 break;
2302 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002303
Jeff Brown90f0cee2010-10-08 22:31:17 -07002304 case AINPUT_EVENT_TYPE_MOTION: {
2305 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2306 int32_t action = motionEvent->getAction();
2307 size_t pointerCount = motionEvent->getPointerCount();
2308 const int32_t* pointerIds = motionEvent->getPointerIds();
2309 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2310 return INPUT_EVENT_INJECTION_FAILED;
2311 }
2312
2313 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown33d54ce2010-10-11 14:20:19 -07002314 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002315
2316 mLock.lock();
2317 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2318 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2319 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2320 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2321 action, motionEvent->getFlags(),
2322 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2323 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2324 motionEvent->getDownTime(), uint32_t(pointerCount),
2325 pointerIds, samplePointerCoords);
2326 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2327 sampleEventTimes += 1;
2328 samplePointerCoords += pointerCount;
2329 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2330 }
2331 injectedEntry = motionEntry;
2332 break;
2333 }
2334
2335 default:
2336 LOGW("Cannot inject event of type %d", event->getType());
2337 return INPUT_EVENT_INJECTION_FAILED;
2338 }
2339
2340 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2341 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2342 injectionState->injectionIsAsync = true;
2343 }
2344
2345 injectionState->refCount += 1;
2346 injectedEntry->injectionState = injectionState;
2347
2348 bool needWake = enqueueInboundEventLocked(injectedEntry);
2349 mLock.unlock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002350
Jeff Browna665ca82010-09-08 11:49:43 -07002351 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002352 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07002353 }
2354
2355 int32_t injectionResult;
2356 { // acquire lock
2357 AutoMutex _l(mLock);
2358
Jeff Brownf67c53e2010-07-28 15:48:59 -07002359 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2360 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2361 } else {
2362 for (;;) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002363 injectionResult = injectionState->injectionResult;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002364 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2365 break;
2366 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002367
Jeff Brown51d45a72010-06-17 20:52:56 -07002368 nsecs_t remainingTimeout = endTime - now();
2369 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002370#if DEBUG_INJECTION
2371 LOGD("injectInputEvent - Timed out waiting for injection result "
2372 "to become available.");
2373#endif
Jeff Brown51d45a72010-06-17 20:52:56 -07002374 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2375 break;
2376 }
2377
Jeff Brownf67c53e2010-07-28 15:48:59 -07002378 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2379 }
2380
2381 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2382 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002383 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002384#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002385 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002386 injectionState->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002387#endif
2388 nsecs_t remainingTimeout = endTime - now();
2389 if (remainingTimeout <= 0) {
2390#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002391 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002392 "dispatches to finish.");
2393#endif
2394 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2395 break;
2396 }
2397
2398 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2399 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002400 }
2401 }
2402
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002403 mAllocator.releaseInjectionState(injectionState);
Jeff Brown51d45a72010-06-17 20:52:56 -07002404 } // release lock
2405
Jeff Brownf67c53e2010-07-28 15:48:59 -07002406#if DEBUG_INJECTION
2407 LOGD("injectInputEvent - Finished with result %d. "
2408 "injectorPid=%d, injectorUid=%d",
2409 injectionResult, injectorPid, injectorUid);
2410#endif
2411
Jeff Brown51d45a72010-06-17 20:52:56 -07002412 return injectionResult;
2413}
2414
Jeff Brown90f0cee2010-10-08 22:31:17 -07002415bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2416 return injectorUid == 0
2417 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2418}
2419
Jeff Brown51d45a72010-06-17 20:52:56 -07002420void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002421 InjectionState* injectionState = entry->injectionState;
2422 if (injectionState) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002423#if DEBUG_INJECTION
2424 LOGD("Setting input event injection result to %d. "
2425 "injectorPid=%d, injectorUid=%d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002426 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002427#endif
2428
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002429 if (injectionState->injectionIsAsync) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002430 // Log the outcome since the injector did not wait for the injection result.
2431 switch (injectionResult) {
2432 case INPUT_EVENT_INJECTION_SUCCEEDED:
2433 LOGV("Asynchronous input event injection succeeded.");
2434 break;
2435 case INPUT_EVENT_INJECTION_FAILED:
2436 LOGW("Asynchronous input event injection failed.");
2437 break;
2438 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2439 LOGW("Asynchronous input event injection permission denied.");
2440 break;
2441 case INPUT_EVENT_INJECTION_TIMED_OUT:
2442 LOGW("Asynchronous input event injection timed out.");
2443 break;
2444 }
2445 }
2446
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002447 injectionState->injectionResult = injectionResult;
Jeff Brown51d45a72010-06-17 20:52:56 -07002448 mInjectionResultAvailableCondition.broadcast();
2449 }
2450}
2451
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002452void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2453 InjectionState* injectionState = entry->injectionState;
2454 if (injectionState) {
2455 injectionState->pendingForegroundDispatches += 1;
2456 }
2457}
2458
Jeff Brown53a415e2010-09-15 15:18:56 -07002459void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002460 InjectionState* injectionState = entry->injectionState;
2461 if (injectionState) {
2462 injectionState->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002463
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002464 if (injectionState->pendingForegroundDispatches == 0) {
2465 mInjectionSyncFinishedCondition.broadcast();
2466 }
Jeff Browna665ca82010-09-08 11:49:43 -07002467 }
2468}
2469
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002470const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2471 for (size_t i = 0; i < mWindows.size(); i++) {
2472 const InputWindow* window = & mWindows[i];
2473 if (window->inputChannel == inputChannel) {
2474 return window;
2475 }
2476 }
2477 return NULL;
2478}
2479
Jeff Browna665ca82010-09-08 11:49:43 -07002480void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2481#if DEBUG_FOCUS
2482 LOGD("setInputWindows");
2483#endif
2484 { // acquire lock
2485 AutoMutex _l(mLock);
2486
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002487 // Clear old window pointers.
Jeff Brown90f0cee2010-10-08 22:31:17 -07002488 sp<InputChannel> oldFocusedWindowChannel;
2489 if (mFocusedWindow) {
2490 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2491 mFocusedWindow = NULL;
2492 }
2493
Jeff Browna665ca82010-09-08 11:49:43 -07002494 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002495
2496 // Loop over new windows and rebuild the necessary window pointers for
2497 // tracking focus and touch.
Jeff Browna665ca82010-09-08 11:49:43 -07002498 mWindows.appendVector(inputWindows);
2499
2500 size_t numWindows = mWindows.size();
2501 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002502 const InputWindow* window = & mWindows.itemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07002503 if (window->hasFocus) {
2504 mFocusedWindow = window;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002505 break;
Jeff Browna665ca82010-09-08 11:49:43 -07002506 }
2507 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002508
Jeff Brown90f0cee2010-10-08 22:31:17 -07002509 if (oldFocusedWindowChannel != NULL) {
2510 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2511#if DEBUG_FOCUS
2512 LOGD("Focus left window: %s",
2513 oldFocusedWindowChannel->getName().string());
2514#endif
2515 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2516 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2517 oldFocusedWindowChannel.clear();
2518 }
2519 }
2520 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2521#if DEBUG_FOCUS
2522 LOGD("Focus entered window: %s",
2523 mFocusedWindow->inputChannel->getName().string());
2524#endif
2525 }
2526
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002527 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2528 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2529 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2530 if (window) {
2531 touchedWindow.window = window;
2532 i += 1;
2533 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -07002534#if DEBUG_FOCUS
2535 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2536#endif
Jeff Brown90f0cee2010-10-08 22:31:17 -07002537 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2538 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownb13d7b52010-10-15 16:20:51 -07002539 mTouchState.windows.removeAt(i);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002540 }
2541 }
Jeff Browna665ca82010-09-08 11:49:43 -07002542
Jeff Browna665ca82010-09-08 11:49:43 -07002543#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002544 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002545#endif
2546 } // release lock
2547
2548 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002549 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002550}
2551
2552void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2553#if DEBUG_FOCUS
2554 LOGD("setFocusedApplication");
2555#endif
2556 { // acquire lock
2557 AutoMutex _l(mLock);
2558
2559 releaseFocusedApplicationLocked();
2560
2561 if (inputApplication) {
2562 mFocusedApplicationStorage = *inputApplication;
2563 mFocusedApplication = & mFocusedApplicationStorage;
2564 }
2565
2566#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002567 //logDispatchStateLocked();
Jeff Browna665ca82010-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 Brown59abe7e2010-09-13 23:17:30 -07002572 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002573}
2574
2575void InputDispatcher::releaseFocusedApplicationLocked() {
2576 if (mFocusedApplication) {
2577 mFocusedApplication = NULL;
2578 mFocusedApplicationStorage.handle.clear();
2579 }
2580}
2581
2582void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2583#if DEBUG_FOCUS
2584 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2585#endif
2586
2587 bool changed;
2588 { // acquire lock
2589 AutoMutex _l(mLock);
2590
2591 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brownfef5b042010-10-27 18:43:51 -07002592 if (mDispatchFrozen && !frozen) {
Jeff Browna665ca82010-09-08 11:49:43 -07002593 resetANRTimeoutsLocked();
2594 }
2595
Jeff Brownfef5b042010-10-27 18:43:51 -07002596 if (mDispatchEnabled && !enabled) {
2597 resetAndDropEverythingLocked("dispatcher is being disabled");
2598 }
2599
Jeff Browna665ca82010-09-08 11:49:43 -07002600 mDispatchEnabled = enabled;
2601 mDispatchFrozen = frozen;
2602 changed = true;
2603 } else {
2604 changed = false;
2605 }
2606
2607#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002608 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002609#endif
2610 } // release lock
2611
2612 if (changed) {
2613 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002614 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002615 }
2616}
2617
Jeff Brown744c5592010-09-27 14:52:15 -07002618bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2619 const sp<InputChannel>& toChannel) {
2620#if DEBUG_FOCUS
2621 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2622 fromChannel->getName().string(), toChannel->getName().string());
2623#endif
2624 { // acquire lock
2625 AutoMutex _l(mLock);
2626
2627 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2628 const InputWindow* toWindow = getWindowLocked(toChannel);
2629 if (! fromWindow || ! toWindow) {
2630#if DEBUG_FOCUS
2631 LOGD("Cannot transfer focus because from or to window not found.");
2632#endif
2633 return false;
2634 }
2635 if (fromWindow == toWindow) {
2636#if DEBUG_FOCUS
2637 LOGD("Trivial transfer to same window.");
2638#endif
2639 return true;
2640 }
2641
2642 bool found = false;
2643 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2644 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2645 if (touchedWindow.window == fromWindow) {
2646 int32_t oldTargetFlags = touchedWindow.targetFlags;
2647 BitSet32 pointerIds = touchedWindow.pointerIds;
2648
2649 mTouchState.windows.removeAt(i);
2650
2651 int32_t newTargetFlags = 0;
2652 if (oldTargetFlags & InputTarget::FLAG_FOREGROUND) {
2653 newTargetFlags |= InputTarget::FLAG_FOREGROUND;
2654 if (toWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) {
2655 newTargetFlags |= InputTarget::FLAG_SPLIT;
2656 }
2657 }
2658 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2659
2660 found = true;
2661 break;
2662 }
2663 }
2664
2665 if (! found) {
2666#if DEBUG_FOCUS
2667 LOGD("Focus transfer failed because from window did not have focus.");
2668#endif
2669 return false;
2670 }
2671
Jeff Brownb6702e52010-10-11 18:32:20 -07002672 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2673 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2674 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2675 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2676 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2677
2678 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2679 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2680 InputState::CANCEL_POINTER_EVENTS,
2681 "transferring touch focus from this window to another window");
2682 }
2683
Jeff Brown744c5592010-09-27 14:52:15 -07002684#if DEBUG_FOCUS
2685 logDispatchStateLocked();
2686#endif
2687 } // release lock
2688
2689 // Wake up poll loop since it may need to make new input dispatching choices.
2690 mLooper->wake();
2691 return true;
2692}
2693
Jeff Brownfef5b042010-10-27 18:43:51 -07002694void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2695#if DEBUG_FOCUS
2696 LOGD("Resetting and dropping all events (%s).", reason);
2697#endif
2698
2699 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2700
2701 resetKeyRepeatLocked();
2702 releasePendingEventLocked();
2703 drainInboundQueueLocked();
2704 resetTargetsLocked();
2705
2706 mTouchState.reset();
2707}
2708
Jeff Browna665ca82010-09-08 11:49:43 -07002709void InputDispatcher::logDispatchStateLocked() {
2710 String8 dump;
2711 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002712
2713 char* text = dump.lockBuffer(dump.size());
2714 char* start = text;
2715 while (*start != '\0') {
2716 char* end = strchr(start, '\n');
2717 if (*end == '\n') {
2718 *(end++) = '\0';
2719 }
2720 LOGD("%s", start);
2721 start = end;
2722 }
Jeff Browna665ca82010-09-08 11:49:43 -07002723}
2724
2725void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002726 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2727 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002728
2729 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002730 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002731 mFocusedApplication->name.string(),
2732 mFocusedApplication->dispatchingTimeout / 1000000.0);
2733 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002734 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002735 }
Jeff Brown2806e382010-10-01 17:46:21 -07002736 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002737 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-10-01 17:46:21 -07002738
2739 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2740 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2741 if (!mTouchState.windows.isEmpty()) {
2742 dump.append(INDENT "TouchedWindows:\n");
2743 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2744 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2745 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2746 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2747 touchedWindow.targetFlags);
2748 }
2749 } else {
2750 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002751 }
2752
Jeff Brown2806e382010-10-01 17:46:21 -07002753 if (!mWindows.isEmpty()) {
2754 dump.append(INDENT "Windows:\n");
2755 for (size_t i = 0; i < mWindows.size(); i++) {
2756 const InputWindow& window = mWindows[i];
2757 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2758 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2759 "frame=[%d,%d][%d,%d], "
2760 "visibleFrame=[%d,%d][%d,%d], "
2761 "touchableArea=[%d,%d][%d,%d], "
2762 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2763 i, window.name.string(),
2764 toString(window.paused),
2765 toString(window.hasFocus),
2766 toString(window.hasWallpaper),
2767 toString(window.visible),
2768 toString(window.canReceiveKeys),
2769 window.layoutParamsFlags, window.layoutParamsType,
2770 window.layer,
2771 window.frameLeft, window.frameTop,
2772 window.frameRight, window.frameBottom,
2773 window.visibleFrameLeft, window.visibleFrameTop,
2774 window.visibleFrameRight, window.visibleFrameBottom,
2775 window.touchableAreaLeft, window.touchableAreaTop,
2776 window.touchableAreaRight, window.touchableAreaBottom,
2777 window.ownerPid, window.ownerUid,
2778 window.dispatchingTimeout / 1000000.0);
2779 }
2780 } else {
2781 dump.append(INDENT "Windows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002782 }
2783
Jeff Brown2806e382010-10-01 17:46:21 -07002784 if (!mMonitoringChannels.isEmpty()) {
2785 dump.append(INDENT "MonitoringChannels:\n");
2786 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2787 const sp<InputChannel>& channel = mMonitoringChannels[i];
2788 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2789 }
2790 } else {
2791 dump.append(INDENT "MonitoringChannels: <none>\n");
2792 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002793
Jeff Brown2806e382010-10-01 17:46:21 -07002794 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2795
2796 if (!mActiveConnections.isEmpty()) {
2797 dump.append(INDENT "ActiveConnections:\n");
2798 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2799 const Connection* connection = mActiveConnections[i];
Jeff Brown53f291e2010-10-25 17:37:46 -07002800 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brown90f0cee2010-10-08 22:31:17 -07002801 "inputState.isNeutral=%s\n",
Jeff Brown2806e382010-10-01 17:46:21 -07002802 i, connection->getInputChannelName(), connection->getStatusLabel(),
2803 connection->outboundQueue.count(),
Jeff Brown90f0cee2010-10-08 22:31:17 -07002804 toString(connection->inputState.isNeutral()));
Jeff Brown2806e382010-10-01 17:46:21 -07002805 }
2806 } else {
2807 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002808 }
2809
2810 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002811 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002812 (mAppSwitchDueTime - now()) / 1000000.0);
2813 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002814 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002815 }
2816}
2817
2818status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002819#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002820 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2821 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002822#endif
2823
Jeff Browne839a582010-04-22 18:58:52 -07002824 { // acquire lock
2825 AutoMutex _l(mLock);
2826
Jeff Brown53a415e2010-09-15 15:18:56 -07002827 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002828 LOGW("Attempted to register already registered input channel '%s'",
2829 inputChannel->getName().string());
2830 return BAD_VALUE;
2831 }
2832
2833 sp<Connection> connection = new Connection(inputChannel);
2834 status_t status = connection->initialize();
2835 if (status) {
2836 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2837 inputChannel->getName().string(), status);
2838 return status;
2839 }
2840
Jeff Brown0cacb872010-08-17 15:59:26 -07002841 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002842 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002843
Jeff Browna665ca82010-09-08 11:49:43 -07002844 if (monitor) {
2845 mMonitoringChannels.push(inputChannel);
2846 }
2847
Jeff Brown59abe7e2010-09-13 23:17:30 -07002848 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002849
Jeff Brown54bc2812010-06-15 01:31:58 -07002850 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002851 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002852 return OK;
2853}
2854
2855status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002856#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002857 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002858#endif
2859
Jeff Browne839a582010-04-22 18:58:52 -07002860 { // acquire lock
2861 AutoMutex _l(mLock);
2862
Jeff Brown53a415e2010-09-15 15:18:56 -07002863 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002864 if (connectionIndex < 0) {
2865 LOGW("Attempted to unregister already unregistered input channel '%s'",
2866 inputChannel->getName().string());
2867 return BAD_VALUE;
2868 }
2869
2870 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2871 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2872
2873 connection->status = Connection::STATUS_ZOMBIE;
2874
Jeff Browna665ca82010-09-08 11:49:43 -07002875 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2876 if (mMonitoringChannels[i] == inputChannel) {
2877 mMonitoringChannels.removeAt(i);
2878 break;
2879 }
2880 }
2881
Jeff Brown59abe7e2010-09-13 23:17:30 -07002882 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002883
Jeff Brown51d45a72010-06-17 20:52:56 -07002884 nsecs_t currentTime = now();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002885 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002886
2887 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002888 } // release lock
2889
Jeff Browne839a582010-04-22 18:58:52 -07002890 // Wake the poll loop because removing the connection may have changed the current
2891 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002892 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002893 return OK;
2894}
2895
Jeff Brown53a415e2010-09-15 15:18:56 -07002896ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002897 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2898 if (connectionIndex >= 0) {
2899 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2900 if (connection->inputChannel.get() == inputChannel.get()) {
2901 return connectionIndex;
2902 }
2903 }
2904
2905 return -1;
2906}
2907
Jeff Browne839a582010-04-22 18:58:52 -07002908void InputDispatcher::activateConnectionLocked(Connection* connection) {
2909 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2910 if (mActiveConnections.itemAt(i) == connection) {
2911 return;
2912 }
2913 }
2914 mActiveConnections.add(connection);
2915}
2916
2917void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2918 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2919 if (mActiveConnections.itemAt(i) == connection) {
2920 mActiveConnections.removeAt(i);
2921 return;
2922 }
2923 }
2924}
2925
Jeff Brown54bc2812010-06-15 01:31:58 -07002926void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002927 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002928}
2929
Jeff Brown54bc2812010-06-15 01:31:58 -07002930void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown81499912010-11-05 15:02:16 -07002931 nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
2932 CommandEntry* commandEntry = postCommandLocked(
2933 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
2934 commandEntry->connection = connection;
2935 commandEntry->handled = handled;
Jeff Browne839a582010-04-22 18:58:52 -07002936}
2937
Jeff Brown54bc2812010-06-15 01:31:58 -07002938void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002939 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002940 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2941 connection->getInputChannelName());
2942
Jeff Brown54bc2812010-06-15 01:31:58 -07002943 CommandEntry* commandEntry = postCommandLocked(
2944 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002945 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002946}
2947
Jeff Brown53a415e2010-09-15 15:18:56 -07002948void InputDispatcher::onANRLocked(
2949 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2950 nsecs_t eventTime, nsecs_t waitStartTime) {
2951 LOGI("Application is not responding: %s. "
2952 "%01.1fms since event, %01.1fms since wait started",
2953 getApplicationWindowLabelLocked(application, window).string(),
2954 (currentTime - eventTime) / 1000000.0,
2955 (currentTime - waitStartTime) / 1000000.0);
2956
2957 CommandEntry* commandEntry = postCommandLocked(
2958 & InputDispatcher::doNotifyANRLockedInterruptible);
2959 if (application) {
2960 commandEntry->inputApplicationHandle = application->handle;
2961 }
2962 if (window) {
2963 commandEntry->inputChannel = window->inputChannel;
2964 }
2965}
2966
Jeff Browna665ca82010-09-08 11:49:43 -07002967void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2968 CommandEntry* commandEntry) {
2969 mLock.unlock();
2970
2971 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2972
2973 mLock.lock();
2974}
2975
Jeff Brown54bc2812010-06-15 01:31:58 -07002976void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2977 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002978 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002979
Jeff Brown51d45a72010-06-17 20:52:56 -07002980 if (connection->status != Connection::STATUS_ZOMBIE) {
2981 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002982
Jeff Brown51d45a72010-06-17 20:52:56 -07002983 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2984
2985 mLock.lock();
2986 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002987}
2988
Jeff Brown53a415e2010-09-15 15:18:56 -07002989void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002990 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002991 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002992
Jeff Brown53a415e2010-09-15 15:18:56 -07002993 nsecs_t newTimeout = mPolicy->notifyANR(
2994 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002995
Jeff Brown53a415e2010-09-15 15:18:56 -07002996 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002997
Jeff Brown53a415e2010-09-15 15:18:56 -07002998 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002999}
3000
Jeff Browna665ca82010-09-08 11:49:43 -07003001void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3002 CommandEntry* commandEntry) {
3003 KeyEntry* entry = commandEntry->keyEntry;
Jeff Brown81499912010-11-05 15:02:16 -07003004 initializeKeyEvent(&mReusableKeyEvent, entry);
Jeff Browna665ca82010-09-08 11:49:43 -07003005
3006 mLock.unlock();
3007
3008 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
3009 & mReusableKeyEvent, entry->policyFlags);
3010
3011 mLock.lock();
3012
3013 entry->interceptKeyResult = consumed
3014 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
3015 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3016 mAllocator.releaseKeyEntry(entry);
3017}
3018
Jeff Brown81499912010-11-05 15:02:16 -07003019void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3020 CommandEntry* commandEntry) {
3021 sp<Connection> connection = commandEntry->connection;
3022 bool handled = commandEntry->handled;
3023
3024 if (!handled && !connection->outboundQueue.isEmpty()) {
3025 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
3026 if (dispatchEntry->inProgress
3027 && dispatchEntry->hasForegroundTarget()
3028 && dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3029 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
3030 initializeKeyEvent(&mReusableKeyEvent, keyEntry);
3031
3032 mLock.unlock();
3033
3034 mPolicy->dispatchUnhandledKey(connection->inputChannel,
3035 & mReusableKeyEvent, keyEntry->policyFlags);
3036
3037 mLock.lock();
3038 }
3039 }
3040
3041 startNextDispatchCycleLocked(now(), connection);
3042}
3043
Jeff Browna665ca82010-09-08 11:49:43 -07003044void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3045 mLock.unlock();
3046
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003047 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07003048
3049 mLock.lock();
3050}
3051
Jeff Brown81499912010-11-05 15:02:16 -07003052void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
3053 event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3054 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3055 entry->downTime, entry->eventTime);
3056}
3057
Jeff Brown53a415e2010-09-15 15:18:56 -07003058void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3059 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3060 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07003061}
3062
3063void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07003064 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07003065 dumpDispatchStateLocked(dump);
3066}
3067
Jeff Brown54bc2812010-06-15 01:31:58 -07003068
Jeff Brown53a415e2010-09-15 15:18:56 -07003069// --- InputDispatcher::Queue ---
3070
3071template <typename T>
3072uint32_t InputDispatcher::Queue<T>::count() const {
3073 uint32_t result = 0;
3074 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3075 result += 1;
3076 }
3077 return result;
3078}
3079
3080
Jeff Browne839a582010-04-22 18:58:52 -07003081// --- InputDispatcher::Allocator ---
3082
3083InputDispatcher::Allocator::Allocator() {
3084}
3085
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003086InputDispatcher::InjectionState*
3087InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3088 InjectionState* injectionState = mInjectionStatePool.alloc();
3089 injectionState->refCount = 1;
3090 injectionState->injectorPid = injectorPid;
3091 injectionState->injectorUid = injectorUid;
3092 injectionState->injectionIsAsync = false;
3093 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3094 injectionState->pendingForegroundDispatches = 0;
3095 return injectionState;
3096}
3097
Jeff Brown51d45a72010-06-17 20:52:56 -07003098void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brown90f0cee2010-10-08 22:31:17 -07003099 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown51d45a72010-06-17 20:52:56 -07003100 entry->type = type;
3101 entry->refCount = 1;
3102 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07003103 entry->eventTime = eventTime;
Jeff Brown90f0cee2010-10-08 22:31:17 -07003104 entry->policyFlags = policyFlags;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003105 entry->injectionState = NULL;
3106}
3107
3108void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3109 if (entry->injectionState) {
3110 releaseInjectionState(entry->injectionState);
3111 entry->injectionState = NULL;
3112 }
Jeff Brown51d45a72010-06-17 20:52:56 -07003113}
3114
Jeff Browne839a582010-04-22 18:58:52 -07003115InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07003116InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003117 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003118 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Browne839a582010-04-22 18:58:52 -07003119 return entry;
3120}
3121
Jeff Brown51d45a72010-06-17 20:52:56 -07003122InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07003123 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07003124 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3125 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003126 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003127 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003128
3129 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003130 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003131 entry->action = action;
3132 entry->flags = flags;
3133 entry->keyCode = keyCode;
3134 entry->scanCode = scanCode;
3135 entry->metaState = metaState;
3136 entry->repeatCount = repeatCount;
3137 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07003138 entry->syntheticRepeat = false;
3139 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07003140 return entry;
3141}
3142
Jeff Brown51d45a72010-06-17 20:52:56 -07003143InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07003144 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07003145 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3146 nsecs_t downTime, uint32_t pointerCount,
3147 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003148 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003149 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003150
3151 entry->eventTime = eventTime;
3152 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003153 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003154 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07003155 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07003156 entry->metaState = metaState;
3157 entry->edgeFlags = edgeFlags;
3158 entry->xPrecision = xPrecision;
3159 entry->yPrecision = yPrecision;
3160 entry->downTime = downTime;
3161 entry->pointerCount = pointerCount;
3162 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07003163 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07003164 entry->lastSample = & entry->firstSample;
3165 for (uint32_t i = 0; i < pointerCount; i++) {
3166 entry->pointerIds[i] = pointerIds[i];
3167 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3168 }
Jeff Browne839a582010-04-22 18:58:52 -07003169 return entry;
3170}
3171
3172InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07003173 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07003174 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07003175 DispatchEntry* entry = mDispatchEntryPool.alloc();
3176 entry->eventEntry = eventEntry;
3177 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07003178 entry->targetFlags = targetFlags;
3179 entry->xOffset = xOffset;
3180 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07003181 entry->inProgress = false;
3182 entry->headMotionSample = NULL;
3183 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07003184 return entry;
3185}
3186
Jeff Brown54bc2812010-06-15 01:31:58 -07003187InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3188 CommandEntry* entry = mCommandEntryPool.alloc();
3189 entry->command = command;
3190 return entry;
3191}
3192
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003193void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3194 injectionState->refCount -= 1;
3195 if (injectionState->refCount == 0) {
3196 mInjectionStatePool.free(injectionState);
3197 } else {
3198 assert(injectionState->refCount > 0);
3199 }
3200}
3201
Jeff Browne839a582010-04-22 18:58:52 -07003202void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3203 switch (entry->type) {
3204 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3205 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3206 break;
3207 case EventEntry::TYPE_KEY:
3208 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3209 break;
3210 case EventEntry::TYPE_MOTION:
3211 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3212 break;
3213 default:
3214 assert(false);
3215 break;
3216 }
3217}
3218
3219void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3220 ConfigurationChangedEntry* entry) {
3221 entry->refCount -= 1;
3222 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003223 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003224 mConfigurationChangeEntryPool.free(entry);
3225 } else {
3226 assert(entry->refCount > 0);
3227 }
3228}
3229
3230void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3231 entry->refCount -= 1;
3232 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003233 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003234 mKeyEntryPool.free(entry);
3235 } else {
3236 assert(entry->refCount > 0);
3237 }
3238}
3239
3240void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3241 entry->refCount -= 1;
3242 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003243 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -07003244 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3245 MotionSample* next = sample->next;
3246 mMotionSamplePool.free(sample);
3247 sample = next;
3248 }
Jeff Browne839a582010-04-22 18:58:52 -07003249 mMotionEntryPool.free(entry);
3250 } else {
3251 assert(entry->refCount > 0);
3252 }
3253}
3254
3255void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3256 releaseEventEntry(entry->eventEntry);
3257 mDispatchEntryPool.free(entry);
3258}
3259
Jeff Brown54bc2812010-06-15 01:31:58 -07003260void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3261 mCommandEntryPool.free(entry);
3262}
3263
Jeff Browne839a582010-04-22 18:58:52 -07003264void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003265 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003266 MotionSample* sample = mMotionSamplePool.alloc();
3267 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003268 uint32_t pointerCount = motionEntry->pointerCount;
3269 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07003270 sample->pointerCoords[i] = pointerCoords[i];
3271 }
3272
3273 sample->next = NULL;
3274 motionEntry->lastSample->next = sample;
3275 motionEntry->lastSample = sample;
3276}
3277
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003278void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3279 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003280
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003281 keyEntry->dispatchInProgress = false;
3282 keyEntry->syntheticRepeat = false;
3283 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003284}
3285
3286
Jeff Brown542412c2010-08-18 15:51:08 -07003287// --- InputDispatcher::MotionEntry ---
3288
3289uint32_t InputDispatcher::MotionEntry::countSamples() const {
3290 uint32_t count = 1;
3291 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3292 count += 1;
3293 }
3294 return count;
3295}
3296
Jeff Browna665ca82010-09-08 11:49:43 -07003297
3298// --- InputDispatcher::InputState ---
3299
Jeff Brown90f0cee2010-10-08 22:31:17 -07003300InputDispatcher::InputState::InputState() {
Jeff Browna665ca82010-09-08 11:49:43 -07003301}
3302
3303InputDispatcher::InputState::~InputState() {
3304}
3305
3306bool InputDispatcher::InputState::isNeutral() const {
3307 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3308}
3309
Jeff Browna665ca82010-09-08 11:49:43 -07003310InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3311 const EventEntry* entry) {
3312 switch (entry->type) {
3313 case EventEntry::TYPE_KEY:
3314 return trackKey(static_cast<const KeyEntry*>(entry));
3315
3316 case EventEntry::TYPE_MOTION:
3317 return trackMotion(static_cast<const MotionEntry*>(entry));
3318
3319 default:
3320 return CONSISTENT;
3321 }
3322}
3323
3324InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3325 const KeyEntry* entry) {
3326 int32_t action = entry->action;
3327 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3328 KeyMemento& memento = mKeyMementos.editItemAt(i);
3329 if (memento.deviceId == entry->deviceId
3330 && memento.source == entry->source
3331 && memento.keyCode == entry->keyCode
3332 && memento.scanCode == entry->scanCode) {
3333 switch (action) {
3334 case AKEY_EVENT_ACTION_UP:
3335 mKeyMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003336 return CONSISTENT;
3337
3338 case AKEY_EVENT_ACTION_DOWN:
3339 return TOLERABLE;
3340
3341 default:
3342 return BROKEN;
3343 }
3344 }
3345 }
3346
3347 switch (action) {
3348 case AKEY_EVENT_ACTION_DOWN: {
3349 mKeyMementos.push();
3350 KeyMemento& memento = mKeyMementos.editTop();
3351 memento.deviceId = entry->deviceId;
3352 memento.source = entry->source;
3353 memento.keyCode = entry->keyCode;
3354 memento.scanCode = entry->scanCode;
3355 memento.downTime = entry->downTime;
3356 return CONSISTENT;
3357 }
3358
3359 default:
3360 return BROKEN;
3361 }
3362}
3363
3364InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3365 const MotionEntry* entry) {
3366 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3367 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3368 MotionMemento& memento = mMotionMementos.editItemAt(i);
3369 if (memento.deviceId == entry->deviceId
3370 && memento.source == entry->source) {
3371 switch (action) {
3372 case AMOTION_EVENT_ACTION_UP:
3373 case AMOTION_EVENT_ACTION_CANCEL:
3374 mMotionMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003375 return CONSISTENT;
3376
3377 case AMOTION_EVENT_ACTION_DOWN:
3378 return TOLERABLE;
3379
3380 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3381 if (entry->pointerCount == memento.pointerCount + 1) {
3382 memento.setPointers(entry);
3383 return CONSISTENT;
3384 }
3385 return BROKEN;
3386
3387 case AMOTION_EVENT_ACTION_POINTER_UP:
3388 if (entry->pointerCount == memento.pointerCount - 1) {
3389 memento.setPointers(entry);
3390 return CONSISTENT;
3391 }
3392 return BROKEN;
3393
3394 case AMOTION_EVENT_ACTION_MOVE:
3395 if (entry->pointerCount == memento.pointerCount) {
3396 return CONSISTENT;
3397 }
3398 return BROKEN;
3399
3400 default:
3401 return BROKEN;
3402 }
3403 }
3404 }
3405
3406 switch (action) {
3407 case AMOTION_EVENT_ACTION_DOWN: {
3408 mMotionMementos.push();
3409 MotionMemento& memento = mMotionMementos.editTop();
3410 memento.deviceId = entry->deviceId;
3411 memento.source = entry->source;
3412 memento.xPrecision = entry->xPrecision;
3413 memento.yPrecision = entry->yPrecision;
3414 memento.downTime = entry->downTime;
3415 memento.setPointers(entry);
3416 return CONSISTENT;
3417 }
3418
3419 default:
3420 return BROKEN;
3421 }
3422}
3423
3424void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3425 pointerCount = entry->pointerCount;
3426 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3427 pointerIds[i] = entry->pointerIds[i];
3428 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3429 }
3430}
3431
Jeff Brown90f0cee2010-10-08 22:31:17 -07003432void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3433 Allocator* allocator, Vector<EventEntry*>& outEvents,
3434 CancelationOptions options) {
3435 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003436 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003437 if (shouldCancelEvent(memento.source, options)) {
3438 outEvents.push(allocator->obtainKeyEntry(currentTime,
3439 memento.deviceId, memento.source, 0,
3440 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3441 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3442 mKeyMementos.removeAt(i);
3443 } else {
3444 i += 1;
3445 }
Jeff Browna665ca82010-09-08 11:49:43 -07003446 }
3447
Jeff Brown316237d2010-10-11 18:22:53 -07003448 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003449 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003450 if (shouldCancelEvent(memento.source, options)) {
3451 outEvents.push(allocator->obtainMotionEntry(currentTime,
3452 memento.deviceId, memento.source, 0,
3453 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3454 memento.xPrecision, memento.yPrecision, memento.downTime,
3455 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3456 mMotionMementos.removeAt(i);
3457 } else {
3458 i += 1;
3459 }
Jeff Browna665ca82010-09-08 11:49:43 -07003460 }
3461}
3462
3463void InputDispatcher::InputState::clear() {
3464 mKeyMementos.clear();
3465 mMotionMementos.clear();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003466}
3467
Jeff Brownb6702e52010-10-11 18:32:20 -07003468void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3469 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3470 const MotionMemento& memento = mMotionMementos.itemAt(i);
3471 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3472 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3473 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3474 if (memento.deviceId == otherMemento.deviceId
3475 && memento.source == otherMemento.source) {
3476 other.mMotionMementos.removeAt(j);
3477 } else {
3478 j += 1;
3479 }
3480 }
3481 other.mMotionMementos.push(memento);
3482 }
3483 }
3484}
3485
Jeff Brown90f0cee2010-10-08 22:31:17 -07003486bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3487 CancelationOptions options) {
3488 switch (options) {
3489 case CANCEL_POINTER_EVENTS:
3490 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3491 case CANCEL_NON_POINTER_EVENTS:
3492 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3493 default:
3494 return true;
3495 }
Jeff Browna665ca82010-09-08 11:49:43 -07003496}
3497
3498
Jeff Browne839a582010-04-22 18:58:52 -07003499// --- InputDispatcher::Connection ---
3500
3501InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3502 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003503 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003504}
3505
3506InputDispatcher::Connection::~Connection() {
3507}
3508
3509status_t InputDispatcher::Connection::initialize() {
3510 return inputPublisher.initialize();
3511}
3512
Jeff Brown54bc2812010-06-15 01:31:58 -07003513const char* InputDispatcher::Connection::getStatusLabel() const {
3514 switch (status) {
3515 case STATUS_NORMAL:
3516 return "NORMAL";
3517
3518 case STATUS_BROKEN:
3519 return "BROKEN";
3520
Jeff Brown54bc2812010-06-15 01:31:58 -07003521 case STATUS_ZOMBIE:
3522 return "ZOMBIE";
3523
3524 default:
3525 return "UNKNOWN";
3526 }
3527}
3528
Jeff Browne839a582010-04-22 18:58:52 -07003529InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3530 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003531 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3532 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003533 if (dispatchEntry->eventEntry == eventEntry) {
3534 return dispatchEntry;
3535 }
3536 }
3537 return NULL;
3538}
3539
Jeff Browna665ca82010-09-08 11:49:43 -07003540
Jeff Brown54bc2812010-06-15 01:31:58 -07003541// --- InputDispatcher::CommandEntry ---
3542
Jeff Browna665ca82010-09-08 11:49:43 -07003543InputDispatcher::CommandEntry::CommandEntry() :
3544 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003545}
3546
3547InputDispatcher::CommandEntry::~CommandEntry() {
3548}
3549
Jeff Browne839a582010-04-22 18:58:52 -07003550
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003551// --- InputDispatcher::TouchState ---
3552
3553InputDispatcher::TouchState::TouchState() :
3554 down(false), split(false) {
3555}
3556
3557InputDispatcher::TouchState::~TouchState() {
3558}
3559
3560void InputDispatcher::TouchState::reset() {
3561 down = false;
3562 split = false;
3563 windows.clear();
3564}
3565
3566void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3567 down = other.down;
3568 split = other.split;
3569 windows.clear();
3570 windows.appendVector(other.windows);
3571}
3572
3573void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3574 int32_t targetFlags, BitSet32 pointerIds) {
3575 if (targetFlags & InputTarget::FLAG_SPLIT) {
3576 split = true;
3577 }
3578
3579 for (size_t i = 0; i < windows.size(); i++) {
3580 TouchedWindow& touchedWindow = windows.editItemAt(i);
3581 if (touchedWindow.window == window) {
3582 touchedWindow.targetFlags |= targetFlags;
3583 touchedWindow.pointerIds.value |= pointerIds.value;
3584 return;
3585 }
3586 }
3587
3588 windows.push();
3589
3590 TouchedWindow& touchedWindow = windows.editTop();
3591 touchedWindow.window = window;
3592 touchedWindow.targetFlags = targetFlags;
3593 touchedWindow.pointerIds = pointerIds;
3594 touchedWindow.channel = window->inputChannel;
3595}
3596
3597void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3598 for (size_t i = 0 ; i < windows.size(); ) {
3599 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3600 windows.removeAt(i);
3601 } else {
3602 i += 1;
3603 }
3604 }
3605}
3606
3607const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3608 for (size_t i = 0; i < windows.size(); i++) {
3609 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3610 return windows[i].window;
3611 }
3612 }
3613 return NULL;
3614}
3615
3616
Jeff Browne839a582010-04-22 18:58:52 -07003617// --- InputDispatcherThread ---
3618
3619InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3620 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3621}
3622
3623InputDispatcherThread::~InputDispatcherThread() {
3624}
3625
3626bool InputDispatcherThread::threadLoop() {
3627 mDispatcher->dispatchOnce();
3628 return true;
3629}
3630
3631} // namespace android