blob: c0872e52c27b6e92d1580a76a9d3737ed3c55c13 [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
Johan Redestigbbd0dc82011-02-25 16:45:17 +010040#include <android/input.h>
Jeff Browne839a582010-04-22 18:58:52 -070041#include <cutils/log.h>
Johan Redestigbbd0dc82011-02-25 16:45:17 +010042#include <ui/Input.h>
Jeff Browne839a582010-04-22 18:58:52 -070043#include <ui/InputDispatcher.h>
Jeff Browna665ca82010-09-08 11:49:43 -070044#include <ui/PowerManager.h>
Jeff Browne839a582010-04-22 18:58:52 -070045
46#include <stddef.h>
47#include <unistd.h>
Jeff Browne839a582010-04-22 18:58:52 -070048#include <errno.h>
49#include <limits.h>
Jeff Browne839a582010-04-22 18:58:52 -070050
Jeff Brown2806e382010-10-01 17:46:21 -070051#define INDENT " "
52#define INDENT2 " "
53
Jeff Browne839a582010-04-22 18:58:52 -070054namespace android {
55
Jeff Brownf6149c32010-11-01 20:35:46 -070056// Delay before reporting long touch events to the power manager.
57const nsecs_t LONG_TOUCH_DELAY = 300 * 1000000LL; // 300 ms
Jeff Browna665ca82010-09-08 11:49:43 -070058
59// Default input dispatching timeout if there is no focused application or paused window
60// from which to determine an appropriate dispatching timeout.
61const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
62
63// Amount of time to allow for all pending events to be processed when an app switch
64// key is on the way. This is used to preempt input dispatch and drop input events
65// when an application takes too long to respond and the user has pressed an app switch key.
66const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
67
Jeff Browne839a582010-04-22 18:58:52 -070068
Jeff Brown51d45a72010-06-17 20:52:56 -070069static inline nsecs_t now() {
70 return systemTime(SYSTEM_TIME_MONOTONIC);
71}
72
Jeff Browna665ca82010-09-08 11:49:43 -070073static inline const char* toString(bool value) {
74 return value ? "true" : "false";
75}
76
Jeff Brownd1b0a2b2010-09-26 22:20:12 -070077static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
78 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
79 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
80}
81
82static bool isValidKeyAction(int32_t action) {
83 switch (action) {
84 case AKEY_EVENT_ACTION_DOWN:
85 case AKEY_EVENT_ACTION_UP:
86 return true;
87 default:
88 return false;
89 }
90}
91
92static bool validateKeyEvent(int32_t action) {
93 if (! isValidKeyAction(action)) {
94 LOGE("Key event has invalid action code 0x%x", action);
95 return false;
96 }
97 return true;
98}
99
Jeff Brown90f0cee2010-10-08 22:31:17 -0700100static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700101 switch (action & AMOTION_EVENT_ACTION_MASK) {
102 case AMOTION_EVENT_ACTION_DOWN:
103 case AMOTION_EVENT_ACTION_UP:
104 case AMOTION_EVENT_ACTION_CANCEL:
105 case AMOTION_EVENT_ACTION_MOVE:
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700106 case AMOTION_EVENT_ACTION_OUTSIDE:
107 return true;
Jeff Brown90f0cee2010-10-08 22:31:17 -0700108 case AMOTION_EVENT_ACTION_POINTER_DOWN:
109 case AMOTION_EVENT_ACTION_POINTER_UP: {
110 int32_t index = getMotionEventActionPointerIndex(action);
111 return index >= 0 && size_t(index) < pointerCount;
112 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700113 default:
114 return false;
115 }
116}
117
118static bool validateMotionEvent(int32_t action, size_t pointerCount,
119 const int32_t* pointerIds) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700120 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700121 LOGE("Motion event has invalid action code 0x%x", action);
122 return false;
123 }
124 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
125 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
126 pointerCount, MAX_POINTERS);
127 return false;
128 }
Jeff Brown3c3cc622010-10-20 15:33:38 -0700129 BitSet32 pointerIdBits;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700130 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brown3c3cc622010-10-20 15:33:38 -0700131 int32_t id = pointerIds[i];
132 if (id < 0 || id > MAX_POINTER_ID) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700133 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
Jeff Brown3c3cc622010-10-20 15:33:38 -0700134 id, MAX_POINTER_ID);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700135 return false;
136 }
Jeff Brown3c3cc622010-10-20 15:33:38 -0700137 if (pointerIdBits.hasBit(id)) {
138 LOGE("Motion event has duplicate pointer id %d", id);
139 return false;
140 }
141 pointerIdBits.markBit(id);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700142 }
143 return true;
144}
145
Jeff Browna665ca82010-09-08 11:49:43 -0700146
147// --- InputWindow ---
148
Jeff Browna665ca82010-09-08 11:49:43 -0700149bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
150 return x >= touchableAreaLeft && x <= touchableAreaRight
151 && y >= touchableAreaTop && y <= touchableAreaBottom;
152}
153
Jeff Brown35cf0e92010-10-05 12:26:23 -0700154bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
155 return x >= frameLeft && x <= frameRight
156 && y >= frameTop && y <= frameBottom;
157}
158
159bool InputWindow::isTrustedOverlay() const {
160 return layoutParamsType == TYPE_INPUT_METHOD
Jeff Brownd9dd44d2010-10-15 00:54:27 -0700161 || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
162 || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
Jeff Brown35cf0e92010-10-05 12:26:23 -0700163}
164
Jeff Browna665ca82010-09-08 11:49:43 -0700165
Jeff Browne839a582010-04-22 18:58:52 -0700166// --- InputDispatcher ---
167
Jeff Brown54bc2812010-06-15 01:31:58 -0700168InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Browna665ca82010-09-08 11:49:43 -0700169 mPolicy(policy),
170 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
171 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700172 mFocusedWindow(NULL),
Jeff Browna665ca82010-09-08 11:49:43 -0700173 mFocusedApplication(NULL),
174 mCurrentInputTargetsValid(false),
175 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown59abe7e2010-09-13 23:17:30 -0700176 mLooper = new Looper(false);
Jeff Browne839a582010-04-22 18:58:52 -0700177
Jeff Browna665ca82010-09-08 11:49:43 -0700178 mInboundQueue.headSentinel.refCount = -1;
179 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
180 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Browne839a582010-04-22 18:58:52 -0700181
Jeff Browna665ca82010-09-08 11:49:43 -0700182 mInboundQueue.tailSentinel.refCount = -1;
183 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
184 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Browne839a582010-04-22 18:58:52 -0700185
186 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown54bc2812010-06-15 01:31:58 -0700187
Jeff Brown542412c2010-08-18 15:51:08 -0700188 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
189 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
190 mThrottleState.lastDeviceId = -1;
191
192#if DEBUG_THROTTLING
193 mThrottleState.originalSampleCount = 0;
194 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
195#endif
Jeff Browne839a582010-04-22 18:58:52 -0700196}
197
198InputDispatcher::~InputDispatcher() {
Jeff Browna665ca82010-09-08 11:49:43 -0700199 { // acquire lock
200 AutoMutex _l(mLock);
201
202 resetKeyRepeatLocked();
Jeff Brownd8816c32010-09-16 14:07:33 -0700203 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700204 drainInboundQueueLocked();
205 }
Jeff Browne839a582010-04-22 18:58:52 -0700206
207 while (mConnectionsByReceiveFd.size() != 0) {
208 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
209 }
Jeff Browne839a582010-04-22 18:58:52 -0700210}
211
212void InputDispatcher::dispatchOnce() {
Jeff Brown54bc2812010-06-15 01:31:58 -0700213 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brown61ce3982010-09-07 10:44:57 -0700214 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Browne839a582010-04-22 18:58:52 -0700215
Jeff Browne839a582010-04-22 18:58:52 -0700216 nsecs_t nextWakeupTime = LONG_LONG_MAX;
217 { // acquire lock
218 AutoMutex _l(mLock);
Jeff Browna665ca82010-09-08 11:49:43 -0700219 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Browne839a582010-04-22 18:58:52 -0700220
Jeff Browna665ca82010-09-08 11:49:43 -0700221 if (runCommandsLockedInterruptible()) {
222 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Browne839a582010-04-22 18:58:52 -0700223 }
Jeff Browne839a582010-04-22 18:58:52 -0700224 } // release lock
225
Jeff Browna665ca82010-09-08 11:49:43 -0700226 // Wait for callback or timeout or wake. (make sure we round up, not down)
227 nsecs_t currentTime = now();
228 int32_t timeoutMillis;
229 if (nextWakeupTime > currentTime) {
230 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
231 timeout = (timeout + 999999LL) / 1000000LL;
232 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
233 } else {
234 timeoutMillis = 0;
235 }
236
Jeff Brown59abe7e2010-09-13 23:17:30 -0700237 mLooper->pollOnce(timeoutMillis);
Jeff Browna665ca82010-09-08 11:49:43 -0700238}
239
240void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
241 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
242 nsecs_t currentTime = now();
243
244 // Reset the key repeat timer whenever we disallow key events, even if the next event
245 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
246 // out of sleep.
247 if (keyRepeatTimeout < 0) {
248 resetKeyRepeatLocked();
249 }
250
Jeff Browna665ca82010-09-08 11:49:43 -0700251 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
252 if (mDispatchFrozen) {
253#if DEBUG_FOCUS
254 LOGD("Dispatch frozen. Waiting some more.");
255#endif
256 return;
257 }
258
259 // Optimize latency of app switches.
260 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
261 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
262 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
263 if (mAppSwitchDueTime < *nextWakeupTime) {
264 *nextWakeupTime = mAppSwitchDueTime;
265 }
266
Jeff Browna665ca82010-09-08 11:49:43 -0700267 // Ready to start a new event.
268 // If we don't already have a pending event, go grab one.
269 if (! mPendingEvent) {
270 if (mInboundQueue.isEmpty()) {
271 if (isAppSwitchDue) {
272 // The inbound queue is empty so the app switch key we were waiting
273 // for will never arrive. Stop waiting for it.
274 resetPendingAppSwitchLocked(false);
275 isAppSwitchDue = false;
276 }
277
278 // Synthesize a key repeat if appropriate.
279 if (mKeyRepeatState.lastKeyEntry) {
280 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
281 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
282 } else {
283 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
284 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
285 }
286 }
287 }
288 if (! mPendingEvent) {
289 return;
290 }
291 } else {
292 // Inbound queue has at least one entry.
293 EventEntry* entry = mInboundQueue.headSentinel.next;
294
295 // Throttle the entry if it is a move event and there are no
296 // other events behind it in the queue. Due to movement batching, additional
297 // samples may be appended to this event by the time the throttling timeout
298 // expires.
299 // TODO Make this smarter and consider throttling per device independently.
Jeff Brown90f0cee2010-10-08 22:31:17 -0700300 if (entry->type == EventEntry::TYPE_MOTION
301 && !isAppSwitchDue
302 && mDispatchEnabled
303 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
304 && !entry->isInjected()) {
Jeff Browna665ca82010-09-08 11:49:43 -0700305 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
306 int32_t deviceId = motionEntry->deviceId;
307 uint32_t source = motionEntry->source;
308 if (! isAppSwitchDue
309 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
310 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
311 && deviceId == mThrottleState.lastDeviceId
312 && source == mThrottleState.lastSource) {
313 nsecs_t nextTime = mThrottleState.lastEventTime
314 + mThrottleState.minTimeBetweenEvents;
315 if (currentTime < nextTime) {
316 // Throttle it!
317#if DEBUG_THROTTLING
318 LOGD("Throttling - Delaying motion event for "
319 "device 0x%x, source 0x%08x by up to %0.3fms.",
320 deviceId, source, (nextTime - currentTime) * 0.000001);
321#endif
322 if (nextTime < *nextWakeupTime) {
323 *nextWakeupTime = nextTime;
324 }
325 if (mThrottleState.originalSampleCount == 0) {
326 mThrottleState.originalSampleCount =
327 motionEntry->countSamples();
328 }
329 return;
330 }
331 }
332
333#if DEBUG_THROTTLING
334 if (mThrottleState.originalSampleCount != 0) {
335 uint32_t count = motionEntry->countSamples();
336 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
337 count - mThrottleState.originalSampleCount,
338 mThrottleState.originalSampleCount, count);
339 mThrottleState.originalSampleCount = 0;
340 }
341#endif
342
343 mThrottleState.lastEventTime = entry->eventTime < currentTime
344 ? entry->eventTime : currentTime;
345 mThrottleState.lastDeviceId = deviceId;
346 mThrottleState.lastSource = source;
347 }
348
349 mInboundQueue.dequeue(entry);
350 mPendingEvent = entry;
351 }
Jeff Brownef3a8232010-10-18 13:21:23 -0700352
353 // Poke user activity for this event.
354 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
355 pokeUserActivityLocked(mPendingEvent);
356 }
Jeff Browna665ca82010-09-08 11:49:43 -0700357 }
358
359 // Now we have an event to dispatch.
360 assert(mPendingEvent != NULL);
Jeff Brownd8816c32010-09-16 14:07:33 -0700361 bool done = false;
Jeff Brown90f0cee2010-10-08 22:31:17 -0700362 DropReason dropReason = DROP_REASON_NOT_DROPPED;
363 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
364 dropReason = DROP_REASON_POLICY;
365 } else if (!mDispatchEnabled) {
366 dropReason = DROP_REASON_DISABLED;
367 }
Jeff Browna665ca82010-09-08 11:49:43 -0700368 switch (mPendingEvent->type) {
369 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
370 ConfigurationChangedEntry* typedEntry =
371 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brownd8816c32010-09-16 14:07:33 -0700372 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700373 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Browna665ca82010-09-08 11:49:43 -0700374 break;
375 }
376
377 case EventEntry::TYPE_KEY: {
378 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700379 if (isAppSwitchDue) {
380 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700381 resetPendingAppSwitchLocked(true);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700382 isAppSwitchDue = false;
383 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
384 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700385 }
386 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700387 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700388 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700389 break;
390 }
391
392 case EventEntry::TYPE_MOTION: {
393 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700394 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
395 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700396 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700397 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700398 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700399 break;
400 }
401
402 default:
403 assert(false);
Jeff Browna665ca82010-09-08 11:49:43 -0700404 break;
405 }
406
Jeff Brownd8816c32010-09-16 14:07:33 -0700407 if (done) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700408 if (dropReason != DROP_REASON_NOT_DROPPED) {
409 dropInboundEventLocked(mPendingEvent, dropReason);
410 }
411
Jeff Brownd8816c32010-09-16 14:07:33 -0700412 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700413 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
414 }
415}
416
417bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
418 bool needWake = mInboundQueue.isEmpty();
419 mInboundQueue.enqueueAtTail(entry);
420
421 switch (entry->type) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700422 case EventEntry::TYPE_KEY: {
423 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
424 if (isAppSwitchKeyEventLocked(keyEntry)) {
425 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
426 mAppSwitchSawKeyDown = true;
427 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
428 if (mAppSwitchSawKeyDown) {
429#if DEBUG_APP_SWITCH
430 LOGD("App switch is pending!");
431#endif
432 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
433 mAppSwitchSawKeyDown = false;
434 needWake = true;
435 }
436 }
437 }
Jeff Browna665ca82010-09-08 11:49:43 -0700438 break;
439 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700440 }
Jeff Browna665ca82010-09-08 11:49:43 -0700441
442 return needWake;
443}
444
Jeff Brown90f0cee2010-10-08 22:31:17 -0700445void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
446 const char* reason;
447 switch (dropReason) {
448 case DROP_REASON_POLICY:
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700449#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Browna8ed8562010-10-11 23:32:49 -0700450 LOGD("Dropped event because policy consumed it.");
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700451#endif
Jeff Browna8ed8562010-10-11 23:32:49 -0700452 reason = "inbound event was dropped because the policy consumed it";
Jeff Brown90f0cee2010-10-08 22:31:17 -0700453 break;
454 case DROP_REASON_DISABLED:
455 LOGI("Dropped event because input dispatch is disabled.");
456 reason = "inbound event was dropped because input dispatch is disabled";
457 break;
458 case DROP_REASON_APP_SWITCH:
459 LOGI("Dropped event because of pending overdue app switch.");
460 reason = "inbound event was dropped because of pending overdue app switch";
461 break;
462 default:
463 assert(false);
464 return;
465 }
466
467 switch (entry->type) {
468 case EventEntry::TYPE_KEY:
469 synthesizeCancelationEventsForAllConnectionsLocked(
470 InputState::CANCEL_NON_POINTER_EVENTS, reason);
471 break;
472 case EventEntry::TYPE_MOTION: {
473 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
474 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
475 synthesizeCancelationEventsForAllConnectionsLocked(
476 InputState::CANCEL_POINTER_EVENTS, reason);
477 } else {
478 synthesizeCancelationEventsForAllConnectionsLocked(
479 InputState::CANCEL_NON_POINTER_EVENTS, reason);
480 }
481 break;
482 }
483 }
484}
485
486bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Browna665ca82010-09-08 11:49:43 -0700487 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
488}
489
Jeff Brown90f0cee2010-10-08 22:31:17 -0700490bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
491 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
492 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700493 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brown90f0cee2010-10-08 22:31:17 -0700494 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
495}
496
Jeff Browna665ca82010-09-08 11:49:43 -0700497bool InputDispatcher::isAppSwitchPendingLocked() {
498 return mAppSwitchDueTime != LONG_LONG_MAX;
499}
500
Jeff Browna665ca82010-09-08 11:49:43 -0700501void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
502 mAppSwitchDueTime = LONG_LONG_MAX;
503
504#if DEBUG_APP_SWITCH
505 if (handled) {
506 LOGD("App switch has arrived.");
507 } else {
508 LOGD("App switch was abandoned.");
509 }
510#endif
Jeff Browne839a582010-04-22 18:58:52 -0700511}
512
Jeff Brown54bc2812010-06-15 01:31:58 -0700513bool InputDispatcher::runCommandsLockedInterruptible() {
514 if (mCommandQueue.isEmpty()) {
515 return false;
516 }
Jeff Browne839a582010-04-22 18:58:52 -0700517
Jeff Brown54bc2812010-06-15 01:31:58 -0700518 do {
519 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
520
521 Command command = commandEntry->command;
522 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
523
Jeff Brown51d45a72010-06-17 20:52:56 -0700524 commandEntry->connection.clear();
Jeff Brown54bc2812010-06-15 01:31:58 -0700525 mAllocator.releaseCommandEntry(commandEntry);
526 } while (! mCommandQueue.isEmpty());
527 return true;
Jeff Browne839a582010-04-22 18:58:52 -0700528}
529
Jeff Brown54bc2812010-06-15 01:31:58 -0700530InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
531 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
532 mCommandQueue.enqueueAtTail(commandEntry);
533 return commandEntry;
534}
535
Jeff Browna665ca82010-09-08 11:49:43 -0700536void InputDispatcher::drainInboundQueueLocked() {
537 while (! mInboundQueue.isEmpty()) {
538 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brownd8816c32010-09-16 14:07:33 -0700539 releaseInboundEventLocked(entry);
Jeff Browne839a582010-04-22 18:58:52 -0700540 }
Jeff Browne839a582010-04-22 18:58:52 -0700541}
542
Jeff Brownd8816c32010-09-16 14:07:33 -0700543void InputDispatcher::releasePendingEventLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700544 if (mPendingEvent) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700545 releaseInboundEventLocked(mPendingEvent);
Jeff Browna665ca82010-09-08 11:49:43 -0700546 mPendingEvent = NULL;
547 }
548}
549
Jeff Brownd8816c32010-09-16 14:07:33 -0700550void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700551 InjectionState* injectionState = entry->injectionState;
552 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Browna665ca82010-09-08 11:49:43 -0700553#if DEBUG_DISPATCH_CYCLE
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700554 LOGD("Injected inbound event was dropped.");
Jeff Browna665ca82010-09-08 11:49:43 -0700555#endif
556 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
557 }
558 mAllocator.releaseEventEntry(entry);
559}
560
Jeff Browna665ca82010-09-08 11:49:43 -0700561void InputDispatcher::resetKeyRepeatLocked() {
562 if (mKeyRepeatState.lastKeyEntry) {
563 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
564 mKeyRepeatState.lastKeyEntry = NULL;
565 }
566}
567
568InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brown61ce3982010-09-07 10:44:57 -0700569 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown50de30a2010-06-22 01:27:15 -0700570 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
571
Jeff Brown50de30a2010-06-22 01:27:15 -0700572 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700573 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
574 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Browne839a582010-04-22 18:58:52 -0700575 if (entry->refCount == 1) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700576 mAllocator.recycleKeyEntry(entry);
Jeff Brown51d45a72010-06-17 20:52:56 -0700577 entry->eventTime = currentTime;
Jeff Brown51d45a72010-06-17 20:52:56 -0700578 entry->policyFlags = policyFlags;
Jeff Browne839a582010-04-22 18:58:52 -0700579 entry->repeatCount += 1;
580 } else {
Jeff Brown51d45a72010-06-17 20:52:56 -0700581 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700582 entry->deviceId, entry->source, policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700583 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brownf16c26d2010-07-02 15:37:36 -0700584 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Browne839a582010-04-22 18:58:52 -0700585
586 mKeyRepeatState.lastKeyEntry = newEntry;
587 mAllocator.releaseKeyEntry(entry);
588
589 entry = newEntry;
590 }
Jeff Browna665ca82010-09-08 11:49:43 -0700591 entry->syntheticRepeat = true;
592
593 // Increment reference count since we keep a reference to the event in
594 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
595 entry->refCount += 1;
Jeff Browne839a582010-04-22 18:58:52 -0700596
Jeff Brown61ce3982010-09-07 10:44:57 -0700597 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Browna665ca82010-09-08 11:49:43 -0700598 return entry;
Jeff Browne839a582010-04-22 18:58:52 -0700599}
600
Jeff Browna665ca82010-09-08 11:49:43 -0700601bool InputDispatcher::dispatchConfigurationChangedLocked(
602 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Browne839a582010-04-22 18:58:52 -0700603#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Browna665ca82010-09-08 11:49:43 -0700604 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
605#endif
606
607 // Reset key repeating in case a keyboard device was added or removed or something.
608 resetKeyRepeatLocked();
609
610 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
611 CommandEntry* commandEntry = postCommandLocked(
612 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
613 commandEntry->eventTime = entry->eventTime;
614 return true;
615}
616
617bool InputDispatcher::dispatchKeyLocked(
618 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700619 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brown9cf416c2010-11-02 17:58:22 -0700620 // Preprocessing.
621 if (! entry->dispatchInProgress) {
622 if (entry->repeatCount == 0
623 && entry->action == AKEY_EVENT_ACTION_DOWN
624 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
625 && !entry->isInjected()) {
626 if (mKeyRepeatState.lastKeyEntry
627 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
628 // We have seen two identical key downs in a row which indicates that the device
629 // driver is automatically generating key repeats itself. We take note of the
630 // repeat here, but we disable our own next key repeat timer since it is clear that
631 // we will not need to synthesize key repeats ourselves.
632 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
633 resetKeyRepeatLocked();
634 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
635 } else {
636 // Not a repeat. Save key down state in case we do see a repeat later.
637 resetKeyRepeatLocked();
638 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
639 }
640 mKeyRepeatState.lastKeyEntry = entry;
641 entry->refCount += 1;
642 } else if (! entry->syntheticRepeat) {
643 resetKeyRepeatLocked();
644 }
645
Jeff Brownec7fb802011-03-02 20:49:06 -0800646 if (entry->repeatCount == 1) {
647 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
648 } else {
649 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
650 }
651
Jeff Brown9cf416c2010-11-02 17:58:22 -0700652 entry->dispatchInProgress = true;
653 resetTargetsLocked();
654
655 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
656 }
657
Jeff Brownd8816c32010-09-16 14:07:33 -0700658 // Give the policy a chance to intercept the key.
659 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700660 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700661 CommandEntry* commandEntry = postCommandLocked(
662 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700663 if (mFocusedWindow) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700664 commandEntry->inputChannel = mFocusedWindow->inputChannel;
665 }
666 commandEntry->keyEntry = entry;
667 entry->refCount += 1;
668 return false; // wait for the command to run
669 } else {
670 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
671 }
672 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700673 if (*dropReason == DROP_REASON_NOT_DROPPED) {
674 *dropReason = DROP_REASON_POLICY;
675 }
Jeff Brownd8816c32010-09-16 14:07:33 -0700676 }
677
678 // Clean up if dropping the event.
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700679 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700680 resetTargetsLocked();
Jeff Browna8ed8562010-10-11 23:32:49 -0700681 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
682 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brownd8816c32010-09-16 14:07:33 -0700683 return true;
684 }
685
Jeff Browna665ca82010-09-08 11:49:43 -0700686 // Identify targets.
687 if (! mCurrentInputTargetsValid) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700688 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
689 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700690 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
691 return false;
692 }
693
694 setInjectionResultLocked(entry, injectionResult);
695 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
696 return true;
697 }
698
699 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700700 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700701 }
702
703 // Dispatch the key.
704 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Browna665ca82010-09-08 11:49:43 -0700705 return true;
706}
707
708void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
709#if DEBUG_OUTBOUND_EVENT_DETAILS
710 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
711 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
Jeff Brown9cf416c2010-11-02 17:58:22 -0700712 "repeatCount=%d, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700713 prefix,
714 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
715 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Jeff Brown9cf416c2010-11-02 17:58:22 -0700716 entry->repeatCount, entry->downTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700717#endif
718}
719
720bool InputDispatcher::dispatchMotionLocked(
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700721 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brown9cf416c2010-11-02 17:58:22 -0700722 // Preprocessing.
723 if (! entry->dispatchInProgress) {
724 entry->dispatchInProgress = true;
725 resetTargetsLocked();
726
727 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
728 }
729
Jeff Brownd8816c32010-09-16 14:07:33 -0700730 // Clean up if dropping the event.
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700731 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700732 resetTargetsLocked();
Jeff Browna8ed8562010-10-11 23:32:49 -0700733 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
734 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brownd8816c32010-09-16 14:07:33 -0700735 return true;
736 }
737
Jeff Browna665ca82010-09-08 11:49:43 -0700738 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
739
740 // Identify targets.
741 if (! mCurrentInputTargetsValid) {
Jeff Browna665ca82010-09-08 11:49:43 -0700742 int32_t injectionResult;
743 if (isPointerEvent) {
744 // Pointer event. (eg. touchscreen)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700745 injectionResult = findTouchedWindowTargetsLocked(currentTime,
746 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700747 } else {
748 // Non touch event. (eg. trackball)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700749 injectionResult = findFocusedWindowTargetsLocked(currentTime,
750 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700751 }
752 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
753 return false;
754 }
755
756 setInjectionResultLocked(entry, injectionResult);
757 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
758 return true;
759 }
760
761 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700762 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700763 }
764
765 // Dispatch the motion.
766 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Browna665ca82010-09-08 11:49:43 -0700767 return true;
768}
769
770
771void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
772#if DEBUG_OUTBOUND_EVENT_DETAILS
773 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700774 "action=0x%x, flags=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700775 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700776 prefix,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700777 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
778 entry->action, entry->flags,
Jeff Browne839a582010-04-22 18:58:52 -0700779 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
780 entry->downTime);
781
782 // Print the most recent sample that we have available, this may change due to batching.
783 size_t sampleCount = 1;
Jeff Browna665ca82010-09-08 11:49:43 -0700784 const MotionSample* sample = & entry->firstSample;
Jeff Browne839a582010-04-22 18:58:52 -0700785 for (; sample->next != NULL; sample = sample->next) {
786 sampleCount += 1;
787 }
788 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -0700789 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700790 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -0700791 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -0700792 i, entry->pointerIds[i],
Jeff Brown38a7fab2010-08-30 03:02:23 -0700793 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
794 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
795 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
796 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
797 sample->pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -0700798 }
799
800 // Keep in mind that due to batching, it is possible for the number of samples actually
801 // dispatched to change before the application finally consumed them.
Jeff Brown5c1ed842010-07-14 18:48:53 -0700802 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -0700803 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
804 }
805#endif
Jeff Browne839a582010-04-22 18:58:52 -0700806}
807
808void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
809 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
810#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700811 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700812 "resumeWithAppendedMotionSample=%s",
Jeff Browna665ca82010-09-08 11:49:43 -0700813 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -0700814#endif
815
Jeff Brown54bc2812010-06-15 01:31:58 -0700816 assert(eventEntry->dispatchInProgress); // should already have been set to true
817
Jeff Brownef3a8232010-10-18 13:21:23 -0700818 pokeUserActivityLocked(eventEntry);
819
Jeff Browne839a582010-04-22 18:58:52 -0700820 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
821 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
822
Jeff Brown53a415e2010-09-15 15:18:56 -0700823 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -0700824 if (connectionIndex >= 0) {
825 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown51d45a72010-06-17 20:52:56 -0700826 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -0700827 resumeWithAppendedMotionSample);
828 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700829#if DEBUG_FOCUS
830 LOGD("Dropping event delivery to target with channel '%s' because it "
831 "is no longer registered with the input dispatcher.",
Jeff Browne839a582010-04-22 18:58:52 -0700832 inputTarget.inputChannel->getName().string());
Jeff Brown90f0cee2010-10-08 22:31:17 -0700833#endif
Jeff Browne839a582010-04-22 18:58:52 -0700834 }
835 }
836}
837
Jeff Brownd8816c32010-09-16 14:07:33 -0700838void InputDispatcher::resetTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700839 mCurrentInputTargetsValid = false;
840 mCurrentInputTargets.clear();
Jeff Browna665ca82010-09-08 11:49:43 -0700841 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
842}
843
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700844void InputDispatcher::commitTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700845 mCurrentInputTargetsValid = true;
846}
847
848int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
849 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
850 nsecs_t* nextWakeupTime) {
851 if (application == NULL && window == NULL) {
852 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
853#if DEBUG_FOCUS
854 LOGD("Waiting for system to become ready for input.");
855#endif
856 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
857 mInputTargetWaitStartTime = currentTime;
858 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
859 mInputTargetWaitTimeoutExpired = false;
860 }
861 } else {
862 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
863#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700864 LOGD("Waiting for application to become ready for input: %s",
865 getApplicationWindowLabelLocked(application, window).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700866#endif
867 nsecs_t timeout = window ? window->dispatchingTimeout :
868 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
869
870 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
871 mInputTargetWaitStartTime = currentTime;
872 mInputTargetWaitTimeoutTime = currentTime + timeout;
873 mInputTargetWaitTimeoutExpired = false;
874 }
875 }
876
877 if (mInputTargetWaitTimeoutExpired) {
878 return INPUT_EVENT_INJECTION_TIMED_OUT;
879 }
880
881 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown53a415e2010-09-15 15:18:56 -0700882 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700883
884 // Force poll loop to wake up immediately on next iteration once we get the
885 // ANR response back from the policy.
886 *nextWakeupTime = LONG_LONG_MIN;
887 return INPUT_EVENT_INJECTION_PENDING;
888 } else {
889 // Force poll loop to wake up when timeout is due.
890 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
891 *nextWakeupTime = mInputTargetWaitTimeoutTime;
892 }
893 return INPUT_EVENT_INJECTION_PENDING;
894 }
895}
896
Jeff Brown53a415e2010-09-15 15:18:56 -0700897void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
898 const sp<InputChannel>& inputChannel) {
Jeff Browna665ca82010-09-08 11:49:43 -0700899 if (newTimeout > 0) {
900 // Extend the timeout.
901 mInputTargetWaitTimeoutTime = now() + newTimeout;
902 } else {
903 // Give up.
904 mInputTargetWaitTimeoutExpired = true;
Jeff Brown53a415e2010-09-15 15:18:56 -0700905
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700906 // Release the touch targets.
907 mTouchState.reset();
Jeff Brown405a1d32010-09-16 12:31:46 -0700908
Jeff Brown53a415e2010-09-15 15:18:56 -0700909 // Input state will not be realistic. Mark it out of sync.
Jeff Brown40ad4702010-09-16 11:02:16 -0700910 if (inputChannel.get()) {
911 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
912 if (connectionIndex >= 0) {
913 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700914 synthesizeCancelationEventsForConnectionLocked(
915 connection, InputState::CANCEL_ALL_EVENTS,
916 "application not responding");
Jeff Brown40ad4702010-09-16 11:02:16 -0700917 }
Jeff Brown53a415e2010-09-15 15:18:56 -0700918 }
Jeff Browna665ca82010-09-08 11:49:43 -0700919 }
920}
921
Jeff Brown53a415e2010-09-15 15:18:56 -0700922nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Browna665ca82010-09-08 11:49:43 -0700923 nsecs_t currentTime) {
924 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
925 return currentTime - mInputTargetWaitStartTime;
926 }
927 return 0;
928}
929
930void InputDispatcher::resetANRTimeoutsLocked() {
931#if DEBUG_FOCUS
932 LOGD("Resetting ANR timeouts.");
933#endif
934
Jeff Browna665ca82010-09-08 11:49:43 -0700935 // Reset input target wait timeout.
936 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
937}
938
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700939int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
940 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -0700941 mCurrentInputTargets.clear();
942
943 int32_t injectionResult;
944
945 // If there is no currently focused window and no focused application
946 // then drop the event.
947 if (! mFocusedWindow) {
948 if (mFocusedApplication) {
949#if DEBUG_FOCUS
950 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -0700951 "focused application that may eventually add a window: %s.",
952 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700953#endif
954 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
955 mFocusedApplication, NULL, nextWakeupTime);
956 goto Unresponsive;
957 }
958
959 LOGI("Dropping event because there is no focused window or focused application.");
960 injectionResult = INPUT_EVENT_INJECTION_FAILED;
961 goto Failed;
962 }
963
964 // Check permissions.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700965 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700966 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
967 goto Failed;
968 }
969
970 // If the currently focused window is paused then keep waiting.
971 if (mFocusedWindow->paused) {
972#if DEBUG_FOCUS
973 LOGD("Waiting because focused window is paused.");
974#endif
975 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
976 mFocusedApplication, mFocusedWindow, nextWakeupTime);
977 goto Unresponsive;
978 }
979
Jeff Brown53a415e2010-09-15 15:18:56 -0700980 // If the currently focused window is still working on previous events then keep waiting.
981 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
982#if DEBUG_FOCUS
983 LOGD("Waiting because focused window still processing previous input.");
984#endif
985 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
986 mFocusedApplication, mFocusedWindow, nextWakeupTime);
987 goto Unresponsive;
988 }
989
Jeff Browna665ca82010-09-08 11:49:43 -0700990 // Success! Output targets.
991 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700992 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -0700993
994 // Done.
995Failed:
996Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -0700997 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
998 updateDispatchStatisticsLocked(currentTime, entry,
999 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001000#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -07001001 LOGD("findFocusedWindow finished: injectionResult=%d, "
1002 "timeSpendWaitingForApplication=%0.1fms",
1003 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001004#endif
1005 return injectionResult;
1006}
1007
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001008int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1009 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -07001010 enum InjectionPermission {
1011 INJECTION_PERMISSION_UNKNOWN,
1012 INJECTION_PERMISSION_GRANTED,
1013 INJECTION_PERMISSION_DENIED
1014 };
1015
Jeff Browna665ca82010-09-08 11:49:43 -07001016 mCurrentInputTargets.clear();
1017
1018 nsecs_t startTime = now();
1019
1020 // For security reasons, we defer updating the touch state until we are sure that
1021 // event injection will be allowed.
1022 //
1023 // FIXME In the original code, screenWasOff could never be set to true.
1024 // The reason is that the POLICY_FLAG_WOKE_HERE
1025 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1026 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1027 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1028 // events upon which no preprocessing took place. So policyFlags was always 0.
1029 // In the new native input dispatcher we're a bit more careful about event
1030 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1031 // Unfortunately we obtain undesirable behavior.
1032 //
1033 // Here's what happens:
1034 //
1035 // When the device dims in anticipation of going to sleep, touches
1036 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1037 // the device to brighten and reset the user activity timer.
1038 // Touches on other windows (such as the launcher window)
1039 // are dropped. Then after a moment, the device goes to sleep. Oops.
1040 //
1041 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1042 // instead of POLICY_FLAG_WOKE_HERE...
1043 //
1044 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1045
1046 int32_t action = entry->action;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001047 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Browna665ca82010-09-08 11:49:43 -07001048
1049 // Update the touch state as needed based on the properties of the touch event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001050 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1051 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1052 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1053 mTempTouchState.reset();
1054 mTempTouchState.down = true;
1055 } else {
1056 mTempTouchState.copyFrom(mTouchState);
1057 }
Jeff Browna665ca82010-09-08 11:49:43 -07001058
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001059 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1060 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1061 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1062 /* Case 1: New splittable pointer going down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001063
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001064 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1065 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1066 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1067 const InputWindow* newTouchedWindow = NULL;
1068 const InputWindow* topErrorWindow = NULL;
Jeff Browna665ca82010-09-08 11:49:43 -07001069
1070 // Traverse windows from front to back to find touched window and outside targets.
1071 size_t numWindows = mWindows.size();
1072 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001073 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07001074 int32_t flags = window->layoutParamsFlags;
1075
1076 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1077 if (! topErrorWindow) {
1078 topErrorWindow = window;
1079 }
1080 }
1081
1082 if (window->visible) {
1083 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1084 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1085 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1086 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1087 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1088 newTouchedWindow = window;
Jeff Browna665ca82010-09-08 11:49:43 -07001089 }
1090 break; // found touched window, exit window loop
1091 }
1092 }
1093
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001094 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1095 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001096 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1097 if (isWindowObscuredAtPointLocked(window, x, y)) {
1098 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1099 }
1100
1101 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -07001102 }
1103 }
1104 }
1105
1106 // If there is an error window but it is not taking focus (typically because
1107 // it is invisible) then wait for it. Any other focused window may in
1108 // fact be in ANR state.
1109 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1110#if DEBUG_FOCUS
1111 LOGD("Waiting because system error window is pending.");
1112#endif
1113 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1114 NULL, NULL, nextWakeupTime);
1115 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1116 goto Unresponsive;
1117 }
1118
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001119 // Figure out whether splitting will be allowed for this window.
Jeff Brown1c322582010-09-28 13:24:41 -07001120 if (newTouchedWindow
1121 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001122 // New window supports splitting.
1123 isSplit = true;
1124 } else if (isSplit) {
1125 // New window does not support splitting but we have already split events.
1126 // Assign the pointer to the first foreground window we find.
1127 // (May be NULL which is why we put this code block before the next check.)
1128 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1129 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001130
Jeff Browna665ca82010-09-08 11:49:43 -07001131 // If we did not find a touched window then fail.
1132 if (! newTouchedWindow) {
1133 if (mFocusedApplication) {
1134#if DEBUG_FOCUS
1135 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -07001136 "focused application that may eventually add a new window: %s.",
1137 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -07001138#endif
1139 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1140 mFocusedApplication, NULL, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -07001141 goto Unresponsive;
1142 }
1143
1144 LOGI("Dropping event because there is no touched window or focused application.");
1145 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001146 goto Failed;
1147 }
1148
Jeff Brown35cf0e92010-10-05 12:26:23 -07001149 // Set target flags.
1150 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1151 if (isSplit) {
1152 targetFlags |= InputTarget::FLAG_SPLIT;
1153 }
1154 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1155 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1156 }
1157
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001158 // Update the temporary touch state.
1159 BitSet32 pointerIds;
1160 if (isSplit) {
1161 uint32_t pointerId = entry->pointerIds[pointerIndex];
1162 pointerIds.markBit(pointerId);
Jeff Browna665ca82010-09-08 11:49:43 -07001163 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001164 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001165 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001166 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001167
1168 // If the pointer is not currently down, then ignore the event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001169 if (! mTempTouchState.down) {
Jeff Browna665ca82010-09-08 11:49:43 -07001170 LOGI("Dropping event because the pointer is not down.");
1171 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001172 goto Failed;
1173 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001174 }
Jeff Browna665ca82010-09-08 11:49:43 -07001175
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001176 // Check permission to inject into all touched foreground windows and ensure there
1177 // is at least one touched foreground window.
1178 {
1179 bool haveForegroundWindow = false;
1180 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1181 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1182 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1183 haveForegroundWindow = true;
1184 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1185 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1186 injectionPermission = INJECTION_PERMISSION_DENIED;
1187 goto Failed;
1188 }
1189 }
1190 }
1191 if (! haveForegroundWindow) {
Jeff Browna665ca82010-09-08 11:49:43 -07001192#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001193 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Browna665ca82010-09-08 11:49:43 -07001194#endif
1195 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001196 goto Failed;
1197 }
1198
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001199 // Permission granted to injection into all touched foreground windows.
1200 injectionPermission = INJECTION_PERMISSION_GRANTED;
1201 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001202
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001203 // Ensure all touched foreground windows are ready for new input.
1204 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1205 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1206 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1207 // If the touched window is paused then keep waiting.
1208 if (touchedWindow.window->paused) {
1209#if DEBUG_INPUT_DISPATCHER_POLICY
1210 LOGD("Waiting because touched window is paused.");
Jeff Brown53a415e2010-09-15 15:18:56 -07001211#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001212 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1213 NULL, touchedWindow.window, nextWakeupTime);
1214 goto Unresponsive;
1215 }
1216
1217 // If the touched window is still working on previous events then keep waiting.
1218 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1219#if DEBUG_FOCUS
1220 LOGD("Waiting because touched window still processing previous input.");
1221#endif
1222 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1223 NULL, touchedWindow.window, nextWakeupTime);
1224 goto Unresponsive;
1225 }
1226 }
1227 }
1228
1229 // If this is the first pointer going down and the touched window has a wallpaper
1230 // then also add the touched wallpaper windows so they are locked in for the duration
1231 // of the touch gesture.
1232 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1233 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1234 if (foregroundWindow->hasWallpaper) {
1235 for (size_t i = 0; i < mWindows.size(); i++) {
1236 const InputWindow* window = & mWindows[i];
1237 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001238 mTempTouchState.addOrUpdateWindow(window,
1239 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001240 }
1241 }
1242 }
1243 }
1244
Jeff Browna665ca82010-09-08 11:49:43 -07001245 // Success! Output targets.
1246 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Browna665ca82010-09-08 11:49:43 -07001247
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001248 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1249 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1250 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1251 touchedWindow.pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001252 }
1253
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001254 // Drop the outside touch window since we will not care about them in the next iteration.
1255 mTempTouchState.removeOutsideTouchWindows();
1256
Jeff Browna665ca82010-09-08 11:49:43 -07001257Failed:
1258 // Check injection permission once and for all.
1259 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001260 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001261 injectionPermission = INJECTION_PERMISSION_GRANTED;
1262 } else {
1263 injectionPermission = INJECTION_PERMISSION_DENIED;
1264 }
1265 }
1266
1267 // Update final pieces of touch state if the injector had permission.
1268 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001269 if (maskedAction == AMOTION_EVENT_ACTION_UP
1270 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1271 // All pointers up or canceled.
1272 mTempTouchState.reset();
1273 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1274 // First pointer went down.
1275 if (mTouchState.down) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001276#if DEBUG_FOCUS
1277 LOGD("Pointer down received while already down.");
1278#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001279 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001280 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1281 // One pointer went up.
1282 if (isSplit) {
1283 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1284 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Browna665ca82010-09-08 11:49:43 -07001285
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001286 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1287 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1288 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1289 touchedWindow.pointerIds.clearBit(pointerId);
1290 if (touchedWindow.pointerIds.isEmpty()) {
1291 mTempTouchState.windows.removeAt(i);
1292 continue;
1293 }
1294 }
1295 i += 1;
1296 }
Jeff Browna665ca82010-09-08 11:49:43 -07001297 }
Jeff Browna665ca82010-09-08 11:49:43 -07001298 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001299
1300 // Save changes to touch state.
1301 mTouchState.copyFrom(mTempTouchState);
Jeff Browna665ca82010-09-08 11:49:43 -07001302 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001303#if DEBUG_FOCUS
1304 LOGD("Not updating touch focus because injection was denied.");
1305#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001306 }
1307
1308Unresponsive:
Jeff Brownfef5b042010-10-27 18:43:51 -07001309 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1310 mTempTouchState.reset();
1311
Jeff Brown53a415e2010-09-15 15:18:56 -07001312 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1313 updateDispatchStatisticsLocked(currentTime, entry,
1314 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001315#if DEBUG_FOCUS
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001316 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1317 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown53a415e2010-09-15 15:18:56 -07001318 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001319#endif
1320 return injectionResult;
1321}
1322
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001323void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1324 BitSet32 pointerIds) {
Jeff Browna665ca82010-09-08 11:49:43 -07001325 mCurrentInputTargets.push();
1326
1327 InputTarget& target = mCurrentInputTargets.editTop();
1328 target.inputChannel = window->inputChannel;
1329 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001330 target.xOffset = - window->frameLeft;
1331 target.yOffset = - window->frameTop;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001332 target.pointerIds = pointerIds;
Jeff Browna665ca82010-09-08 11:49:43 -07001333}
1334
1335void InputDispatcher::addMonitoringTargetsLocked() {
1336 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1337 mCurrentInputTargets.push();
1338
1339 InputTarget& target = mCurrentInputTargets.editTop();
1340 target.inputChannel = mMonitoringChannels[i];
1341 target.flags = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07001342 target.xOffset = 0;
1343 target.yOffset = 0;
1344 }
1345}
1346
1347bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001348 const InjectionState* injectionState) {
1349 if (injectionState
Jeff Brown90f0cee2010-10-08 22:31:17 -07001350 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1351 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1352 if (window) {
1353 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1354 "with input channel %s owned by uid %d",
1355 injectionState->injectorPid, injectionState->injectorUid,
1356 window->inputChannel->getName().string(),
1357 window->ownerUid);
1358 } else {
1359 LOGW("Permission denied: injecting event from pid %d uid %d",
1360 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-09-08 11:49:43 -07001361 }
Jeff Brown90f0cee2010-10-08 22:31:17 -07001362 return false;
Jeff Browna665ca82010-09-08 11:49:43 -07001363 }
1364 return true;
1365}
1366
Jeff Brown35cf0e92010-10-05 12:26:23 -07001367bool InputDispatcher::isWindowObscuredAtPointLocked(
1368 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Browna665ca82010-09-08 11:49:43 -07001369 size_t numWindows = mWindows.size();
1370 for (size_t i = 0; i < numWindows; i++) {
1371 const InputWindow* other = & mWindows.itemAt(i);
1372 if (other == window) {
1373 break;
1374 }
Jeff Brown35cf0e92010-10-05 12:26:23 -07001375 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001376 return true;
1377 }
1378 }
1379 return false;
1380}
1381
Jeff Brown53a415e2010-09-15 15:18:56 -07001382bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1383 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1384 if (connectionIndex >= 0) {
1385 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1386 return connection->outboundQueue.isEmpty();
1387 } else {
1388 return true;
1389 }
1390}
1391
1392String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1393 const InputWindow* window) {
1394 if (application) {
1395 if (window) {
1396 String8 label(application->name);
1397 label.append(" - ");
1398 label.append(window->name);
1399 return label;
1400 } else {
1401 return application->name;
1402 }
1403 } else if (window) {
1404 return window->name;
1405 } else {
1406 return String8("<unknown application or window>");
1407 }
1408}
1409
Jeff Brownef3a8232010-10-18 13:21:23 -07001410void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1411 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Browne7a0d2b2010-10-29 21:50:21 -07001412 switch (eventEntry->type) {
1413 case EventEntry::TYPE_MOTION: {
Jeff Brownef3a8232010-10-18 13:21:23 -07001414 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Browne7a0d2b2010-10-29 21:50:21 -07001415 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1416 return;
1417 }
1418
Jeff Brownef3a8232010-10-18 13:21:23 -07001419 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1420 switch (motionEntry->action) {
1421 case AMOTION_EVENT_ACTION_DOWN:
1422 eventType = POWER_MANAGER_TOUCH_EVENT;
1423 break;
1424 case AMOTION_EVENT_ACTION_UP:
1425 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
1426 break;
1427 default:
Jeff Brownf6149c32010-11-01 20:35:46 -07001428 if (motionEntry->eventTime - motionEntry->downTime < LONG_TOUCH_DELAY) {
Jeff Brownef3a8232010-10-18 13:21:23 -07001429 eventType = POWER_MANAGER_TOUCH_EVENT;
1430 } else {
1431 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
1432 }
1433 break;
1434 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001435 }
Jeff Browne7a0d2b2010-10-29 21:50:21 -07001436 break;
1437 }
1438 case EventEntry::TYPE_KEY: {
1439 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1440 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1441 return;
1442 }
1443 break;
1444 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001445 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001446
Jeff Browna665ca82010-09-08 11:49:43 -07001447 CommandEntry* commandEntry = postCommandLocked(
1448 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Brownef3a8232010-10-18 13:21:23 -07001449 commandEntry->eventTime = eventEntry->eventTime;
Jeff Browna665ca82010-09-08 11:49:43 -07001450 commandEntry->userActivityEventType = eventType;
1451}
1452
Jeff Brown51d45a72010-06-17 20:52:56 -07001453void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1454 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -07001455 bool resumeWithAppendedMotionSample) {
1456#if DEBUG_DISPATCH_CYCLE
Jeff Brown53a415e2010-09-15 15:18:56 -07001457 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001458 "xOffset=%f, yOffset=%f, "
1459 "windowType=%d, pointerIds=0x%x, "
1460 "resumeWithAppendedMotionSample=%s",
Jeff Brown53a415e2010-09-15 15:18:56 -07001461 connection->getInputChannelName(), inputTarget->flags,
Jeff Browne839a582010-04-22 18:58:52 -07001462 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001463 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Browna665ca82010-09-08 11:49:43 -07001464 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -07001465#endif
1466
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001467 // Make sure we are never called for streaming when splitting across multiple windows.
1468 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1469 assert(! (resumeWithAppendedMotionSample && isSplit));
1470
Jeff Browne839a582010-04-22 18:58:52 -07001471 // Skip this event if the connection status is not normal.
Jeff Brown53a415e2010-09-15 15:18:56 -07001472 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Browne839a582010-04-22 18:58:52 -07001473 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001474#if DEBUG_DISPATCH_CYCLE
1475 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Browna665ca82010-09-08 11:49:43 -07001476 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown90f0cee2010-10-08 22:31:17 -07001477#endif
Jeff Browne839a582010-04-22 18:58:52 -07001478 return;
1479 }
1480
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001481 // Split a motion event if needed.
1482 if (isSplit) {
1483 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1484
1485 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1486 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1487 MotionEntry* splitMotionEntry = splitMotionEvent(
1488 originalMotionEntry, inputTarget->pointerIds);
1489#if DEBUG_FOCUS
1490 LOGD("channel '%s' ~ Split motion event.",
1491 connection->getInputChannelName());
1492 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1493#endif
1494 eventEntry = splitMotionEntry;
1495 }
1496 }
1497
Jeff Browne839a582010-04-22 18:58:52 -07001498 // Resume the dispatch cycle with a freshly appended motion sample.
1499 // First we check that the last dispatch entry in the outbound queue is for the same
1500 // motion event to which we appended the motion sample. If we find such a dispatch
1501 // entry, and if it is currently in progress then we try to stream the new sample.
1502 bool wasEmpty = connection->outboundQueue.isEmpty();
1503
1504 if (! wasEmpty && resumeWithAppendedMotionSample) {
1505 DispatchEntry* motionEventDispatchEntry =
1506 connection->findQueuedDispatchEntryForEvent(eventEntry);
1507 if (motionEventDispatchEntry) {
1508 // If the dispatch entry is not in progress, then we must be busy dispatching an
1509 // earlier event. Not a problem, the motion event is on the outbound queue and will
1510 // be dispatched later.
1511 if (! motionEventDispatchEntry->inProgress) {
1512#if DEBUG_BATCHING
1513 LOGD("channel '%s' ~ Not streaming because the motion event has "
1514 "not yet been dispatched. "
1515 "(Waiting for earlier events to be consumed.)",
1516 connection->getInputChannelName());
1517#endif
1518 return;
1519 }
1520
1521 // If the dispatch entry is in progress but it already has a tail of pending
1522 // motion samples, then it must mean that the shared memory buffer filled up.
1523 // Not a problem, when this dispatch cycle is finished, we will eventually start
1524 // a new dispatch cycle to process the tail and that tail includes the newly
1525 // appended motion sample.
1526 if (motionEventDispatchEntry->tailMotionSample) {
1527#if DEBUG_BATCHING
1528 LOGD("channel '%s' ~ Not streaming because no new samples can "
1529 "be appended to the motion event in this dispatch cycle. "
1530 "(Waiting for next dispatch cycle to start.)",
1531 connection->getInputChannelName());
1532#endif
1533 return;
1534 }
1535
1536 // The dispatch entry is in progress and is still potentially open for streaming.
1537 // Try to stream the new motion sample. This might fail if the consumer has already
1538 // consumed the motion event (or if the channel is broken).
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001539 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1540 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Browne839a582010-04-22 18:58:52 -07001541 status_t status = connection->inputPublisher.appendMotionSample(
1542 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1543 if (status == OK) {
1544#if DEBUG_BATCHING
1545 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1546 connection->getInputChannelName());
1547#endif
1548 return;
1549 }
1550
1551#if DEBUG_BATCHING
1552 if (status == NO_MEMORY) {
1553 LOGD("channel '%s' ~ Could not append motion sample to currently "
1554 "dispatched move event because the shared memory buffer is full. "
1555 "(Waiting for next dispatch cycle to start.)",
1556 connection->getInputChannelName());
1557 } else if (status == status_t(FAILED_TRANSACTION)) {
1558 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown50de30a2010-06-22 01:27:15 -07001559 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-04-22 18:58:52 -07001560 "(Waiting for next dispatch cycle to start.)",
1561 connection->getInputChannelName());
1562 } else {
1563 LOGD("channel '%s' ~ Could not append motion sample to currently "
1564 "dispatched move event due to an error, status=%d. "
1565 "(Waiting for next dispatch cycle to start.)",
1566 connection->getInputChannelName(), status);
1567 }
1568#endif
1569 // Failed to stream. Start a new tail of pending motion samples to dispatch
1570 // in the next cycle.
1571 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1572 return;
1573 }
1574 }
1575
1576 // This is a new event.
1577 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Browna665ca82010-09-08 11:49:43 -07001578 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown53a415e2010-09-15 15:18:56 -07001579 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1580 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001581 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001582 }
1583
Jeff Browne839a582010-04-22 18:58:52 -07001584 // Handle the case where we could not stream a new motion sample because the consumer has
1585 // already consumed the motion event (otherwise the corresponding dispatch entry would
1586 // still be in the outbound queue for this connection). We set the head motion sample
1587 // to the list starting with the newly appended motion sample.
1588 if (resumeWithAppendedMotionSample) {
1589#if DEBUG_BATCHING
1590 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1591 "that cannot be streamed because the motion event has already been consumed.",
1592 connection->getInputChannelName());
1593#endif
1594 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1595 dispatchEntry->headMotionSample = appendedMotionSample;
1596 }
1597
1598 // Enqueue the dispatch entry.
1599 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1600
1601 // If the outbound queue was previously empty, start the dispatch cycle going.
1602 if (wasEmpty) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001603 activateConnectionLocked(connection.get());
Jeff Brown53a415e2010-09-15 15:18:56 -07001604 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001605 }
1606}
1607
Jeff Brown51d45a72010-06-17 20:52:56 -07001608void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown53a415e2010-09-15 15:18:56 -07001609 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001610#if DEBUG_DISPATCH_CYCLE
1611 LOGD("channel '%s' ~ startDispatchCycle",
1612 connection->getInputChannelName());
1613#endif
1614
1615 assert(connection->status == Connection::STATUS_NORMAL);
1616 assert(! connection->outboundQueue.isEmpty());
1617
Jeff Browna665ca82010-09-08 11:49:43 -07001618 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001619 assert(! dispatchEntry->inProgress);
1620
Jeff Browna665ca82010-09-08 11:49:43 -07001621 // Mark the dispatch entry as in progress.
1622 dispatchEntry->inProgress = true;
1623
1624 // Update the connection's input state.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001625 EventEntry* eventEntry = dispatchEntry->eventEntry;
1626 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001627
1628#if FILTER_INPUT_EVENTS
1629 // Filter out inconsistent sequences of input events.
1630 // The input system may drop or inject events in a way that could violate implicit
1631 // invariants on input state and potentially cause an application to crash
1632 // or think that a key or pointer is stuck down. Technically we make no guarantees
1633 // of consistency but it would be nice to improve on this where possible.
1634 // XXX: This code is a proof of concept only. Not ready for prime time.
1635 if (consistency == InputState::TOLERABLE) {
1636#if DEBUG_DISPATCH_CYCLE
1637 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1638 "current input state but that is likely to be tolerated by the application.",
1639 connection->getInputChannelName());
1640#endif
1641 } else if (consistency == InputState::BROKEN) {
1642 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1643 "current input state and that is likely to cause the application to crash.",
1644 connection->getInputChannelName());
1645 startNextDispatchCycleLocked(currentTime, connection);
1646 return;
1647 }
1648#endif
Jeff Browne839a582010-04-22 18:58:52 -07001649
1650 // Publish the event.
1651 status_t status;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001652 switch (eventEntry->type) {
Jeff Browne839a582010-04-22 18:58:52 -07001653 case EventEntry::TYPE_KEY: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001654 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001655
1656 // Apply target flags.
1657 int32_t action = keyEntry->action;
1658 int32_t flags = keyEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001659
1660 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001661 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-04-22 18:58:52 -07001662 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1663 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1664 keyEntry->eventTime);
1665
1666 if (status) {
1667 LOGE("channel '%s' ~ Could not publish key event, "
1668 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001669 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001670 return;
1671 }
1672 break;
1673 }
1674
1675 case EventEntry::TYPE_MOTION: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001676 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001677
1678 // Apply target flags.
1679 int32_t action = motionEntry->action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07001680 int32_t flags = motionEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001681 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001682 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -07001683 }
Jeff Brownaf30ff62010-09-01 17:01:00 -07001684 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1685 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1686 }
Jeff Browne839a582010-04-22 18:58:52 -07001687
1688 // If headMotionSample is non-NULL, then it points to the first new sample that we
1689 // were unable to dispatch during the previous cycle so we resume dispatching from
1690 // that point in the list of motion samples.
1691 // Otherwise, we just start from the first sample of the motion event.
1692 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1693 if (! firstMotionSample) {
1694 firstMotionSample = & motionEntry->firstSample;
1695 }
1696
Jeff Brownf26db0d2010-07-16 17:21:06 -07001697 // Set the X and Y offset depending on the input source.
1698 float xOffset, yOffset;
1699 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1700 xOffset = dispatchEntry->xOffset;
1701 yOffset = dispatchEntry->yOffset;
1702 } else {
1703 xOffset = 0.0f;
1704 yOffset = 0.0f;
1705 }
1706
Jeff Browne839a582010-04-22 18:58:52 -07001707 // Publish the motion event and the first motion sample.
1708 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001709 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -07001710 xOffset, yOffset,
Jeff Browne839a582010-04-22 18:58:52 -07001711 motionEntry->xPrecision, motionEntry->yPrecision,
1712 motionEntry->downTime, firstMotionSample->eventTime,
1713 motionEntry->pointerCount, motionEntry->pointerIds,
1714 firstMotionSample->pointerCoords);
1715
1716 if (status) {
1717 LOGE("channel '%s' ~ Could not publish motion event, "
1718 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001719 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001720 return;
1721 }
1722
1723 // Append additional motion samples.
1724 MotionSample* nextMotionSample = firstMotionSample->next;
1725 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1726 status = connection->inputPublisher.appendMotionSample(
1727 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1728 if (status == NO_MEMORY) {
1729#if DEBUG_DISPATCH_CYCLE
1730 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1731 "be sent in the next dispatch cycle.",
1732 connection->getInputChannelName());
1733#endif
1734 break;
1735 }
1736 if (status != OK) {
1737 LOGE("channel '%s' ~ Could not append motion sample "
1738 "for a reason other than out of memory, status=%d",
1739 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001740 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001741 return;
1742 }
1743 }
1744
1745 // Remember the next motion sample that we could not dispatch, in case we ran out
1746 // of space in the shared memory buffer.
1747 dispatchEntry->tailMotionSample = nextMotionSample;
1748 break;
1749 }
1750
1751 default: {
1752 assert(false);
1753 }
1754 }
1755
1756 // Send the dispatch signal.
1757 status = connection->inputPublisher.sendDispatchSignal();
1758 if (status) {
1759 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1760 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001761 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001762 return;
1763 }
1764
1765 // Record information about the newly started dispatch cycle.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001766 connection->lastEventTime = eventEntry->eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07001767 connection->lastDispatchTime = currentTime;
1768
Jeff Browne839a582010-04-22 18:58:52 -07001769 // Notify other system components.
1770 onDispatchCycleStartedLocked(currentTime, connection);
1771}
1772
Jeff Brown51d45a72010-06-17 20:52:56 -07001773void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1774 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001775#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001776 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -07001777 "%01.1fms since dispatch",
1778 connection->getInputChannelName(),
1779 connection->getEventLatencyMillis(currentTime),
1780 connection->getDispatchLatencyMillis(currentTime));
1781#endif
1782
Jeff Brown54bc2812010-06-15 01:31:58 -07001783 if (connection->status == Connection::STATUS_BROKEN
1784 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001785 return;
1786 }
1787
Jeff Brown53a415e2010-09-15 15:18:56 -07001788 // Notify other system components.
1789 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001790
1791 // Reset the publisher since the event has been consumed.
1792 // We do this now so that the publisher can release some of its internal resources
1793 // while waiting for the next dispatch cycle to begin.
1794 status_t status = connection->inputPublisher.reset();
1795 if (status) {
1796 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1797 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001798 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001799 return;
1800 }
1801
Jeff Browna665ca82010-09-08 11:49:43 -07001802 startNextDispatchCycleLocked(currentTime, connection);
1803}
1804
1805void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1806 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001807 // Start the next dispatch cycle for this connection.
1808 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001809 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001810 if (dispatchEntry->inProgress) {
1811 // Finish or resume current event in progress.
1812 if (dispatchEntry->tailMotionSample) {
1813 // We have a tail of undispatched motion samples.
1814 // Reuse the same DispatchEntry and start a new cycle.
1815 dispatchEntry->inProgress = false;
1816 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1817 dispatchEntry->tailMotionSample = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07001818 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001819 return;
1820 }
1821 // Finished.
1822 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001823 if (dispatchEntry->hasForegroundTarget()) {
1824 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001825 }
Jeff Browne839a582010-04-22 18:58:52 -07001826 mAllocator.releaseDispatchEntry(dispatchEntry);
1827 } else {
1828 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown53a415e2010-09-15 15:18:56 -07001829 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001830 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001831 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001832 return;
1833 }
1834 }
1835
1836 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001837 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001838}
1839
Jeff Brown90f0cee2010-10-08 22:31:17 -07001840void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1841 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001842#if DEBUG_DISPATCH_CYCLE
Jeff Brown90f0cee2010-10-08 22:31:17 -07001843 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001844 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001845#endif
1846
Jeff Browna665ca82010-09-08 11:49:43 -07001847 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001848 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001849
Jeff Brown90f0cee2010-10-08 22:31:17 -07001850 // The connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001851 // Ignore already broken or zombie connections.
Jeff Brown90f0cee2010-10-08 22:31:17 -07001852 if (connection->status == Connection::STATUS_NORMAL) {
1853 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001854
Jeff Brown90f0cee2010-10-08 22:31:17 -07001855 // Notify other system components.
1856 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001857 }
Jeff Browne839a582010-04-22 18:58:52 -07001858}
1859
Jeff Brown53a415e2010-09-15 15:18:56 -07001860void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1861 while (! connection->outboundQueue.isEmpty()) {
1862 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1863 if (dispatchEntry->hasForegroundTarget()) {
1864 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001865 }
1866 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001867 }
1868
Jeff Brown53a415e2010-09-15 15:18:56 -07001869 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001870}
1871
Jeff Brown59abe7e2010-09-13 23:17:30 -07001872int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-04-22 18:58:52 -07001873 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1874
1875 { // acquire lock
1876 AutoMutex _l(d->mLock);
1877
1878 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1879 if (connectionIndex < 0) {
1880 LOGE("Received spurious receive callback for unknown input channel. "
1881 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001882 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001883 }
1884
Jeff Brown51d45a72010-06-17 20:52:56 -07001885 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001886
1887 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001888 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-04-22 18:58:52 -07001889 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1890 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001891 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001892 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001893 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001894 }
1895
Jeff Brown59abe7e2010-09-13 23:17:30 -07001896 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001897 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1898 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001899 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001900 }
1901
1902 status_t status = connection->inputPublisher.receiveFinishedSignal();
1903 if (status) {
1904 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1905 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001906 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001907 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001908 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001909 }
1910
Jeff Brown51d45a72010-06-17 20:52:56 -07001911 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001912 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001913 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001914 } // release lock
1915}
1916
Jeff Brown90f0cee2010-10-08 22:31:17 -07001917void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1918 InputState::CancelationOptions options, const char* reason) {
1919 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1920 synthesizeCancelationEventsForConnectionLocked(
1921 mConnectionsByReceiveFd.valueAt(i), options, reason);
1922 }
1923}
1924
1925void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1926 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1927 const char* reason) {
1928 ssize_t index = getConnectionIndexLocked(channel);
1929 if (index >= 0) {
1930 synthesizeCancelationEventsForConnectionLocked(
1931 mConnectionsByReceiveFd.valueAt(index), options, reason);
1932 }
1933}
1934
1935void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1936 const sp<Connection>& connection, InputState::CancelationOptions options,
1937 const char* reason) {
1938 nsecs_t currentTime = now();
1939
1940 mTempCancelationEvents.clear();
1941 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1942 mTempCancelationEvents, options);
1943
1944 if (! mTempCancelationEvents.isEmpty()
1945 && connection->status != Connection::STATUS_BROKEN) {
1946#if DEBUG_OUTBOUND_EVENT_DETAILS
1947 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1948 "with reality: %s, options=%d.",
1949 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1950#endif
1951 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1952 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1953 switch (cancelationEventEntry->type) {
1954 case EventEntry::TYPE_KEY:
1955 logOutboundKeyDetailsLocked("cancel - ",
1956 static_cast<KeyEntry*>(cancelationEventEntry));
1957 break;
1958 case EventEntry::TYPE_MOTION:
1959 logOutboundMotionDetailsLocked("cancel - ",
1960 static_cast<MotionEntry*>(cancelationEventEntry));
1961 break;
1962 }
1963
1964 int32_t xOffset, yOffset;
1965 const InputWindow* window = getWindowLocked(connection->inputChannel);
1966 if (window) {
1967 xOffset = -window->frameLeft;
1968 yOffset = -window->frameTop;
1969 } else {
1970 xOffset = 0;
1971 yOffset = 0;
1972 }
1973
1974 DispatchEntry* cancelationDispatchEntry =
1975 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1976 0, xOffset, yOffset);
1977 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1978
1979 mAllocator.releaseEventEntry(cancelationEventEntry);
1980 }
1981
1982 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1983 startDispatchCycleLocked(currentTime, connection);
1984 }
1985 }
1986}
1987
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001988InputDispatcher::MotionEntry*
1989InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1990 assert(pointerIds.value != 0);
1991
1992 uint32_t splitPointerIndexMap[MAX_POINTERS];
1993 int32_t splitPointerIds[MAX_POINTERS];
1994 PointerCoords splitPointerCoords[MAX_POINTERS];
1995
1996 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1997 uint32_t splitPointerCount = 0;
1998
1999 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2000 originalPointerIndex++) {
2001 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
2002 if (pointerIds.hasBit(pointerId)) {
2003 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2004 splitPointerIds[splitPointerCount] = pointerId;
2005 splitPointerCoords[splitPointerCount] =
2006 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
2007 splitPointerCount += 1;
2008 }
2009 }
2010 assert(splitPointerCount == pointerIds.count());
2011
2012 int32_t action = originalMotionEntry->action;
2013 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2014 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2015 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2016 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2017 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2018 if (pointerIds.hasBit(pointerId)) {
2019 if (pointerIds.count() == 1) {
2020 // The first/last pointer went down/up.
2021 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2022 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brownffb16d62010-09-27 16:35:11 -07002023 } else {
2024 // A secondary pointer went down/up.
2025 uint32_t splitPointerIndex = 0;
2026 while (pointerId != splitPointerIds[splitPointerIndex]) {
2027 splitPointerIndex += 1;
2028 }
2029 action = maskedAction | (splitPointerIndex
2030 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002031 }
2032 } else {
2033 // An unrelated pointer changed.
2034 action = AMOTION_EVENT_ACTION_MOVE;
2035 }
2036 }
2037
2038 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2039 originalMotionEntry->eventTime,
2040 originalMotionEntry->deviceId,
2041 originalMotionEntry->source,
2042 originalMotionEntry->policyFlags,
2043 action,
2044 originalMotionEntry->flags,
2045 originalMotionEntry->metaState,
2046 originalMotionEntry->edgeFlags,
2047 originalMotionEntry->xPrecision,
2048 originalMotionEntry->yPrecision,
2049 originalMotionEntry->downTime,
2050 splitPointerCount, splitPointerIds, splitPointerCoords);
2051
2052 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2053 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2054 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2055 splitPointerIndex++) {
2056 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2057 splitPointerCoords[splitPointerIndex] =
2058 originalMotionSample->pointerCoords[originalPointerIndex];
2059 }
2060
2061 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2062 splitPointerCoords);
2063 }
2064
2065 return splitMotionEntry;
2066}
2067
Jeff Brown54bc2812010-06-15 01:31:58 -07002068void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002069#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -07002070 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07002071#endif
2072
Jeff Browna665ca82010-09-08 11:49:43 -07002073 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002074 { // acquire lock
2075 AutoMutex _l(mLock);
2076
Jeff Brown51d45a72010-06-17 20:52:56 -07002077 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browna665ca82010-09-08 11:49:43 -07002078 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002079 } // release lock
2080
Jeff Browna665ca82010-09-08 11:49:43 -07002081 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002082 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002083 }
2084}
2085
Jeff Brown5c1ed842010-07-14 18:48:53 -07002086void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -07002087 uint32_t policyFlags, int32_t action, int32_t flags,
2088 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2089#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002090 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07002091 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07002092 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -07002093 keyCode, scanCode, metaState, downTime);
2094#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002095 if (! validateKeyEvent(action)) {
2096 return;
2097 }
Jeff Browne839a582010-04-22 18:58:52 -07002098
Johan Redestigbbd0dc82011-02-25 16:45:17 +01002099 /* According to http://source.android.com/porting/keymaps_keyboard_input.html
2100 * Key definitions: Key definitions follow the syntax key SCANCODE KEYCODE [FLAGS...],
2101 * where SCANCODE is a number, KEYCODE is defined in your specific keylayout file
2102 * (android.keylayout.xxx), and potential FLAGS are defined as follows:
2103 * SHIFT: While pressed, the shift key modifier is set
2104 * ALT: While pressed, the alt key modifier is set
2105 * CAPS: While pressed, the caps lock key modifier is set
2106 * Since KeyEvent.java doesn't check if Cap lock is ON and we don't have a
2107 * modifer state for cap lock, we will not support it.
2108 */
2109 if (policyFlags & POLICY_FLAG_ALT) {
2110 metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON;
2111 }
2112 if (policyFlags & POLICY_FLAG_ALT_GR) {
2113 metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON;
2114 }
2115 if (policyFlags & POLICY_FLAG_SHIFT) {
2116 metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON;
2117 }
2118
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002119 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002120 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2121 keyCode, scanCode, /*byref*/ policyFlags);
2122
Jeff Browna665ca82010-09-08 11:49:43 -07002123 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002124 { // acquire lock
2125 AutoMutex _l(mLock);
2126
Jeff Brown51d45a72010-06-17 20:52:56 -07002127 int32_t repeatCount = 0;
2128 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002129 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07002130 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07002131
Jeff Browna665ca82010-09-08 11:49:43 -07002132 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002133 } // release lock
2134
Jeff Browna665ca82010-09-08 11:49:43 -07002135 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002136 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002137 }
2138}
2139
Jeff Brown5c1ed842010-07-14 18:48:53 -07002140void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002141 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002142 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2143 float xPrecision, float yPrecision, nsecs_t downTime) {
2144#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002145 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002146 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2147 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2148 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002149 xPrecision, yPrecision, downTime);
2150 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07002151 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002152 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07002153 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07002154 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-08-30 03:02:23 -07002155 pointerCoords[i].pressure, pointerCoords[i].size,
2156 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2157 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2158 pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -07002159 }
2160#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002161 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2162 return;
2163 }
Jeff Browne839a582010-04-22 18:58:52 -07002164
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002165 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002166 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2167
Jeff Browna665ca82010-09-08 11:49:43 -07002168 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002169 { // acquire lock
2170 AutoMutex _l(mLock);
2171
2172 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07002173 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07002174 // BATCHING CASE
2175 //
2176 // Try to append a move sample to the tail of the inbound queue for this device.
2177 // Give up if we encounter a non-move motion event for this device since that
2178 // means we cannot append any new samples until a new motion event has started.
Jeff Browna665ca82010-09-08 11:49:43 -07002179 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2180 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07002181 if (entry->type != EventEntry::TYPE_MOTION) {
2182 // Keep looking for motion events.
2183 continue;
2184 }
2185
2186 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2187 if (motionEntry->deviceId != deviceId) {
2188 // Keep looking for this device.
2189 continue;
2190 }
2191
Jeff Brown5c1ed842010-07-14 18:48:53 -07002192 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07002193 || motionEntry->pointerCount != pointerCount
2194 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07002195 // Last motion event in the queue for this device is not compatible for
2196 // appending new samples. Stop here.
2197 goto NoBatchingOrStreaming;
2198 }
2199
2200 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07002201 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07002202 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002203#if DEBUG_BATCHING
2204 LOGD("Appended motion sample onto batch for most recent "
2205 "motion event for this device in the inbound queue.");
2206#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07002207 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002208 }
2209
2210 // STREAMING CASE
2211 //
2212 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07002213 // Search the outbound queue for the current foreground targets to find a dispatched
2214 // motion event that is still in progress. If found, then, appen the new sample to
2215 // that event and push it out to all current targets. The logic in
2216 // prepareDispatchCycleLocked takes care of the case where some targets may
2217 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown54bc2812010-06-15 01:31:58 -07002218 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002219 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2220 const InputTarget& inputTarget = mCurrentInputTargets[i];
2221 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2222 // Skip non-foreground targets. We only want to stream if there is at
2223 // least one foreground target whose dispatch is still in progress.
2224 continue;
Jeff Browne839a582010-04-22 18:58:52 -07002225 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002226
2227 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2228 if (connectionIndex < 0) {
2229 // Connection must no longer be valid.
2230 continue;
2231 }
2232
2233 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2234 if (connection->outboundQueue.isEmpty()) {
2235 // This foreground target has an empty outbound queue.
2236 continue;
2237 }
2238
2239 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2240 if (! dispatchEntry->inProgress
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002241 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2242 || dispatchEntry->isSplit()) {
2243 // No motion event is being dispatched, or it is being split across
2244 // windows in which case we cannot stream.
Jeff Brown53a415e2010-09-15 15:18:56 -07002245 continue;
2246 }
2247
2248 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2249 dispatchEntry->eventEntry);
2250 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2251 || motionEntry->deviceId != deviceId
2252 || motionEntry->pointerCount != pointerCount
2253 || motionEntry->isInjected()) {
2254 // The motion event is not compatible with this move.
2255 continue;
2256 }
2257
2258 // Hurray! This foreground target is currently dispatching a move event
2259 // that we can stream onto. Append the motion sample and resume dispatch.
2260 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2261#if DEBUG_BATCHING
2262 LOGD("Appended motion sample onto batch for most recently dispatched "
2263 "motion event for this device in the outbound queues. "
2264 "Attempting to stream the motion sample.");
2265#endif
2266 nsecs_t currentTime = now();
2267 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2268 true /*resumeWithAppendedMotionSample*/);
2269
2270 runCommandsLockedInterruptible();
2271 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002272 }
2273 }
2274
2275NoBatchingOrStreaming:;
2276 }
2277
2278 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07002279 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002280 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002281 xPrecision, yPrecision, downTime,
2282 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002283
Jeff Browna665ca82010-09-08 11:49:43 -07002284 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002285 } // release lock
2286
Jeff Browna665ca82010-09-08 11:49:43 -07002287 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002288 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002289 }
2290}
2291
Jeff Brown90f0cee2010-10-08 22:31:17 -07002292void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2293 uint32_t policyFlags) {
2294#if DEBUG_INBOUND_EVENT_DETAILS
2295 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2296 switchCode, switchValue, policyFlags);
2297#endif
2298
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002299 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002300 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2301}
2302
Jeff Brown51d45a72010-06-17 20:52:56 -07002303int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07002304 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002305#if DEBUG_INBOUND_EVENT_DETAILS
2306 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002307 "syncMode=%d, timeoutMillis=%d",
2308 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07002309#endif
2310
2311 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002312
2313 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2314 if (hasInjectionPermission(injectorPid, injectorUid)) {
2315 policyFlags |= POLICY_FLAG_TRUSTED;
2316 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002317
Jeff Brown90f0cee2010-10-08 22:31:17 -07002318 EventEntry* injectedEntry;
2319 switch (event->getType()) {
2320 case AINPUT_EVENT_TYPE_KEY: {
2321 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2322 int32_t action = keyEvent->getAction();
2323 if (! validateKeyEvent(action)) {
Jeff Browna665ca82010-09-08 11:49:43 -07002324 return INPUT_EVENT_INJECTION_FAILED;
2325 }
2326
Jeff Brown90f0cee2010-10-08 22:31:17 -07002327 nsecs_t eventTime = keyEvent->getEventTime();
2328 int32_t deviceId = keyEvent->getDeviceId();
2329 int32_t flags = keyEvent->getFlags();
2330 int32_t keyCode = keyEvent->getKeyCode();
2331 int32_t scanCode = keyEvent->getScanCode();
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002332 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2333 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002334
Jeff Brown90f0cee2010-10-08 22:31:17 -07002335 mLock.lock();
2336 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2337 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2338 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2339 break;
2340 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002341
Jeff Brown90f0cee2010-10-08 22:31:17 -07002342 case AINPUT_EVENT_TYPE_MOTION: {
2343 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2344 int32_t action = motionEvent->getAction();
2345 size_t pointerCount = motionEvent->getPointerCount();
2346 const int32_t* pointerIds = motionEvent->getPointerIds();
2347 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2348 return INPUT_EVENT_INJECTION_FAILED;
2349 }
2350
2351 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002352 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002353
2354 mLock.lock();
2355 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2356 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2357 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2358 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2359 action, motionEvent->getFlags(),
2360 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2361 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2362 motionEvent->getDownTime(), uint32_t(pointerCount),
2363 pointerIds, samplePointerCoords);
2364 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2365 sampleEventTimes += 1;
2366 samplePointerCoords += pointerCount;
2367 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2368 }
2369 injectedEntry = motionEntry;
2370 break;
2371 }
2372
2373 default:
2374 LOGW("Cannot inject event of type %d", event->getType());
2375 return INPUT_EVENT_INJECTION_FAILED;
2376 }
2377
2378 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2379 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2380 injectionState->injectionIsAsync = true;
2381 }
2382
2383 injectionState->refCount += 1;
2384 injectedEntry->injectionState = injectionState;
2385
2386 bool needWake = enqueueInboundEventLocked(injectedEntry);
2387 mLock.unlock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002388
Jeff Browna665ca82010-09-08 11:49:43 -07002389 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002390 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07002391 }
2392
2393 int32_t injectionResult;
2394 { // acquire lock
2395 AutoMutex _l(mLock);
2396
Jeff Brownf67c53e2010-07-28 15:48:59 -07002397 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2398 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2399 } else {
2400 for (;;) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002401 injectionResult = injectionState->injectionResult;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002402 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2403 break;
2404 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002405
Jeff Brown51d45a72010-06-17 20:52:56 -07002406 nsecs_t remainingTimeout = endTime - now();
2407 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002408#if DEBUG_INJECTION
2409 LOGD("injectInputEvent - Timed out waiting for injection result "
2410 "to become available.");
2411#endif
Jeff Brown51d45a72010-06-17 20:52:56 -07002412 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2413 break;
2414 }
2415
Jeff Brownf67c53e2010-07-28 15:48:59 -07002416 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2417 }
2418
2419 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2420 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002421 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002422#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002423 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002424 injectionState->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002425#endif
2426 nsecs_t remainingTimeout = endTime - now();
2427 if (remainingTimeout <= 0) {
2428#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002429 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002430 "dispatches to finish.");
2431#endif
2432 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2433 break;
2434 }
2435
2436 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2437 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002438 }
2439 }
2440
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002441 mAllocator.releaseInjectionState(injectionState);
Jeff Brown51d45a72010-06-17 20:52:56 -07002442 } // release lock
2443
Jeff Brownf67c53e2010-07-28 15:48:59 -07002444#if DEBUG_INJECTION
2445 LOGD("injectInputEvent - Finished with result %d. "
2446 "injectorPid=%d, injectorUid=%d",
2447 injectionResult, injectorPid, injectorUid);
2448#endif
2449
Jeff Brown51d45a72010-06-17 20:52:56 -07002450 return injectionResult;
2451}
2452
Jeff Brown90f0cee2010-10-08 22:31:17 -07002453bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2454 return injectorUid == 0
2455 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2456}
2457
Jeff Brown51d45a72010-06-17 20:52:56 -07002458void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002459 InjectionState* injectionState = entry->injectionState;
2460 if (injectionState) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002461#if DEBUG_INJECTION
2462 LOGD("Setting input event injection result to %d. "
2463 "injectorPid=%d, injectorUid=%d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002464 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002465#endif
2466
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002467 if (injectionState->injectionIsAsync) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002468 // Log the outcome since the injector did not wait for the injection result.
2469 switch (injectionResult) {
2470 case INPUT_EVENT_INJECTION_SUCCEEDED:
2471 LOGV("Asynchronous input event injection succeeded.");
2472 break;
2473 case INPUT_EVENT_INJECTION_FAILED:
2474 LOGW("Asynchronous input event injection failed.");
2475 break;
2476 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2477 LOGW("Asynchronous input event injection permission denied.");
2478 break;
2479 case INPUT_EVENT_INJECTION_TIMED_OUT:
2480 LOGW("Asynchronous input event injection timed out.");
2481 break;
2482 }
2483 }
2484
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002485 injectionState->injectionResult = injectionResult;
Jeff Brown51d45a72010-06-17 20:52:56 -07002486 mInjectionResultAvailableCondition.broadcast();
2487 }
2488}
2489
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002490void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2491 InjectionState* injectionState = entry->injectionState;
2492 if (injectionState) {
2493 injectionState->pendingForegroundDispatches += 1;
2494 }
2495}
2496
Jeff Brown53a415e2010-09-15 15:18:56 -07002497void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002498 InjectionState* injectionState = entry->injectionState;
2499 if (injectionState) {
2500 injectionState->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002501
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002502 if (injectionState->pendingForegroundDispatches == 0) {
2503 mInjectionSyncFinishedCondition.broadcast();
2504 }
Jeff Browna665ca82010-09-08 11:49:43 -07002505 }
2506}
2507
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002508const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2509 for (size_t i = 0; i < mWindows.size(); i++) {
2510 const InputWindow* window = & mWindows[i];
2511 if (window->inputChannel == inputChannel) {
2512 return window;
2513 }
2514 }
2515 return NULL;
2516}
2517
Jeff Browna665ca82010-09-08 11:49:43 -07002518void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2519#if DEBUG_FOCUS
2520 LOGD("setInputWindows");
2521#endif
2522 { // acquire lock
2523 AutoMutex _l(mLock);
2524
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002525 // Clear old window pointers.
Jeff Brown90f0cee2010-10-08 22:31:17 -07002526 sp<InputChannel> oldFocusedWindowChannel;
2527 if (mFocusedWindow) {
2528 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2529 mFocusedWindow = NULL;
2530 }
2531
Jeff Browna665ca82010-09-08 11:49:43 -07002532 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002533
2534 // Loop over new windows and rebuild the necessary window pointers for
2535 // tracking focus and touch.
Jeff Browna665ca82010-09-08 11:49:43 -07002536 mWindows.appendVector(inputWindows);
2537
2538 size_t numWindows = mWindows.size();
2539 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002540 const InputWindow* window = & mWindows.itemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07002541 if (window->hasFocus) {
2542 mFocusedWindow = window;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002543 break;
Jeff Browna665ca82010-09-08 11:49:43 -07002544 }
2545 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002546
Jeff Brown90f0cee2010-10-08 22:31:17 -07002547 if (oldFocusedWindowChannel != NULL) {
2548 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2549#if DEBUG_FOCUS
2550 LOGD("Focus left window: %s",
2551 oldFocusedWindowChannel->getName().string());
2552#endif
2553 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2554 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2555 oldFocusedWindowChannel.clear();
2556 }
2557 }
2558 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2559#if DEBUG_FOCUS
2560 LOGD("Focus entered window: %s",
2561 mFocusedWindow->inputChannel->getName().string());
2562#endif
2563 }
2564
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002565 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2566 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2567 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2568 if (window) {
2569 touchedWindow.window = window;
2570 i += 1;
2571 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -07002572#if DEBUG_FOCUS
2573 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2574#endif
Jeff Brown90f0cee2010-10-08 22:31:17 -07002575 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2576 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownb13d7b52010-10-15 16:20:51 -07002577 mTouchState.windows.removeAt(i);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002578 }
2579 }
Jeff Browna665ca82010-09-08 11:49:43 -07002580
Jeff Browna665ca82010-09-08 11:49:43 -07002581#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002582 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002583#endif
2584 } // release lock
2585
2586 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002587 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002588}
2589
2590void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2591#if DEBUG_FOCUS
2592 LOGD("setFocusedApplication");
2593#endif
2594 { // acquire lock
2595 AutoMutex _l(mLock);
2596
2597 releaseFocusedApplicationLocked();
2598
2599 if (inputApplication) {
2600 mFocusedApplicationStorage = *inputApplication;
2601 mFocusedApplication = & mFocusedApplicationStorage;
2602 }
2603
2604#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002605 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002606#endif
2607 } // release lock
2608
2609 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002610 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002611}
2612
2613void InputDispatcher::releaseFocusedApplicationLocked() {
2614 if (mFocusedApplication) {
2615 mFocusedApplication = NULL;
2616 mFocusedApplicationStorage.handle.clear();
2617 }
2618}
2619
2620void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2621#if DEBUG_FOCUS
2622 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2623#endif
2624
2625 bool changed;
2626 { // acquire lock
2627 AutoMutex _l(mLock);
2628
2629 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brownfef5b042010-10-27 18:43:51 -07002630 if (mDispatchFrozen && !frozen) {
Jeff Browna665ca82010-09-08 11:49:43 -07002631 resetANRTimeoutsLocked();
2632 }
2633
Jeff Brownfef5b042010-10-27 18:43:51 -07002634 if (mDispatchEnabled && !enabled) {
2635 resetAndDropEverythingLocked("dispatcher is being disabled");
2636 }
2637
Jeff Browna665ca82010-09-08 11:49:43 -07002638 mDispatchEnabled = enabled;
2639 mDispatchFrozen = frozen;
2640 changed = true;
2641 } else {
2642 changed = false;
2643 }
2644
2645#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002646 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002647#endif
2648 } // release lock
2649
2650 if (changed) {
2651 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002652 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002653 }
2654}
2655
Jeff Brownfef5b042010-10-27 18:43:51 -07002656void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2657#if DEBUG_FOCUS
2658 LOGD("Resetting and dropping all events (%s).", reason);
2659#endif
2660
2661 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2662
2663 resetKeyRepeatLocked();
2664 releasePendingEventLocked();
2665 drainInboundQueueLocked();
2666 resetTargetsLocked();
2667
2668 mTouchState.reset();
2669}
2670
Jeff Browna665ca82010-09-08 11:49:43 -07002671void InputDispatcher::logDispatchStateLocked() {
2672 String8 dump;
2673 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002674
2675 char* text = dump.lockBuffer(dump.size());
2676 char* start = text;
2677 while (*start != '\0') {
2678 char* end = strchr(start, '\n');
2679 if (*end == '\n') {
2680 *(end++) = '\0';
2681 }
2682 LOGD("%s", start);
2683 start = end;
2684 }
Jeff Browna665ca82010-09-08 11:49:43 -07002685}
2686
2687void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002688 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2689 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002690
2691 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002692 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002693 mFocusedApplication->name.string(),
2694 mFocusedApplication->dispatchingTimeout / 1000000.0);
2695 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002696 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002697 }
Jeff Brown2806e382010-10-01 17:46:21 -07002698 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002699 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-10-01 17:46:21 -07002700
2701 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2702 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2703 if (!mTouchState.windows.isEmpty()) {
2704 dump.append(INDENT "TouchedWindows:\n");
2705 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2706 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2707 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2708 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2709 touchedWindow.targetFlags);
2710 }
2711 } else {
2712 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002713 }
2714
Jeff Brown2806e382010-10-01 17:46:21 -07002715 if (!mWindows.isEmpty()) {
2716 dump.append(INDENT "Windows:\n");
2717 for (size_t i = 0; i < mWindows.size(); i++) {
2718 const InputWindow& window = mWindows[i];
2719 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2720 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2721 "frame=[%d,%d][%d,%d], "
2722 "visibleFrame=[%d,%d][%d,%d], "
2723 "touchableArea=[%d,%d][%d,%d], "
2724 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2725 i, window.name.string(),
2726 toString(window.paused),
2727 toString(window.hasFocus),
2728 toString(window.hasWallpaper),
2729 toString(window.visible),
2730 toString(window.canReceiveKeys),
2731 window.layoutParamsFlags, window.layoutParamsType,
2732 window.layer,
2733 window.frameLeft, window.frameTop,
2734 window.frameRight, window.frameBottom,
2735 window.visibleFrameLeft, window.visibleFrameTop,
2736 window.visibleFrameRight, window.visibleFrameBottom,
2737 window.touchableAreaLeft, window.touchableAreaTop,
2738 window.touchableAreaRight, window.touchableAreaBottom,
2739 window.ownerPid, window.ownerUid,
2740 window.dispatchingTimeout / 1000000.0);
2741 }
2742 } else {
2743 dump.append(INDENT "Windows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002744 }
2745
Jeff Brown2806e382010-10-01 17:46:21 -07002746 if (!mMonitoringChannels.isEmpty()) {
2747 dump.append(INDENT "MonitoringChannels:\n");
2748 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2749 const sp<InputChannel>& channel = mMonitoringChannels[i];
2750 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2751 }
2752 } else {
2753 dump.append(INDENT "MonitoringChannels: <none>\n");
2754 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002755
Jeff Brown2806e382010-10-01 17:46:21 -07002756 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2757
2758 if (!mActiveConnections.isEmpty()) {
2759 dump.append(INDENT "ActiveConnections:\n");
2760 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2761 const Connection* connection = mActiveConnections[i];
2762 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
Jeff Brown90f0cee2010-10-08 22:31:17 -07002763 "inputState.isNeutral=%s\n",
Jeff Brown2806e382010-10-01 17:46:21 -07002764 i, connection->getInputChannelName(), connection->getStatusLabel(),
2765 connection->outboundQueue.count(),
Jeff Brown90f0cee2010-10-08 22:31:17 -07002766 toString(connection->inputState.isNeutral()));
Jeff Brown2806e382010-10-01 17:46:21 -07002767 }
2768 } else {
2769 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002770 }
2771
2772 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002773 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002774 (mAppSwitchDueTime - now()) / 1000000.0);
2775 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002776 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002777 }
2778}
2779
2780status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002781#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002782 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2783 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002784#endif
2785
Jeff Browne839a582010-04-22 18:58:52 -07002786 { // acquire lock
2787 AutoMutex _l(mLock);
2788
Jeff Brown53a415e2010-09-15 15:18:56 -07002789 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002790 LOGW("Attempted to register already registered input channel '%s'",
2791 inputChannel->getName().string());
2792 return BAD_VALUE;
2793 }
2794
2795 sp<Connection> connection = new Connection(inputChannel);
2796 status_t status = connection->initialize();
2797 if (status) {
2798 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2799 inputChannel->getName().string(), status);
2800 return status;
2801 }
2802
Jeff Brown0cacb872010-08-17 15:59:26 -07002803 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002804 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002805
Jeff Browna665ca82010-09-08 11:49:43 -07002806 if (monitor) {
2807 mMonitoringChannels.push(inputChannel);
2808 }
2809
Jeff Brown59abe7e2010-09-13 23:17:30 -07002810 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002811
Jeff Brown54bc2812010-06-15 01:31:58 -07002812 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002813 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002814 return OK;
2815}
2816
2817status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002818#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002819 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002820#endif
2821
Jeff Browne839a582010-04-22 18:58:52 -07002822 { // acquire lock
2823 AutoMutex _l(mLock);
2824
Jeff Brown53a415e2010-09-15 15:18:56 -07002825 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002826 if (connectionIndex < 0) {
2827 LOGW("Attempted to unregister already unregistered input channel '%s'",
2828 inputChannel->getName().string());
2829 return BAD_VALUE;
2830 }
2831
2832 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2833 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2834
2835 connection->status = Connection::STATUS_ZOMBIE;
2836
Jeff Browna665ca82010-09-08 11:49:43 -07002837 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2838 if (mMonitoringChannels[i] == inputChannel) {
2839 mMonitoringChannels.removeAt(i);
2840 break;
2841 }
2842 }
2843
Jeff Brown59abe7e2010-09-13 23:17:30 -07002844 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002845
Jeff Brown51d45a72010-06-17 20:52:56 -07002846 nsecs_t currentTime = now();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002847 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002848
2849 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002850 } // release lock
2851
Jeff Browne839a582010-04-22 18:58:52 -07002852 // Wake the poll loop because removing the connection may have changed the current
2853 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002854 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002855 return OK;
2856}
2857
Jeff Brown53a415e2010-09-15 15:18:56 -07002858ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002859 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2860 if (connectionIndex >= 0) {
2861 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2862 if (connection->inputChannel.get() == inputChannel.get()) {
2863 return connectionIndex;
2864 }
2865 }
2866
2867 return -1;
2868}
2869
Jeff Browne839a582010-04-22 18:58:52 -07002870void InputDispatcher::activateConnectionLocked(Connection* connection) {
2871 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2872 if (mActiveConnections.itemAt(i) == connection) {
2873 return;
2874 }
2875 }
2876 mActiveConnections.add(connection);
2877}
2878
2879void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2880 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2881 if (mActiveConnections.itemAt(i) == connection) {
2882 mActiveConnections.removeAt(i);
2883 return;
2884 }
2885 }
2886}
2887
Jeff Brown54bc2812010-06-15 01:31:58 -07002888void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002889 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002890}
2891
Jeff Brown54bc2812010-06-15 01:31:58 -07002892void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002893 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002894}
2895
Jeff Brown54bc2812010-06-15 01:31:58 -07002896void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002897 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002898 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2899 connection->getInputChannelName());
2900
Jeff Brown54bc2812010-06-15 01:31:58 -07002901 CommandEntry* commandEntry = postCommandLocked(
2902 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002903 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002904}
2905
Jeff Brown53a415e2010-09-15 15:18:56 -07002906void InputDispatcher::onANRLocked(
2907 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2908 nsecs_t eventTime, nsecs_t waitStartTime) {
2909 LOGI("Application is not responding: %s. "
2910 "%01.1fms since event, %01.1fms since wait started",
2911 getApplicationWindowLabelLocked(application, window).string(),
2912 (currentTime - eventTime) / 1000000.0,
2913 (currentTime - waitStartTime) / 1000000.0);
2914
2915 CommandEntry* commandEntry = postCommandLocked(
2916 & InputDispatcher::doNotifyANRLockedInterruptible);
2917 if (application) {
2918 commandEntry->inputApplicationHandle = application->handle;
2919 }
2920 if (window) {
2921 commandEntry->inputChannel = window->inputChannel;
2922 }
2923}
2924
Jeff Browna665ca82010-09-08 11:49:43 -07002925void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2926 CommandEntry* commandEntry) {
2927 mLock.unlock();
2928
2929 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2930
2931 mLock.lock();
2932}
2933
Jeff Brown54bc2812010-06-15 01:31:58 -07002934void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2935 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002936 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002937
Jeff Brown51d45a72010-06-17 20:52:56 -07002938 if (connection->status != Connection::STATUS_ZOMBIE) {
2939 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002940
Jeff Brown51d45a72010-06-17 20:52:56 -07002941 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2942
2943 mLock.lock();
2944 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002945}
2946
Jeff Brown53a415e2010-09-15 15:18:56 -07002947void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002948 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002949 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002950
Jeff Brown53a415e2010-09-15 15:18:56 -07002951 nsecs_t newTimeout = mPolicy->notifyANR(
2952 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002953
Jeff Brown53a415e2010-09-15 15:18:56 -07002954 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002955
Jeff Brown53a415e2010-09-15 15:18:56 -07002956 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002957}
2958
Jeff Browna665ca82010-09-08 11:49:43 -07002959void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2960 CommandEntry* commandEntry) {
2961 KeyEntry* entry = commandEntry->keyEntry;
2962 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2963 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2964 entry->downTime, entry->eventTime);
2965
2966 mLock.unlock();
2967
2968 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2969 & mReusableKeyEvent, entry->policyFlags);
2970
2971 mLock.lock();
2972
2973 entry->interceptKeyResult = consumed
2974 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2975 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2976 mAllocator.releaseKeyEntry(entry);
2977}
2978
2979void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2980 mLock.unlock();
2981
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002982 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07002983
2984 mLock.lock();
2985}
2986
Jeff Brown53a415e2010-09-15 15:18:56 -07002987void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
2988 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
2989 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07002990}
2991
2992void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002993 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002994 dumpDispatchStateLocked(dump);
2995}
2996
Jeff Brown54bc2812010-06-15 01:31:58 -07002997
Jeff Brown53a415e2010-09-15 15:18:56 -07002998// --- InputDispatcher::Queue ---
2999
3000template <typename T>
3001uint32_t InputDispatcher::Queue<T>::count() const {
3002 uint32_t result = 0;
3003 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3004 result += 1;
3005 }
3006 return result;
3007}
3008
3009
Jeff Browne839a582010-04-22 18:58:52 -07003010// --- InputDispatcher::Allocator ---
3011
3012InputDispatcher::Allocator::Allocator() {
3013}
3014
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003015InputDispatcher::InjectionState*
3016InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3017 InjectionState* injectionState = mInjectionStatePool.alloc();
3018 injectionState->refCount = 1;
3019 injectionState->injectorPid = injectorPid;
3020 injectionState->injectorUid = injectorUid;
3021 injectionState->injectionIsAsync = false;
3022 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3023 injectionState->pendingForegroundDispatches = 0;
3024 return injectionState;
3025}
3026
Jeff Brown51d45a72010-06-17 20:52:56 -07003027void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brown90f0cee2010-10-08 22:31:17 -07003028 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown51d45a72010-06-17 20:52:56 -07003029 entry->type = type;
3030 entry->refCount = 1;
3031 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07003032 entry->eventTime = eventTime;
Jeff Brown90f0cee2010-10-08 22:31:17 -07003033 entry->policyFlags = policyFlags;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003034 entry->injectionState = NULL;
3035}
3036
3037void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3038 if (entry->injectionState) {
3039 releaseInjectionState(entry->injectionState);
3040 entry->injectionState = NULL;
3041 }
Jeff Brown51d45a72010-06-17 20:52:56 -07003042}
3043
Jeff Browne839a582010-04-22 18:58:52 -07003044InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07003045InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003046 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003047 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Browne839a582010-04-22 18:58:52 -07003048 return entry;
3049}
3050
Jeff Brown51d45a72010-06-17 20:52:56 -07003051InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07003052 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07003053 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3054 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003055 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003056 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003057
3058 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003059 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003060 entry->action = action;
3061 entry->flags = flags;
3062 entry->keyCode = keyCode;
3063 entry->scanCode = scanCode;
3064 entry->metaState = metaState;
3065 entry->repeatCount = repeatCount;
3066 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07003067 entry->syntheticRepeat = false;
3068 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07003069 return entry;
3070}
3071
Jeff Brown51d45a72010-06-17 20:52:56 -07003072InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07003073 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07003074 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3075 nsecs_t downTime, uint32_t pointerCount,
3076 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003077 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003078 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003079
3080 entry->eventTime = eventTime;
3081 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003082 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003083 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07003084 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07003085 entry->metaState = metaState;
3086 entry->edgeFlags = edgeFlags;
3087 entry->xPrecision = xPrecision;
3088 entry->yPrecision = yPrecision;
3089 entry->downTime = downTime;
3090 entry->pointerCount = pointerCount;
3091 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07003092 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07003093 entry->lastSample = & entry->firstSample;
3094 for (uint32_t i = 0; i < pointerCount; i++) {
3095 entry->pointerIds[i] = pointerIds[i];
3096 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3097 }
Jeff Browne839a582010-04-22 18:58:52 -07003098 return entry;
3099}
3100
3101InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07003102 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07003103 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07003104 DispatchEntry* entry = mDispatchEntryPool.alloc();
3105 entry->eventEntry = eventEntry;
3106 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07003107 entry->targetFlags = targetFlags;
3108 entry->xOffset = xOffset;
3109 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07003110 entry->inProgress = false;
3111 entry->headMotionSample = NULL;
3112 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07003113 return entry;
3114}
3115
Jeff Brown54bc2812010-06-15 01:31:58 -07003116InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3117 CommandEntry* entry = mCommandEntryPool.alloc();
3118 entry->command = command;
3119 return entry;
3120}
3121
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003122void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3123 injectionState->refCount -= 1;
3124 if (injectionState->refCount == 0) {
3125 mInjectionStatePool.free(injectionState);
3126 } else {
3127 assert(injectionState->refCount > 0);
3128 }
3129}
3130
Jeff Browne839a582010-04-22 18:58:52 -07003131void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3132 switch (entry->type) {
3133 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3134 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3135 break;
3136 case EventEntry::TYPE_KEY:
3137 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3138 break;
3139 case EventEntry::TYPE_MOTION:
3140 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3141 break;
3142 default:
3143 assert(false);
3144 break;
3145 }
3146}
3147
3148void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3149 ConfigurationChangedEntry* entry) {
3150 entry->refCount -= 1;
3151 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003152 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003153 mConfigurationChangeEntryPool.free(entry);
3154 } else {
3155 assert(entry->refCount > 0);
3156 }
3157}
3158
3159void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3160 entry->refCount -= 1;
3161 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003162 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003163 mKeyEntryPool.free(entry);
3164 } else {
3165 assert(entry->refCount > 0);
3166 }
3167}
3168
3169void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3170 entry->refCount -= 1;
3171 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003172 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -07003173 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3174 MotionSample* next = sample->next;
3175 mMotionSamplePool.free(sample);
3176 sample = next;
3177 }
Jeff Browne839a582010-04-22 18:58:52 -07003178 mMotionEntryPool.free(entry);
3179 } else {
3180 assert(entry->refCount > 0);
3181 }
3182}
3183
3184void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3185 releaseEventEntry(entry->eventEntry);
3186 mDispatchEntryPool.free(entry);
3187}
3188
Jeff Brown54bc2812010-06-15 01:31:58 -07003189void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3190 mCommandEntryPool.free(entry);
3191}
3192
Jeff Browne839a582010-04-22 18:58:52 -07003193void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003194 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003195 MotionSample* sample = mMotionSamplePool.alloc();
3196 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003197 uint32_t pointerCount = motionEntry->pointerCount;
3198 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07003199 sample->pointerCoords[i] = pointerCoords[i];
3200 }
3201
3202 sample->next = NULL;
3203 motionEntry->lastSample->next = sample;
3204 motionEntry->lastSample = sample;
3205}
3206
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003207void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3208 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003209
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003210 keyEntry->dispatchInProgress = false;
3211 keyEntry->syntheticRepeat = false;
3212 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003213}
3214
3215
Jeff Brown542412c2010-08-18 15:51:08 -07003216// --- InputDispatcher::MotionEntry ---
3217
3218uint32_t InputDispatcher::MotionEntry::countSamples() const {
3219 uint32_t count = 1;
3220 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3221 count += 1;
3222 }
3223 return count;
3224}
3225
Jeff Browna665ca82010-09-08 11:49:43 -07003226
3227// --- InputDispatcher::InputState ---
3228
Jeff Brown90f0cee2010-10-08 22:31:17 -07003229InputDispatcher::InputState::InputState() {
Jeff Browna665ca82010-09-08 11:49:43 -07003230}
3231
3232InputDispatcher::InputState::~InputState() {
3233}
3234
3235bool InputDispatcher::InputState::isNeutral() const {
3236 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3237}
3238
Jeff Browna665ca82010-09-08 11:49:43 -07003239InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3240 const EventEntry* entry) {
3241 switch (entry->type) {
3242 case EventEntry::TYPE_KEY:
3243 return trackKey(static_cast<const KeyEntry*>(entry));
3244
3245 case EventEntry::TYPE_MOTION:
3246 return trackMotion(static_cast<const MotionEntry*>(entry));
3247
3248 default:
3249 return CONSISTENT;
3250 }
3251}
3252
3253InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3254 const KeyEntry* entry) {
3255 int32_t action = entry->action;
3256 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3257 KeyMemento& memento = mKeyMementos.editItemAt(i);
3258 if (memento.deviceId == entry->deviceId
3259 && memento.source == entry->source
3260 && memento.keyCode == entry->keyCode
3261 && memento.scanCode == entry->scanCode) {
3262 switch (action) {
3263 case AKEY_EVENT_ACTION_UP:
3264 mKeyMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003265 return CONSISTENT;
3266
3267 case AKEY_EVENT_ACTION_DOWN:
3268 return TOLERABLE;
3269
3270 default:
3271 return BROKEN;
3272 }
3273 }
3274 }
3275
3276 switch (action) {
3277 case AKEY_EVENT_ACTION_DOWN: {
3278 mKeyMementos.push();
3279 KeyMemento& memento = mKeyMementos.editTop();
3280 memento.deviceId = entry->deviceId;
3281 memento.source = entry->source;
3282 memento.keyCode = entry->keyCode;
3283 memento.scanCode = entry->scanCode;
3284 memento.downTime = entry->downTime;
3285 return CONSISTENT;
3286 }
3287
3288 default:
3289 return BROKEN;
3290 }
3291}
3292
3293InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3294 const MotionEntry* entry) {
3295 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3296 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3297 MotionMemento& memento = mMotionMementos.editItemAt(i);
3298 if (memento.deviceId == entry->deviceId
3299 && memento.source == entry->source) {
3300 switch (action) {
3301 case AMOTION_EVENT_ACTION_UP:
3302 case AMOTION_EVENT_ACTION_CANCEL:
3303 mMotionMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003304 return CONSISTENT;
3305
3306 case AMOTION_EVENT_ACTION_DOWN:
3307 return TOLERABLE;
3308
3309 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3310 if (entry->pointerCount == memento.pointerCount + 1) {
3311 memento.setPointers(entry);
3312 return CONSISTENT;
3313 }
3314 return BROKEN;
3315
3316 case AMOTION_EVENT_ACTION_POINTER_UP:
3317 if (entry->pointerCount == memento.pointerCount - 1) {
3318 memento.setPointers(entry);
3319 return CONSISTENT;
3320 }
3321 return BROKEN;
3322
3323 case AMOTION_EVENT_ACTION_MOVE:
3324 if (entry->pointerCount == memento.pointerCount) {
3325 return CONSISTENT;
3326 }
3327 return BROKEN;
3328
3329 default:
3330 return BROKEN;
3331 }
3332 }
3333 }
3334
3335 switch (action) {
3336 case AMOTION_EVENT_ACTION_DOWN: {
3337 mMotionMementos.push();
3338 MotionMemento& memento = mMotionMementos.editTop();
3339 memento.deviceId = entry->deviceId;
3340 memento.source = entry->source;
3341 memento.xPrecision = entry->xPrecision;
3342 memento.yPrecision = entry->yPrecision;
3343 memento.downTime = entry->downTime;
3344 memento.setPointers(entry);
3345 return CONSISTENT;
3346 }
3347
3348 default:
3349 return BROKEN;
3350 }
3351}
3352
3353void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3354 pointerCount = entry->pointerCount;
3355 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3356 pointerIds[i] = entry->pointerIds[i];
3357 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3358 }
3359}
3360
Jeff Brown90f0cee2010-10-08 22:31:17 -07003361void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3362 Allocator* allocator, Vector<EventEntry*>& outEvents,
3363 CancelationOptions options) {
3364 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003365 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003366 if (shouldCancelEvent(memento.source, options)) {
3367 outEvents.push(allocator->obtainKeyEntry(currentTime,
3368 memento.deviceId, memento.source, 0,
3369 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3370 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3371 mKeyMementos.removeAt(i);
3372 } else {
3373 i += 1;
3374 }
Jeff Browna665ca82010-09-08 11:49:43 -07003375 }
3376
Jeff Brown316237d2010-10-11 18:22:53 -07003377 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003378 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003379 if (shouldCancelEvent(memento.source, options)) {
3380 outEvents.push(allocator->obtainMotionEntry(currentTime,
3381 memento.deviceId, memento.source, 0,
3382 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3383 memento.xPrecision, memento.yPrecision, memento.downTime,
3384 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3385 mMotionMementos.removeAt(i);
3386 } else {
3387 i += 1;
3388 }
Jeff Browna665ca82010-09-08 11:49:43 -07003389 }
3390}
3391
3392void InputDispatcher::InputState::clear() {
3393 mKeyMementos.clear();
3394 mMotionMementos.clear();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003395}
3396
3397bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3398 CancelationOptions options) {
3399 switch (options) {
3400 case CANCEL_POINTER_EVENTS:
3401 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3402 case CANCEL_NON_POINTER_EVENTS:
3403 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3404 default:
3405 return true;
3406 }
Jeff Browna665ca82010-09-08 11:49:43 -07003407}
3408
3409
Jeff Browne839a582010-04-22 18:58:52 -07003410// --- InputDispatcher::Connection ---
3411
3412InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3413 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003414 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003415}
3416
3417InputDispatcher::Connection::~Connection() {
3418}
3419
3420status_t InputDispatcher::Connection::initialize() {
3421 return inputPublisher.initialize();
3422}
3423
Jeff Brown54bc2812010-06-15 01:31:58 -07003424const char* InputDispatcher::Connection::getStatusLabel() const {
3425 switch (status) {
3426 case STATUS_NORMAL:
3427 return "NORMAL";
3428
3429 case STATUS_BROKEN:
3430 return "BROKEN";
3431
Jeff Brown54bc2812010-06-15 01:31:58 -07003432 case STATUS_ZOMBIE:
3433 return "ZOMBIE";
3434
3435 default:
3436 return "UNKNOWN";
3437 }
3438}
3439
Jeff Browne839a582010-04-22 18:58:52 -07003440InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3441 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003442 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3443 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003444 if (dispatchEntry->eventEntry == eventEntry) {
3445 return dispatchEntry;
3446 }
3447 }
3448 return NULL;
3449}
3450
Jeff Browna665ca82010-09-08 11:49:43 -07003451
Jeff Brown54bc2812010-06-15 01:31:58 -07003452// --- InputDispatcher::CommandEntry ---
3453
Jeff Browna665ca82010-09-08 11:49:43 -07003454InputDispatcher::CommandEntry::CommandEntry() :
3455 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003456}
3457
3458InputDispatcher::CommandEntry::~CommandEntry() {
3459}
3460
Jeff Browne839a582010-04-22 18:58:52 -07003461
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003462// --- InputDispatcher::TouchState ---
3463
3464InputDispatcher::TouchState::TouchState() :
3465 down(false), split(false) {
3466}
3467
3468InputDispatcher::TouchState::~TouchState() {
3469}
3470
3471void InputDispatcher::TouchState::reset() {
3472 down = false;
3473 split = false;
3474 windows.clear();
3475}
3476
3477void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3478 down = other.down;
3479 split = other.split;
3480 windows.clear();
3481 windows.appendVector(other.windows);
3482}
3483
3484void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3485 int32_t targetFlags, BitSet32 pointerIds) {
3486 if (targetFlags & InputTarget::FLAG_SPLIT) {
3487 split = true;
3488 }
3489
3490 for (size_t i = 0; i < windows.size(); i++) {
3491 TouchedWindow& touchedWindow = windows.editItemAt(i);
3492 if (touchedWindow.window == window) {
3493 touchedWindow.targetFlags |= targetFlags;
3494 touchedWindow.pointerIds.value |= pointerIds.value;
3495 return;
3496 }
3497 }
3498
3499 windows.push();
3500
3501 TouchedWindow& touchedWindow = windows.editTop();
3502 touchedWindow.window = window;
3503 touchedWindow.targetFlags = targetFlags;
3504 touchedWindow.pointerIds = pointerIds;
3505 touchedWindow.channel = window->inputChannel;
3506}
3507
3508void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3509 for (size_t i = 0 ; i < windows.size(); ) {
3510 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3511 windows.removeAt(i);
3512 } else {
3513 i += 1;
3514 }
3515 }
3516}
3517
3518const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3519 for (size_t i = 0; i < windows.size(); i++) {
3520 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3521 return windows[i].window;
3522 }
3523 }
3524 return NULL;
3525}
3526
3527
Jeff Browne839a582010-04-22 18:58:52 -07003528// --- InputDispatcherThread ---
3529
3530InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3531 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3532}
3533
3534InputDispatcherThread::~InputDispatcherThread() {
3535}
3536
3537bool InputDispatcherThread::threadLoop() {
3538 mDispatcher->dispatchOnce();
3539 return true;
3540}
3541
3542} // namespace android