blob: 92ed0b11b6b18a7c5e804e7a43536d49d8ac30c4 [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 Brownf16c26d2010-07-02 15:37:36 -0700597 if (entry->repeatCount == 1) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700598 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brownf16c26d2010-07-02 15:37:36 -0700599 }
600
Jeff Brown61ce3982010-09-07 10:44:57 -0700601 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Browna665ca82010-09-08 11:49:43 -0700602 return entry;
Jeff Browne839a582010-04-22 18:58:52 -0700603}
604
Jeff Browna665ca82010-09-08 11:49:43 -0700605bool InputDispatcher::dispatchConfigurationChangedLocked(
606 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Browne839a582010-04-22 18:58:52 -0700607#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Browna665ca82010-09-08 11:49:43 -0700608 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
609#endif
610
611 // Reset key repeating in case a keyboard device was added or removed or something.
612 resetKeyRepeatLocked();
613
614 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
615 CommandEntry* commandEntry = postCommandLocked(
616 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
617 commandEntry->eventTime = entry->eventTime;
618 return true;
619}
620
621bool InputDispatcher::dispatchKeyLocked(
622 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700623 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brown9cf416c2010-11-02 17:58:22 -0700624 // Preprocessing.
625 if (! entry->dispatchInProgress) {
626 if (entry->repeatCount == 0
627 && entry->action == AKEY_EVENT_ACTION_DOWN
628 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
629 && !entry->isInjected()) {
630 if (mKeyRepeatState.lastKeyEntry
631 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
632 // We have seen two identical key downs in a row which indicates that the device
633 // driver is automatically generating key repeats itself. We take note of the
634 // repeat here, but we disable our own next key repeat timer since it is clear that
635 // we will not need to synthesize key repeats ourselves.
636 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
637 resetKeyRepeatLocked();
638 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
639 } else {
640 // Not a repeat. Save key down state in case we do see a repeat later.
641 resetKeyRepeatLocked();
642 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
643 }
644 mKeyRepeatState.lastKeyEntry = entry;
645 entry->refCount += 1;
646 } else if (! entry->syntheticRepeat) {
647 resetKeyRepeatLocked();
648 }
649
650 entry->dispatchInProgress = true;
651 resetTargetsLocked();
652
653 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
654 }
655
Jeff Brownd8816c32010-09-16 14:07:33 -0700656 // Give the policy a chance to intercept the key.
657 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700658 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700659 CommandEntry* commandEntry = postCommandLocked(
660 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700661 if (mFocusedWindow) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700662 commandEntry->inputChannel = mFocusedWindow->inputChannel;
663 }
664 commandEntry->keyEntry = entry;
665 entry->refCount += 1;
666 return false; // wait for the command to run
667 } else {
668 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
669 }
670 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700671 if (*dropReason == DROP_REASON_NOT_DROPPED) {
672 *dropReason = DROP_REASON_POLICY;
673 }
Jeff Brownd8816c32010-09-16 14:07:33 -0700674 }
675
676 // Clean up if dropping the event.
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700677 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700678 resetTargetsLocked();
Jeff Browna8ed8562010-10-11 23:32:49 -0700679 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
680 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brownd8816c32010-09-16 14:07:33 -0700681 return true;
682 }
683
Jeff Browna665ca82010-09-08 11:49:43 -0700684 // Identify targets.
685 if (! mCurrentInputTargetsValid) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700686 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
687 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700688 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
689 return false;
690 }
691
692 setInjectionResultLocked(entry, injectionResult);
693 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
694 return true;
695 }
696
697 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700698 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700699 }
700
701 // Dispatch the key.
702 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Browna665ca82010-09-08 11:49:43 -0700703 return true;
704}
705
706void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
707#if DEBUG_OUTBOUND_EVENT_DETAILS
708 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
709 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
Jeff Brown9cf416c2010-11-02 17:58:22 -0700710 "repeatCount=%d, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700711 prefix,
712 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
713 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Jeff Brown9cf416c2010-11-02 17:58:22 -0700714 entry->repeatCount, entry->downTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700715#endif
716}
717
718bool InputDispatcher::dispatchMotionLocked(
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700719 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brown9cf416c2010-11-02 17:58:22 -0700720 // Preprocessing.
721 if (! entry->dispatchInProgress) {
722 entry->dispatchInProgress = true;
723 resetTargetsLocked();
724
725 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
726 }
727
Jeff Brownd8816c32010-09-16 14:07:33 -0700728 // Clean up if dropping the event.
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700729 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700730 resetTargetsLocked();
Jeff Browna8ed8562010-10-11 23:32:49 -0700731 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
732 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brownd8816c32010-09-16 14:07:33 -0700733 return true;
734 }
735
Jeff Browna665ca82010-09-08 11:49:43 -0700736 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
737
738 // Identify targets.
739 if (! mCurrentInputTargetsValid) {
Jeff Browna665ca82010-09-08 11:49:43 -0700740 int32_t injectionResult;
741 if (isPointerEvent) {
742 // Pointer event. (eg. touchscreen)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700743 injectionResult = findTouchedWindowTargetsLocked(currentTime,
744 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700745 } else {
746 // Non touch event. (eg. trackball)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700747 injectionResult = findFocusedWindowTargetsLocked(currentTime,
748 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700749 }
750 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
751 return false;
752 }
753
754 setInjectionResultLocked(entry, injectionResult);
755 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
756 return true;
757 }
758
759 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700760 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700761 }
762
763 // Dispatch the motion.
764 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Browna665ca82010-09-08 11:49:43 -0700765 return true;
766}
767
768
769void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
770#if DEBUG_OUTBOUND_EVENT_DETAILS
771 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700772 "action=0x%x, flags=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700773 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700774 prefix,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700775 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
776 entry->action, entry->flags,
Jeff Browne839a582010-04-22 18:58:52 -0700777 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
778 entry->downTime);
779
780 // Print the most recent sample that we have available, this may change due to batching.
781 size_t sampleCount = 1;
Jeff Browna665ca82010-09-08 11:49:43 -0700782 const MotionSample* sample = & entry->firstSample;
Jeff Browne839a582010-04-22 18:58:52 -0700783 for (; sample->next != NULL; sample = sample->next) {
784 sampleCount += 1;
785 }
786 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -0700787 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700788 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -0700789 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -0700790 i, entry->pointerIds[i],
Jeff Brown38a7fab2010-08-30 03:02:23 -0700791 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
792 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
793 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
794 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
795 sample->pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -0700796 }
797
798 // Keep in mind that due to batching, it is possible for the number of samples actually
799 // dispatched to change before the application finally consumed them.
Jeff Brown5c1ed842010-07-14 18:48:53 -0700800 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -0700801 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
802 }
803#endif
Jeff Browne839a582010-04-22 18:58:52 -0700804}
805
806void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
807 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
808#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700809 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700810 "resumeWithAppendedMotionSample=%s",
Jeff Browna665ca82010-09-08 11:49:43 -0700811 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -0700812#endif
813
Jeff Brown54bc2812010-06-15 01:31:58 -0700814 assert(eventEntry->dispatchInProgress); // should already have been set to true
815
Jeff Brownef3a8232010-10-18 13:21:23 -0700816 pokeUserActivityLocked(eventEntry);
817
Jeff Browne839a582010-04-22 18:58:52 -0700818 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
819 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
820
Jeff Brown53a415e2010-09-15 15:18:56 -0700821 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -0700822 if (connectionIndex >= 0) {
823 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown51d45a72010-06-17 20:52:56 -0700824 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -0700825 resumeWithAppendedMotionSample);
826 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700827#if DEBUG_FOCUS
828 LOGD("Dropping event delivery to target with channel '%s' because it "
829 "is no longer registered with the input dispatcher.",
Jeff Browne839a582010-04-22 18:58:52 -0700830 inputTarget.inputChannel->getName().string());
Jeff Brown90f0cee2010-10-08 22:31:17 -0700831#endif
Jeff Browne839a582010-04-22 18:58:52 -0700832 }
833 }
834}
835
Jeff Brownd8816c32010-09-16 14:07:33 -0700836void InputDispatcher::resetTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700837 mCurrentInputTargetsValid = false;
838 mCurrentInputTargets.clear();
Jeff Browna665ca82010-09-08 11:49:43 -0700839 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
840}
841
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700842void InputDispatcher::commitTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700843 mCurrentInputTargetsValid = true;
844}
845
846int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
847 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
848 nsecs_t* nextWakeupTime) {
849 if (application == NULL && window == NULL) {
850 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
851#if DEBUG_FOCUS
852 LOGD("Waiting for system to become ready for input.");
853#endif
854 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
855 mInputTargetWaitStartTime = currentTime;
856 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
857 mInputTargetWaitTimeoutExpired = false;
858 }
859 } else {
860 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
861#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700862 LOGD("Waiting for application to become ready for input: %s",
863 getApplicationWindowLabelLocked(application, window).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700864#endif
865 nsecs_t timeout = window ? window->dispatchingTimeout :
866 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
867
868 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
869 mInputTargetWaitStartTime = currentTime;
870 mInputTargetWaitTimeoutTime = currentTime + timeout;
871 mInputTargetWaitTimeoutExpired = false;
872 }
873 }
874
875 if (mInputTargetWaitTimeoutExpired) {
876 return INPUT_EVENT_INJECTION_TIMED_OUT;
877 }
878
879 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown53a415e2010-09-15 15:18:56 -0700880 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700881
882 // Force poll loop to wake up immediately on next iteration once we get the
883 // ANR response back from the policy.
884 *nextWakeupTime = LONG_LONG_MIN;
885 return INPUT_EVENT_INJECTION_PENDING;
886 } else {
887 // Force poll loop to wake up when timeout is due.
888 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
889 *nextWakeupTime = mInputTargetWaitTimeoutTime;
890 }
891 return INPUT_EVENT_INJECTION_PENDING;
892 }
893}
894
Jeff Brown53a415e2010-09-15 15:18:56 -0700895void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
896 const sp<InputChannel>& inputChannel) {
Jeff Browna665ca82010-09-08 11:49:43 -0700897 if (newTimeout > 0) {
898 // Extend the timeout.
899 mInputTargetWaitTimeoutTime = now() + newTimeout;
900 } else {
901 // Give up.
902 mInputTargetWaitTimeoutExpired = true;
Jeff Brown53a415e2010-09-15 15:18:56 -0700903
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700904 // Release the touch targets.
905 mTouchState.reset();
Jeff Brown405a1d32010-09-16 12:31:46 -0700906
Jeff Brown53a415e2010-09-15 15:18:56 -0700907 // Input state will not be realistic. Mark it out of sync.
Jeff Brown40ad4702010-09-16 11:02:16 -0700908 if (inputChannel.get()) {
909 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
910 if (connectionIndex >= 0) {
911 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700912 synthesizeCancelationEventsForConnectionLocked(
913 connection, InputState::CANCEL_ALL_EVENTS,
914 "application not responding");
Jeff Brown40ad4702010-09-16 11:02:16 -0700915 }
Jeff Brown53a415e2010-09-15 15:18:56 -0700916 }
Jeff Browna665ca82010-09-08 11:49:43 -0700917 }
918}
919
Jeff Brown53a415e2010-09-15 15:18:56 -0700920nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Browna665ca82010-09-08 11:49:43 -0700921 nsecs_t currentTime) {
922 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
923 return currentTime - mInputTargetWaitStartTime;
924 }
925 return 0;
926}
927
928void InputDispatcher::resetANRTimeoutsLocked() {
929#if DEBUG_FOCUS
930 LOGD("Resetting ANR timeouts.");
931#endif
932
Jeff Browna665ca82010-09-08 11:49:43 -0700933 // Reset input target wait timeout.
934 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
935}
936
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700937int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
938 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -0700939 mCurrentInputTargets.clear();
940
941 int32_t injectionResult;
942
943 // If there is no currently focused window and no focused application
944 // then drop the event.
945 if (! mFocusedWindow) {
946 if (mFocusedApplication) {
947#if DEBUG_FOCUS
948 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -0700949 "focused application that may eventually add a window: %s.",
950 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700951#endif
952 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
953 mFocusedApplication, NULL, nextWakeupTime);
954 goto Unresponsive;
955 }
956
957 LOGI("Dropping event because there is no focused window or focused application.");
958 injectionResult = INPUT_EVENT_INJECTION_FAILED;
959 goto Failed;
960 }
961
962 // Check permissions.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700963 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700964 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
965 goto Failed;
966 }
967
968 // If the currently focused window is paused then keep waiting.
969 if (mFocusedWindow->paused) {
970#if DEBUG_FOCUS
971 LOGD("Waiting because focused window is paused.");
972#endif
973 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
974 mFocusedApplication, mFocusedWindow, nextWakeupTime);
975 goto Unresponsive;
976 }
977
Jeff Brown53a415e2010-09-15 15:18:56 -0700978 // If the currently focused window is still working on previous events then keep waiting.
979 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
980#if DEBUG_FOCUS
981 LOGD("Waiting because focused window still processing previous input.");
982#endif
983 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
984 mFocusedApplication, mFocusedWindow, nextWakeupTime);
985 goto Unresponsive;
986 }
987
Jeff Browna665ca82010-09-08 11:49:43 -0700988 // Success! Output targets.
989 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700990 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -0700991
992 // Done.
993Failed:
994Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -0700995 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
996 updateDispatchStatisticsLocked(currentTime, entry,
997 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -0700998#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700999 LOGD("findFocusedWindow finished: injectionResult=%d, "
1000 "timeSpendWaitingForApplication=%0.1fms",
1001 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001002#endif
1003 return injectionResult;
1004}
1005
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001006int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1007 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -07001008 enum InjectionPermission {
1009 INJECTION_PERMISSION_UNKNOWN,
1010 INJECTION_PERMISSION_GRANTED,
1011 INJECTION_PERMISSION_DENIED
1012 };
1013
Jeff Browna665ca82010-09-08 11:49:43 -07001014 mCurrentInputTargets.clear();
1015
1016 nsecs_t startTime = now();
1017
1018 // For security reasons, we defer updating the touch state until we are sure that
1019 // event injection will be allowed.
1020 //
1021 // FIXME In the original code, screenWasOff could never be set to true.
1022 // The reason is that the POLICY_FLAG_WOKE_HERE
1023 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1024 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1025 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1026 // events upon which no preprocessing took place. So policyFlags was always 0.
1027 // In the new native input dispatcher we're a bit more careful about event
1028 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1029 // Unfortunately we obtain undesirable behavior.
1030 //
1031 // Here's what happens:
1032 //
1033 // When the device dims in anticipation of going to sleep, touches
1034 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1035 // the device to brighten and reset the user activity timer.
1036 // Touches on other windows (such as the launcher window)
1037 // are dropped. Then after a moment, the device goes to sleep. Oops.
1038 //
1039 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1040 // instead of POLICY_FLAG_WOKE_HERE...
1041 //
1042 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1043
1044 int32_t action = entry->action;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001045 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Browna665ca82010-09-08 11:49:43 -07001046
1047 // Update the touch state as needed based on the properties of the touch event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001048 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1049 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1050 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1051 mTempTouchState.reset();
1052 mTempTouchState.down = true;
1053 } else {
1054 mTempTouchState.copyFrom(mTouchState);
1055 }
Jeff Browna665ca82010-09-08 11:49:43 -07001056
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001057 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1058 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1059 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1060 /* Case 1: New splittable pointer going down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001061
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001062 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1063 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1064 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1065 const InputWindow* newTouchedWindow = NULL;
1066 const InputWindow* topErrorWindow = NULL;
Jeff Browna665ca82010-09-08 11:49:43 -07001067
1068 // Traverse windows from front to back to find touched window and outside targets.
1069 size_t numWindows = mWindows.size();
1070 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001071 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07001072 int32_t flags = window->layoutParamsFlags;
1073
1074 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1075 if (! topErrorWindow) {
1076 topErrorWindow = window;
1077 }
1078 }
1079
1080 if (window->visible) {
1081 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1082 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1083 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1084 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1085 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1086 newTouchedWindow = window;
Jeff Browna665ca82010-09-08 11:49:43 -07001087 }
1088 break; // found touched window, exit window loop
1089 }
1090 }
1091
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001092 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1093 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001094 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1095 if (isWindowObscuredAtPointLocked(window, x, y)) {
1096 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1097 }
1098
1099 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -07001100 }
1101 }
1102 }
1103
1104 // If there is an error window but it is not taking focus (typically because
1105 // it is invisible) then wait for it. Any other focused window may in
1106 // fact be in ANR state.
1107 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1108#if DEBUG_FOCUS
1109 LOGD("Waiting because system error window is pending.");
1110#endif
1111 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1112 NULL, NULL, nextWakeupTime);
1113 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1114 goto Unresponsive;
1115 }
1116
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001117 // Figure out whether splitting will be allowed for this window.
Jeff Brown1c322582010-09-28 13:24:41 -07001118 if (newTouchedWindow
1119 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001120 // New window supports splitting.
1121 isSplit = true;
1122 } else if (isSplit) {
1123 // New window does not support splitting but we have already split events.
1124 // Assign the pointer to the first foreground window we find.
1125 // (May be NULL which is why we put this code block before the next check.)
1126 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1127 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001128
Jeff Browna665ca82010-09-08 11:49:43 -07001129 // If we did not find a touched window then fail.
1130 if (! newTouchedWindow) {
1131 if (mFocusedApplication) {
1132#if DEBUG_FOCUS
1133 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -07001134 "focused application that may eventually add a new window: %s.",
1135 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -07001136#endif
1137 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1138 mFocusedApplication, NULL, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -07001139 goto Unresponsive;
1140 }
1141
1142 LOGI("Dropping event because there is no touched window or focused application.");
1143 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001144 goto Failed;
1145 }
1146
Jeff Brown35cf0e92010-10-05 12:26:23 -07001147 // Set target flags.
1148 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1149 if (isSplit) {
1150 targetFlags |= InputTarget::FLAG_SPLIT;
1151 }
1152 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1153 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1154 }
1155
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001156 // Update the temporary touch state.
1157 BitSet32 pointerIds;
1158 if (isSplit) {
1159 uint32_t pointerId = entry->pointerIds[pointerIndex];
1160 pointerIds.markBit(pointerId);
Jeff Browna665ca82010-09-08 11:49:43 -07001161 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001162 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001163 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001164 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001165
1166 // If the pointer is not currently down, then ignore the event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001167 if (! mTempTouchState.down) {
Jeff Browna665ca82010-09-08 11:49:43 -07001168 LOGI("Dropping event because the pointer is not down.");
1169 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001170 goto Failed;
1171 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001172 }
Jeff Browna665ca82010-09-08 11:49:43 -07001173
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001174 // Check permission to inject into all touched foreground windows and ensure there
1175 // is at least one touched foreground window.
1176 {
1177 bool haveForegroundWindow = false;
1178 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1179 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1180 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1181 haveForegroundWindow = true;
1182 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1183 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1184 injectionPermission = INJECTION_PERMISSION_DENIED;
1185 goto Failed;
1186 }
1187 }
1188 }
1189 if (! haveForegroundWindow) {
Jeff Browna665ca82010-09-08 11:49:43 -07001190#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001191 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Browna665ca82010-09-08 11:49:43 -07001192#endif
1193 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001194 goto Failed;
1195 }
1196
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001197 // Permission granted to injection into all touched foreground windows.
1198 injectionPermission = INJECTION_PERMISSION_GRANTED;
1199 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001200
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001201 // Ensure all touched foreground windows are ready for new input.
1202 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1203 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1204 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1205 // If the touched window is paused then keep waiting.
1206 if (touchedWindow.window->paused) {
1207#if DEBUG_INPUT_DISPATCHER_POLICY
1208 LOGD("Waiting because touched window is paused.");
Jeff Brown53a415e2010-09-15 15:18:56 -07001209#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001210 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1211 NULL, touchedWindow.window, nextWakeupTime);
1212 goto Unresponsive;
1213 }
1214
1215 // If the touched window is still working on previous events then keep waiting.
1216 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1217#if DEBUG_FOCUS
1218 LOGD("Waiting because touched window still processing previous input.");
1219#endif
1220 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1221 NULL, touchedWindow.window, nextWakeupTime);
1222 goto Unresponsive;
1223 }
1224 }
1225 }
1226
1227 // If this is the first pointer going down and the touched window has a wallpaper
1228 // then also add the touched wallpaper windows so they are locked in for the duration
1229 // of the touch gesture.
1230 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1231 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1232 if (foregroundWindow->hasWallpaper) {
1233 for (size_t i = 0; i < mWindows.size(); i++) {
1234 const InputWindow* window = & mWindows[i];
1235 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001236 mTempTouchState.addOrUpdateWindow(window,
1237 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001238 }
1239 }
1240 }
1241 }
1242
Jeff Browna665ca82010-09-08 11:49:43 -07001243 // Success! Output targets.
1244 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Browna665ca82010-09-08 11:49:43 -07001245
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001246 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1247 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1248 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1249 touchedWindow.pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001250 }
1251
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001252 // Drop the outside touch window since we will not care about them in the next iteration.
1253 mTempTouchState.removeOutsideTouchWindows();
1254
Jeff Browna665ca82010-09-08 11:49:43 -07001255Failed:
1256 // Check injection permission once and for all.
1257 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001258 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001259 injectionPermission = INJECTION_PERMISSION_GRANTED;
1260 } else {
1261 injectionPermission = INJECTION_PERMISSION_DENIED;
1262 }
1263 }
1264
1265 // Update final pieces of touch state if the injector had permission.
1266 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001267 if (maskedAction == AMOTION_EVENT_ACTION_UP
1268 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1269 // All pointers up or canceled.
1270 mTempTouchState.reset();
1271 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1272 // First pointer went down.
1273 if (mTouchState.down) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001274#if DEBUG_FOCUS
1275 LOGD("Pointer down received while already down.");
1276#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001277 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001278 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1279 // One pointer went up.
1280 if (isSplit) {
1281 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1282 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Browna665ca82010-09-08 11:49:43 -07001283
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001284 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1285 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1286 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1287 touchedWindow.pointerIds.clearBit(pointerId);
1288 if (touchedWindow.pointerIds.isEmpty()) {
1289 mTempTouchState.windows.removeAt(i);
1290 continue;
1291 }
1292 }
1293 i += 1;
1294 }
Jeff Browna665ca82010-09-08 11:49:43 -07001295 }
Jeff Browna665ca82010-09-08 11:49:43 -07001296 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001297
1298 // Save changes to touch state.
1299 mTouchState.copyFrom(mTempTouchState);
Jeff Browna665ca82010-09-08 11:49:43 -07001300 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001301#if DEBUG_FOCUS
1302 LOGD("Not updating touch focus because injection was denied.");
1303#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001304 }
1305
1306Unresponsive:
Jeff Brownfef5b042010-10-27 18:43:51 -07001307 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1308 mTempTouchState.reset();
1309
Jeff Brown53a415e2010-09-15 15:18:56 -07001310 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1311 updateDispatchStatisticsLocked(currentTime, entry,
1312 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001313#if DEBUG_FOCUS
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001314 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1315 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown53a415e2010-09-15 15:18:56 -07001316 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001317#endif
1318 return injectionResult;
1319}
1320
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001321void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1322 BitSet32 pointerIds) {
Jeff Browna665ca82010-09-08 11:49:43 -07001323 mCurrentInputTargets.push();
1324
1325 InputTarget& target = mCurrentInputTargets.editTop();
1326 target.inputChannel = window->inputChannel;
1327 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001328 target.xOffset = - window->frameLeft;
1329 target.yOffset = - window->frameTop;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001330 target.pointerIds = pointerIds;
Jeff Browna665ca82010-09-08 11:49:43 -07001331}
1332
1333void InputDispatcher::addMonitoringTargetsLocked() {
1334 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1335 mCurrentInputTargets.push();
1336
1337 InputTarget& target = mCurrentInputTargets.editTop();
1338 target.inputChannel = mMonitoringChannels[i];
1339 target.flags = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07001340 target.xOffset = 0;
1341 target.yOffset = 0;
1342 }
1343}
1344
1345bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001346 const InjectionState* injectionState) {
1347 if (injectionState
Jeff Brown90f0cee2010-10-08 22:31:17 -07001348 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1349 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1350 if (window) {
1351 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1352 "with input channel %s owned by uid %d",
1353 injectionState->injectorPid, injectionState->injectorUid,
1354 window->inputChannel->getName().string(),
1355 window->ownerUid);
1356 } else {
1357 LOGW("Permission denied: injecting event from pid %d uid %d",
1358 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-09-08 11:49:43 -07001359 }
Jeff Brown90f0cee2010-10-08 22:31:17 -07001360 return false;
Jeff Browna665ca82010-09-08 11:49:43 -07001361 }
1362 return true;
1363}
1364
Jeff Brown35cf0e92010-10-05 12:26:23 -07001365bool InputDispatcher::isWindowObscuredAtPointLocked(
1366 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Browna665ca82010-09-08 11:49:43 -07001367 size_t numWindows = mWindows.size();
1368 for (size_t i = 0; i < numWindows; i++) {
1369 const InputWindow* other = & mWindows.itemAt(i);
1370 if (other == window) {
1371 break;
1372 }
Jeff Brown35cf0e92010-10-05 12:26:23 -07001373 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001374 return true;
1375 }
1376 }
1377 return false;
1378}
1379
Jeff Brown53a415e2010-09-15 15:18:56 -07001380bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1381 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1382 if (connectionIndex >= 0) {
1383 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1384 return connection->outboundQueue.isEmpty();
1385 } else {
1386 return true;
1387 }
1388}
1389
1390String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1391 const InputWindow* window) {
1392 if (application) {
1393 if (window) {
1394 String8 label(application->name);
1395 label.append(" - ");
1396 label.append(window->name);
1397 return label;
1398 } else {
1399 return application->name;
1400 }
1401 } else if (window) {
1402 return window->name;
1403 } else {
1404 return String8("<unknown application or window>");
1405 }
1406}
1407
Jeff Brownef3a8232010-10-18 13:21:23 -07001408void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1409 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Browne7a0d2b2010-10-29 21:50:21 -07001410 switch (eventEntry->type) {
1411 case EventEntry::TYPE_MOTION: {
Jeff Brownef3a8232010-10-18 13:21:23 -07001412 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Browne7a0d2b2010-10-29 21:50:21 -07001413 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1414 return;
1415 }
1416
Jeff Brownef3a8232010-10-18 13:21:23 -07001417 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1418 switch (motionEntry->action) {
1419 case AMOTION_EVENT_ACTION_DOWN:
1420 eventType = POWER_MANAGER_TOUCH_EVENT;
1421 break;
1422 case AMOTION_EVENT_ACTION_UP:
1423 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
1424 break;
1425 default:
Jeff Brownf6149c32010-11-01 20:35:46 -07001426 if (motionEntry->eventTime - motionEntry->downTime < LONG_TOUCH_DELAY) {
Jeff Brownef3a8232010-10-18 13:21:23 -07001427 eventType = POWER_MANAGER_TOUCH_EVENT;
1428 } else {
1429 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
1430 }
1431 break;
1432 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001433 }
Jeff Browne7a0d2b2010-10-29 21:50:21 -07001434 break;
1435 }
1436 case EventEntry::TYPE_KEY: {
1437 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1438 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1439 return;
1440 }
1441 break;
1442 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001443 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001444
Jeff Browna665ca82010-09-08 11:49:43 -07001445 CommandEntry* commandEntry = postCommandLocked(
1446 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Brownef3a8232010-10-18 13:21:23 -07001447 commandEntry->eventTime = eventEntry->eventTime;
Jeff Browna665ca82010-09-08 11:49:43 -07001448 commandEntry->userActivityEventType = eventType;
1449}
1450
Jeff Brown51d45a72010-06-17 20:52:56 -07001451void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1452 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -07001453 bool resumeWithAppendedMotionSample) {
1454#if DEBUG_DISPATCH_CYCLE
Jeff Brown53a415e2010-09-15 15:18:56 -07001455 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001456 "xOffset=%f, yOffset=%f, "
1457 "windowType=%d, pointerIds=0x%x, "
1458 "resumeWithAppendedMotionSample=%s",
Jeff Brown53a415e2010-09-15 15:18:56 -07001459 connection->getInputChannelName(), inputTarget->flags,
Jeff Browne839a582010-04-22 18:58:52 -07001460 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001461 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Browna665ca82010-09-08 11:49:43 -07001462 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -07001463#endif
1464
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001465 // Make sure we are never called for streaming when splitting across multiple windows.
1466 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1467 assert(! (resumeWithAppendedMotionSample && isSplit));
1468
Jeff Browne839a582010-04-22 18:58:52 -07001469 // Skip this event if the connection status is not normal.
Jeff Brown53a415e2010-09-15 15:18:56 -07001470 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Browne839a582010-04-22 18:58:52 -07001471 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001472#if DEBUG_DISPATCH_CYCLE
1473 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Browna665ca82010-09-08 11:49:43 -07001474 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown90f0cee2010-10-08 22:31:17 -07001475#endif
Jeff Browne839a582010-04-22 18:58:52 -07001476 return;
1477 }
1478
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001479 // Split a motion event if needed.
1480 if (isSplit) {
1481 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1482
1483 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1484 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1485 MotionEntry* splitMotionEntry = splitMotionEvent(
1486 originalMotionEntry, inputTarget->pointerIds);
1487#if DEBUG_FOCUS
1488 LOGD("channel '%s' ~ Split motion event.",
1489 connection->getInputChannelName());
1490 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1491#endif
1492 eventEntry = splitMotionEntry;
1493 }
1494 }
1495
Jeff Browne839a582010-04-22 18:58:52 -07001496 // Resume the dispatch cycle with a freshly appended motion sample.
1497 // First we check that the last dispatch entry in the outbound queue is for the same
1498 // motion event to which we appended the motion sample. If we find such a dispatch
1499 // entry, and if it is currently in progress then we try to stream the new sample.
1500 bool wasEmpty = connection->outboundQueue.isEmpty();
1501
1502 if (! wasEmpty && resumeWithAppendedMotionSample) {
1503 DispatchEntry* motionEventDispatchEntry =
1504 connection->findQueuedDispatchEntryForEvent(eventEntry);
1505 if (motionEventDispatchEntry) {
1506 // If the dispatch entry is not in progress, then we must be busy dispatching an
1507 // earlier event. Not a problem, the motion event is on the outbound queue and will
1508 // be dispatched later.
1509 if (! motionEventDispatchEntry->inProgress) {
1510#if DEBUG_BATCHING
1511 LOGD("channel '%s' ~ Not streaming because the motion event has "
1512 "not yet been dispatched. "
1513 "(Waiting for earlier events to be consumed.)",
1514 connection->getInputChannelName());
1515#endif
1516 return;
1517 }
1518
1519 // If the dispatch entry is in progress but it already has a tail of pending
1520 // motion samples, then it must mean that the shared memory buffer filled up.
1521 // Not a problem, when this dispatch cycle is finished, we will eventually start
1522 // a new dispatch cycle to process the tail and that tail includes the newly
1523 // appended motion sample.
1524 if (motionEventDispatchEntry->tailMotionSample) {
1525#if DEBUG_BATCHING
1526 LOGD("channel '%s' ~ Not streaming because no new samples can "
1527 "be appended to the motion event in this dispatch cycle. "
1528 "(Waiting for next dispatch cycle to start.)",
1529 connection->getInputChannelName());
1530#endif
1531 return;
1532 }
1533
1534 // The dispatch entry is in progress and is still potentially open for streaming.
1535 // Try to stream the new motion sample. This might fail if the consumer has already
1536 // consumed the motion event (or if the channel is broken).
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001537 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1538 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Browne839a582010-04-22 18:58:52 -07001539 status_t status = connection->inputPublisher.appendMotionSample(
1540 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1541 if (status == OK) {
1542#if DEBUG_BATCHING
1543 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1544 connection->getInputChannelName());
1545#endif
1546 return;
1547 }
1548
1549#if DEBUG_BATCHING
1550 if (status == NO_MEMORY) {
1551 LOGD("channel '%s' ~ Could not append motion sample to currently "
1552 "dispatched move event because the shared memory buffer is full. "
1553 "(Waiting for next dispatch cycle to start.)",
1554 connection->getInputChannelName());
1555 } else if (status == status_t(FAILED_TRANSACTION)) {
1556 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown50de30a2010-06-22 01:27:15 -07001557 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-04-22 18:58:52 -07001558 "(Waiting for next dispatch cycle to start.)",
1559 connection->getInputChannelName());
1560 } else {
1561 LOGD("channel '%s' ~ Could not append motion sample to currently "
1562 "dispatched move event due to an error, status=%d. "
1563 "(Waiting for next dispatch cycle to start.)",
1564 connection->getInputChannelName(), status);
1565 }
1566#endif
1567 // Failed to stream. Start a new tail of pending motion samples to dispatch
1568 // in the next cycle.
1569 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1570 return;
1571 }
1572 }
1573
1574 // This is a new event.
1575 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Browna665ca82010-09-08 11:49:43 -07001576 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown53a415e2010-09-15 15:18:56 -07001577 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1578 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001579 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001580 }
1581
Jeff Browne839a582010-04-22 18:58:52 -07001582 // Handle the case where we could not stream a new motion sample because the consumer has
1583 // already consumed the motion event (otherwise the corresponding dispatch entry would
1584 // still be in the outbound queue for this connection). We set the head motion sample
1585 // to the list starting with the newly appended motion sample.
1586 if (resumeWithAppendedMotionSample) {
1587#if DEBUG_BATCHING
1588 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1589 "that cannot be streamed because the motion event has already been consumed.",
1590 connection->getInputChannelName());
1591#endif
1592 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1593 dispatchEntry->headMotionSample = appendedMotionSample;
1594 }
1595
1596 // Enqueue the dispatch entry.
1597 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1598
1599 // If the outbound queue was previously empty, start the dispatch cycle going.
1600 if (wasEmpty) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001601 activateConnectionLocked(connection.get());
Jeff Brown53a415e2010-09-15 15:18:56 -07001602 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001603 }
1604}
1605
Jeff Brown51d45a72010-06-17 20:52:56 -07001606void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown53a415e2010-09-15 15:18:56 -07001607 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001608#if DEBUG_DISPATCH_CYCLE
1609 LOGD("channel '%s' ~ startDispatchCycle",
1610 connection->getInputChannelName());
1611#endif
1612
1613 assert(connection->status == Connection::STATUS_NORMAL);
1614 assert(! connection->outboundQueue.isEmpty());
1615
Jeff Browna665ca82010-09-08 11:49:43 -07001616 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001617 assert(! dispatchEntry->inProgress);
1618
Jeff Browna665ca82010-09-08 11:49:43 -07001619 // Mark the dispatch entry as in progress.
1620 dispatchEntry->inProgress = true;
1621
1622 // Update the connection's input state.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001623 EventEntry* eventEntry = dispatchEntry->eventEntry;
1624 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001625
1626#if FILTER_INPUT_EVENTS
1627 // Filter out inconsistent sequences of input events.
1628 // The input system may drop or inject events in a way that could violate implicit
1629 // invariants on input state and potentially cause an application to crash
1630 // or think that a key or pointer is stuck down. Technically we make no guarantees
1631 // of consistency but it would be nice to improve on this where possible.
1632 // XXX: This code is a proof of concept only. Not ready for prime time.
1633 if (consistency == InputState::TOLERABLE) {
1634#if DEBUG_DISPATCH_CYCLE
1635 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1636 "current input state but that is likely to be tolerated by the application.",
1637 connection->getInputChannelName());
1638#endif
1639 } else if (consistency == InputState::BROKEN) {
1640 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1641 "current input state and that is likely to cause the application to crash.",
1642 connection->getInputChannelName());
1643 startNextDispatchCycleLocked(currentTime, connection);
1644 return;
1645 }
1646#endif
Jeff Browne839a582010-04-22 18:58:52 -07001647
1648 // Publish the event.
1649 status_t status;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001650 switch (eventEntry->type) {
Jeff Browne839a582010-04-22 18:58:52 -07001651 case EventEntry::TYPE_KEY: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001652 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001653
1654 // Apply target flags.
1655 int32_t action = keyEntry->action;
1656 int32_t flags = keyEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001657
1658 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001659 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-04-22 18:58:52 -07001660 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1661 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1662 keyEntry->eventTime);
1663
1664 if (status) {
1665 LOGE("channel '%s' ~ Could not publish key event, "
1666 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001667 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001668 return;
1669 }
1670 break;
1671 }
1672
1673 case EventEntry::TYPE_MOTION: {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001674 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001675
1676 // Apply target flags.
1677 int32_t action = motionEntry->action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07001678 int32_t flags = motionEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001679 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001680 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -07001681 }
Jeff Brownaf30ff62010-09-01 17:01:00 -07001682 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1683 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1684 }
Jeff Browne839a582010-04-22 18:58:52 -07001685
1686 // If headMotionSample is non-NULL, then it points to the first new sample that we
1687 // were unable to dispatch during the previous cycle so we resume dispatching from
1688 // that point in the list of motion samples.
1689 // Otherwise, we just start from the first sample of the motion event.
1690 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1691 if (! firstMotionSample) {
1692 firstMotionSample = & motionEntry->firstSample;
1693 }
1694
Jeff Brownf26db0d2010-07-16 17:21:06 -07001695 // Set the X and Y offset depending on the input source.
1696 float xOffset, yOffset;
1697 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1698 xOffset = dispatchEntry->xOffset;
1699 yOffset = dispatchEntry->yOffset;
1700 } else {
1701 xOffset = 0.0f;
1702 yOffset = 0.0f;
1703 }
1704
Jeff Browne839a582010-04-22 18:58:52 -07001705 // Publish the motion event and the first motion sample.
1706 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001707 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -07001708 xOffset, yOffset,
Jeff Browne839a582010-04-22 18:58:52 -07001709 motionEntry->xPrecision, motionEntry->yPrecision,
1710 motionEntry->downTime, firstMotionSample->eventTime,
1711 motionEntry->pointerCount, motionEntry->pointerIds,
1712 firstMotionSample->pointerCoords);
1713
1714 if (status) {
1715 LOGE("channel '%s' ~ Could not publish motion event, "
1716 "status=%d", connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001717 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001718 return;
1719 }
1720
1721 // Append additional motion samples.
1722 MotionSample* nextMotionSample = firstMotionSample->next;
1723 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1724 status = connection->inputPublisher.appendMotionSample(
1725 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1726 if (status == NO_MEMORY) {
1727#if DEBUG_DISPATCH_CYCLE
1728 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1729 "be sent in the next dispatch cycle.",
1730 connection->getInputChannelName());
1731#endif
1732 break;
1733 }
1734 if (status != OK) {
1735 LOGE("channel '%s' ~ Could not append motion sample "
1736 "for a reason other than out of memory, status=%d",
1737 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001738 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001739 return;
1740 }
1741 }
1742
1743 // Remember the next motion sample that we could not dispatch, in case we ran out
1744 // of space in the shared memory buffer.
1745 dispatchEntry->tailMotionSample = nextMotionSample;
1746 break;
1747 }
1748
1749 default: {
1750 assert(false);
1751 }
1752 }
1753
1754 // Send the dispatch signal.
1755 status = connection->inputPublisher.sendDispatchSignal();
1756 if (status) {
1757 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1758 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001759 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001760 return;
1761 }
1762
1763 // Record information about the newly started dispatch cycle.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001764 connection->lastEventTime = eventEntry->eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07001765 connection->lastDispatchTime = currentTime;
1766
Jeff Browne839a582010-04-22 18:58:52 -07001767 // Notify other system components.
1768 onDispatchCycleStartedLocked(currentTime, connection);
1769}
1770
Jeff Brown51d45a72010-06-17 20:52:56 -07001771void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1772 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001773#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001774 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -07001775 "%01.1fms since dispatch",
1776 connection->getInputChannelName(),
1777 connection->getEventLatencyMillis(currentTime),
1778 connection->getDispatchLatencyMillis(currentTime));
1779#endif
1780
Jeff Brown54bc2812010-06-15 01:31:58 -07001781 if (connection->status == Connection::STATUS_BROKEN
1782 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001783 return;
1784 }
1785
Jeff Brown53a415e2010-09-15 15:18:56 -07001786 // Notify other system components.
1787 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001788
1789 // Reset the publisher since the event has been consumed.
1790 // We do this now so that the publisher can release some of its internal resources
1791 // while waiting for the next dispatch cycle to begin.
1792 status_t status = connection->inputPublisher.reset();
1793 if (status) {
1794 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1795 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001796 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001797 return;
1798 }
1799
Jeff Browna665ca82010-09-08 11:49:43 -07001800 startNextDispatchCycleLocked(currentTime, connection);
1801}
1802
1803void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1804 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001805 // Start the next dispatch cycle for this connection.
1806 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001807 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001808 if (dispatchEntry->inProgress) {
1809 // Finish or resume current event in progress.
1810 if (dispatchEntry->tailMotionSample) {
1811 // We have a tail of undispatched motion samples.
1812 // Reuse the same DispatchEntry and start a new cycle.
1813 dispatchEntry->inProgress = false;
1814 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1815 dispatchEntry->tailMotionSample = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07001816 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001817 return;
1818 }
1819 // Finished.
1820 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001821 if (dispatchEntry->hasForegroundTarget()) {
1822 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001823 }
Jeff Browne839a582010-04-22 18:58:52 -07001824 mAllocator.releaseDispatchEntry(dispatchEntry);
1825 } else {
1826 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown53a415e2010-09-15 15:18:56 -07001827 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001828 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001829 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001830 return;
1831 }
1832 }
1833
1834 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001835 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001836}
1837
Jeff Brown90f0cee2010-10-08 22:31:17 -07001838void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1839 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001840#if DEBUG_DISPATCH_CYCLE
Jeff Brown90f0cee2010-10-08 22:31:17 -07001841 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001842 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001843#endif
1844
Jeff Browna665ca82010-09-08 11:49:43 -07001845 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001846 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001847
Jeff Brown90f0cee2010-10-08 22:31:17 -07001848 // The connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001849 // Ignore already broken or zombie connections.
Jeff Brown90f0cee2010-10-08 22:31:17 -07001850 if (connection->status == Connection::STATUS_NORMAL) {
1851 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001852
Jeff Brown90f0cee2010-10-08 22:31:17 -07001853 // Notify other system components.
1854 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001855 }
Jeff Browne839a582010-04-22 18:58:52 -07001856}
1857
Jeff Brown53a415e2010-09-15 15:18:56 -07001858void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1859 while (! connection->outboundQueue.isEmpty()) {
1860 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1861 if (dispatchEntry->hasForegroundTarget()) {
1862 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001863 }
1864 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001865 }
1866
Jeff Brown53a415e2010-09-15 15:18:56 -07001867 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001868}
1869
Jeff Brown59abe7e2010-09-13 23:17:30 -07001870int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-04-22 18:58:52 -07001871 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1872
1873 { // acquire lock
1874 AutoMutex _l(d->mLock);
1875
1876 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1877 if (connectionIndex < 0) {
1878 LOGE("Received spurious receive callback for unknown input channel. "
1879 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001880 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001881 }
1882
Jeff Brown51d45a72010-06-17 20:52:56 -07001883 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001884
1885 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001886 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-04-22 18:58:52 -07001887 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1888 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001889 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001890 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001891 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001892 }
1893
Jeff Brown59abe7e2010-09-13 23:17:30 -07001894 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001895 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1896 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001897 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001898 }
1899
1900 status_t status = connection->inputPublisher.receiveFinishedSignal();
1901 if (status) {
1902 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1903 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001904 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001905 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001906 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001907 }
1908
Jeff Brown51d45a72010-06-17 20:52:56 -07001909 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001910 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001911 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001912 } // release lock
1913}
1914
Jeff Brown90f0cee2010-10-08 22:31:17 -07001915void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1916 InputState::CancelationOptions options, const char* reason) {
1917 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1918 synthesizeCancelationEventsForConnectionLocked(
1919 mConnectionsByReceiveFd.valueAt(i), options, reason);
1920 }
1921}
1922
1923void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1924 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1925 const char* reason) {
1926 ssize_t index = getConnectionIndexLocked(channel);
1927 if (index >= 0) {
1928 synthesizeCancelationEventsForConnectionLocked(
1929 mConnectionsByReceiveFd.valueAt(index), options, reason);
1930 }
1931}
1932
1933void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1934 const sp<Connection>& connection, InputState::CancelationOptions options,
1935 const char* reason) {
1936 nsecs_t currentTime = now();
1937
1938 mTempCancelationEvents.clear();
1939 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1940 mTempCancelationEvents, options);
1941
1942 if (! mTempCancelationEvents.isEmpty()
1943 && connection->status != Connection::STATUS_BROKEN) {
1944#if DEBUG_OUTBOUND_EVENT_DETAILS
1945 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1946 "with reality: %s, options=%d.",
1947 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1948#endif
1949 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1950 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1951 switch (cancelationEventEntry->type) {
1952 case EventEntry::TYPE_KEY:
1953 logOutboundKeyDetailsLocked("cancel - ",
1954 static_cast<KeyEntry*>(cancelationEventEntry));
1955 break;
1956 case EventEntry::TYPE_MOTION:
1957 logOutboundMotionDetailsLocked("cancel - ",
1958 static_cast<MotionEntry*>(cancelationEventEntry));
1959 break;
1960 }
1961
1962 int32_t xOffset, yOffset;
1963 const InputWindow* window = getWindowLocked(connection->inputChannel);
1964 if (window) {
1965 xOffset = -window->frameLeft;
1966 yOffset = -window->frameTop;
1967 } else {
1968 xOffset = 0;
1969 yOffset = 0;
1970 }
1971
1972 DispatchEntry* cancelationDispatchEntry =
1973 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1974 0, xOffset, yOffset);
1975 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1976
1977 mAllocator.releaseEventEntry(cancelationEventEntry);
1978 }
1979
1980 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1981 startDispatchCycleLocked(currentTime, connection);
1982 }
1983 }
1984}
1985
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001986InputDispatcher::MotionEntry*
1987InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1988 assert(pointerIds.value != 0);
1989
1990 uint32_t splitPointerIndexMap[MAX_POINTERS];
1991 int32_t splitPointerIds[MAX_POINTERS];
1992 PointerCoords splitPointerCoords[MAX_POINTERS];
1993
1994 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1995 uint32_t splitPointerCount = 0;
1996
1997 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1998 originalPointerIndex++) {
1999 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
2000 if (pointerIds.hasBit(pointerId)) {
2001 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2002 splitPointerIds[splitPointerCount] = pointerId;
2003 splitPointerCoords[splitPointerCount] =
2004 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
2005 splitPointerCount += 1;
2006 }
2007 }
2008 assert(splitPointerCount == pointerIds.count());
2009
2010 int32_t action = originalMotionEntry->action;
2011 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2012 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2013 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2014 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2015 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2016 if (pointerIds.hasBit(pointerId)) {
2017 if (pointerIds.count() == 1) {
2018 // The first/last pointer went down/up.
2019 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2020 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brownffb16d62010-09-27 16:35:11 -07002021 } else {
2022 // A secondary pointer went down/up.
2023 uint32_t splitPointerIndex = 0;
2024 while (pointerId != splitPointerIds[splitPointerIndex]) {
2025 splitPointerIndex += 1;
2026 }
2027 action = maskedAction | (splitPointerIndex
2028 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002029 }
2030 } else {
2031 // An unrelated pointer changed.
2032 action = AMOTION_EVENT_ACTION_MOVE;
2033 }
2034 }
2035
2036 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2037 originalMotionEntry->eventTime,
2038 originalMotionEntry->deviceId,
2039 originalMotionEntry->source,
2040 originalMotionEntry->policyFlags,
2041 action,
2042 originalMotionEntry->flags,
2043 originalMotionEntry->metaState,
2044 originalMotionEntry->edgeFlags,
2045 originalMotionEntry->xPrecision,
2046 originalMotionEntry->yPrecision,
2047 originalMotionEntry->downTime,
2048 splitPointerCount, splitPointerIds, splitPointerCoords);
2049
2050 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2051 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2052 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2053 splitPointerIndex++) {
2054 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2055 splitPointerCoords[splitPointerIndex] =
2056 originalMotionSample->pointerCoords[originalPointerIndex];
2057 }
2058
2059 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2060 splitPointerCoords);
2061 }
2062
2063 return splitMotionEntry;
2064}
2065
Jeff Brown54bc2812010-06-15 01:31:58 -07002066void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002067#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -07002068 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07002069#endif
2070
Jeff Browna665ca82010-09-08 11:49:43 -07002071 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002072 { // acquire lock
2073 AutoMutex _l(mLock);
2074
Jeff Brown51d45a72010-06-17 20:52:56 -07002075 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browna665ca82010-09-08 11:49:43 -07002076 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002077 } // release lock
2078
Jeff Browna665ca82010-09-08 11:49:43 -07002079 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002080 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002081 }
2082}
2083
Jeff Brown5c1ed842010-07-14 18:48:53 -07002084void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -07002085 uint32_t policyFlags, int32_t action, int32_t flags,
2086 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2087#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002088 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07002089 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07002090 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -07002091 keyCode, scanCode, metaState, downTime);
2092#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002093 if (! validateKeyEvent(action)) {
2094 return;
2095 }
Jeff Browne839a582010-04-22 18:58:52 -07002096
Johan Redestigbbd0dc82011-02-25 16:45:17 +01002097 /* According to http://source.android.com/porting/keymaps_keyboard_input.html
2098 * Key definitions: Key definitions follow the syntax key SCANCODE KEYCODE [FLAGS...],
2099 * where SCANCODE is a number, KEYCODE is defined in your specific keylayout file
2100 * (android.keylayout.xxx), and potential FLAGS are defined as follows:
2101 * SHIFT: While pressed, the shift key modifier is set
2102 * ALT: While pressed, the alt key modifier is set
2103 * CAPS: While pressed, the caps lock key modifier is set
2104 * Since KeyEvent.java doesn't check if Cap lock is ON and we don't have a
2105 * modifer state for cap lock, we will not support it.
2106 */
2107 if (policyFlags & POLICY_FLAG_ALT) {
2108 metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON;
2109 }
2110 if (policyFlags & POLICY_FLAG_ALT_GR) {
2111 metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON;
2112 }
2113 if (policyFlags & POLICY_FLAG_SHIFT) {
2114 metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON;
2115 }
2116
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002117 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002118 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2119 keyCode, scanCode, /*byref*/ policyFlags);
2120
Jeff Browna665ca82010-09-08 11:49:43 -07002121 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002122 { // acquire lock
2123 AutoMutex _l(mLock);
2124
Jeff Brown51d45a72010-06-17 20:52:56 -07002125 int32_t repeatCount = 0;
2126 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002127 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07002128 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07002129
Jeff Browna665ca82010-09-08 11:49:43 -07002130 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002131 } // release lock
2132
Jeff Browna665ca82010-09-08 11:49:43 -07002133 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002134 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002135 }
2136}
2137
Jeff Brown5c1ed842010-07-14 18:48:53 -07002138void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002139 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002140 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2141 float xPrecision, float yPrecision, nsecs_t downTime) {
2142#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002143 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002144 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2145 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2146 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002147 xPrecision, yPrecision, downTime);
2148 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07002149 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002150 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07002151 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07002152 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-08-30 03:02:23 -07002153 pointerCoords[i].pressure, pointerCoords[i].size,
2154 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2155 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2156 pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -07002157 }
2158#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002159 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2160 return;
2161 }
Jeff Browne839a582010-04-22 18:58:52 -07002162
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002163 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002164 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2165
Jeff Browna665ca82010-09-08 11:49:43 -07002166 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002167 { // acquire lock
2168 AutoMutex _l(mLock);
2169
2170 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07002171 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07002172 // BATCHING CASE
2173 //
2174 // Try to append a move sample to the tail of the inbound queue for this device.
2175 // Give up if we encounter a non-move motion event for this device since that
2176 // means we cannot append any new samples until a new motion event has started.
Jeff Browna665ca82010-09-08 11:49:43 -07002177 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2178 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07002179 if (entry->type != EventEntry::TYPE_MOTION) {
2180 // Keep looking for motion events.
2181 continue;
2182 }
2183
2184 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2185 if (motionEntry->deviceId != deviceId) {
2186 // Keep looking for this device.
2187 continue;
2188 }
2189
Jeff Brown5c1ed842010-07-14 18:48:53 -07002190 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07002191 || motionEntry->pointerCount != pointerCount
2192 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07002193 // Last motion event in the queue for this device is not compatible for
2194 // appending new samples. Stop here.
2195 goto NoBatchingOrStreaming;
2196 }
2197
2198 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07002199 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07002200 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002201#if DEBUG_BATCHING
2202 LOGD("Appended motion sample onto batch for most recent "
2203 "motion event for this device in the inbound queue.");
2204#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07002205 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002206 }
2207
2208 // STREAMING CASE
2209 //
2210 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07002211 // Search the outbound queue for the current foreground targets to find a dispatched
2212 // motion event that is still in progress. If found, then, appen the new sample to
2213 // that event and push it out to all current targets. The logic in
2214 // prepareDispatchCycleLocked takes care of the case where some targets may
2215 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown54bc2812010-06-15 01:31:58 -07002216 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002217 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2218 const InputTarget& inputTarget = mCurrentInputTargets[i];
2219 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2220 // Skip non-foreground targets. We only want to stream if there is at
2221 // least one foreground target whose dispatch is still in progress.
2222 continue;
Jeff Browne839a582010-04-22 18:58:52 -07002223 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002224
2225 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2226 if (connectionIndex < 0) {
2227 // Connection must no longer be valid.
2228 continue;
2229 }
2230
2231 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2232 if (connection->outboundQueue.isEmpty()) {
2233 // This foreground target has an empty outbound queue.
2234 continue;
2235 }
2236
2237 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2238 if (! dispatchEntry->inProgress
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002239 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2240 || dispatchEntry->isSplit()) {
2241 // No motion event is being dispatched, or it is being split across
2242 // windows in which case we cannot stream.
Jeff Brown53a415e2010-09-15 15:18:56 -07002243 continue;
2244 }
2245
2246 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2247 dispatchEntry->eventEntry);
2248 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2249 || motionEntry->deviceId != deviceId
2250 || motionEntry->pointerCount != pointerCount
2251 || motionEntry->isInjected()) {
2252 // The motion event is not compatible with this move.
2253 continue;
2254 }
2255
2256 // Hurray! This foreground target is currently dispatching a move event
2257 // that we can stream onto. Append the motion sample and resume dispatch.
2258 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2259#if DEBUG_BATCHING
2260 LOGD("Appended motion sample onto batch for most recently dispatched "
2261 "motion event for this device in the outbound queues. "
2262 "Attempting to stream the motion sample.");
2263#endif
2264 nsecs_t currentTime = now();
2265 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2266 true /*resumeWithAppendedMotionSample*/);
2267
2268 runCommandsLockedInterruptible();
2269 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002270 }
2271 }
2272
2273NoBatchingOrStreaming:;
2274 }
2275
2276 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07002277 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002278 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002279 xPrecision, yPrecision, downTime,
2280 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002281
Jeff Browna665ca82010-09-08 11:49:43 -07002282 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002283 } // release lock
2284
Jeff Browna665ca82010-09-08 11:49:43 -07002285 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002286 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002287 }
2288}
2289
Jeff Brown90f0cee2010-10-08 22:31:17 -07002290void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2291 uint32_t policyFlags) {
2292#if DEBUG_INBOUND_EVENT_DETAILS
2293 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2294 switchCode, switchValue, policyFlags);
2295#endif
2296
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002297 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002298 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2299}
2300
Jeff Brown51d45a72010-06-17 20:52:56 -07002301int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07002302 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002303#if DEBUG_INBOUND_EVENT_DETAILS
2304 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002305 "syncMode=%d, timeoutMillis=%d",
2306 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07002307#endif
2308
2309 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002310
2311 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2312 if (hasInjectionPermission(injectorPid, injectorUid)) {
2313 policyFlags |= POLICY_FLAG_TRUSTED;
2314 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002315
Jeff Brown90f0cee2010-10-08 22:31:17 -07002316 EventEntry* injectedEntry;
2317 switch (event->getType()) {
2318 case AINPUT_EVENT_TYPE_KEY: {
2319 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2320 int32_t action = keyEvent->getAction();
2321 if (! validateKeyEvent(action)) {
Jeff Browna665ca82010-09-08 11:49:43 -07002322 return INPUT_EVENT_INJECTION_FAILED;
2323 }
2324
Jeff Brown90f0cee2010-10-08 22:31:17 -07002325 nsecs_t eventTime = keyEvent->getEventTime();
2326 int32_t deviceId = keyEvent->getDeviceId();
2327 int32_t flags = keyEvent->getFlags();
2328 int32_t keyCode = keyEvent->getKeyCode();
2329 int32_t scanCode = keyEvent->getScanCode();
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002330 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2331 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002332
Jeff Brown90f0cee2010-10-08 22:31:17 -07002333 mLock.lock();
2334 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2335 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2336 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2337 break;
2338 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002339
Jeff Brown90f0cee2010-10-08 22:31:17 -07002340 case AINPUT_EVENT_TYPE_MOTION: {
2341 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2342 int32_t action = motionEvent->getAction();
2343 size_t pointerCount = motionEvent->getPointerCount();
2344 const int32_t* pointerIds = motionEvent->getPointerIds();
2345 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2346 return INPUT_EVENT_INJECTION_FAILED;
2347 }
2348
2349 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002350 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002351
2352 mLock.lock();
2353 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2354 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2355 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2356 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2357 action, motionEvent->getFlags(),
2358 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2359 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2360 motionEvent->getDownTime(), uint32_t(pointerCount),
2361 pointerIds, samplePointerCoords);
2362 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2363 sampleEventTimes += 1;
2364 samplePointerCoords += pointerCount;
2365 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2366 }
2367 injectedEntry = motionEntry;
2368 break;
2369 }
2370
2371 default:
2372 LOGW("Cannot inject event of type %d", event->getType());
2373 return INPUT_EVENT_INJECTION_FAILED;
2374 }
2375
2376 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2377 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2378 injectionState->injectionIsAsync = true;
2379 }
2380
2381 injectionState->refCount += 1;
2382 injectedEntry->injectionState = injectionState;
2383
2384 bool needWake = enqueueInboundEventLocked(injectedEntry);
2385 mLock.unlock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002386
Jeff Browna665ca82010-09-08 11:49:43 -07002387 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002388 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07002389 }
2390
2391 int32_t injectionResult;
2392 { // acquire lock
2393 AutoMutex _l(mLock);
2394
Jeff Brownf67c53e2010-07-28 15:48:59 -07002395 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2396 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2397 } else {
2398 for (;;) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002399 injectionResult = injectionState->injectionResult;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002400 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2401 break;
2402 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002403
Jeff Brown51d45a72010-06-17 20:52:56 -07002404 nsecs_t remainingTimeout = endTime - now();
2405 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002406#if DEBUG_INJECTION
2407 LOGD("injectInputEvent - Timed out waiting for injection result "
2408 "to become available.");
2409#endif
Jeff Brown51d45a72010-06-17 20:52:56 -07002410 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2411 break;
2412 }
2413
Jeff Brownf67c53e2010-07-28 15:48:59 -07002414 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2415 }
2416
2417 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2418 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002419 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002420#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002421 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002422 injectionState->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002423#endif
2424 nsecs_t remainingTimeout = endTime - now();
2425 if (remainingTimeout <= 0) {
2426#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002427 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002428 "dispatches to finish.");
2429#endif
2430 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2431 break;
2432 }
2433
2434 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2435 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002436 }
2437 }
2438
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002439 mAllocator.releaseInjectionState(injectionState);
Jeff Brown51d45a72010-06-17 20:52:56 -07002440 } // release lock
2441
Jeff Brownf67c53e2010-07-28 15:48:59 -07002442#if DEBUG_INJECTION
2443 LOGD("injectInputEvent - Finished with result %d. "
2444 "injectorPid=%d, injectorUid=%d",
2445 injectionResult, injectorPid, injectorUid);
2446#endif
2447
Jeff Brown51d45a72010-06-17 20:52:56 -07002448 return injectionResult;
2449}
2450
Jeff Brown90f0cee2010-10-08 22:31:17 -07002451bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2452 return injectorUid == 0
2453 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2454}
2455
Jeff Brown51d45a72010-06-17 20:52:56 -07002456void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002457 InjectionState* injectionState = entry->injectionState;
2458 if (injectionState) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002459#if DEBUG_INJECTION
2460 LOGD("Setting input event injection result to %d. "
2461 "injectorPid=%d, injectorUid=%d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002462 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002463#endif
2464
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002465 if (injectionState->injectionIsAsync) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002466 // Log the outcome since the injector did not wait for the injection result.
2467 switch (injectionResult) {
2468 case INPUT_EVENT_INJECTION_SUCCEEDED:
2469 LOGV("Asynchronous input event injection succeeded.");
2470 break;
2471 case INPUT_EVENT_INJECTION_FAILED:
2472 LOGW("Asynchronous input event injection failed.");
2473 break;
2474 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2475 LOGW("Asynchronous input event injection permission denied.");
2476 break;
2477 case INPUT_EVENT_INJECTION_TIMED_OUT:
2478 LOGW("Asynchronous input event injection timed out.");
2479 break;
2480 }
2481 }
2482
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002483 injectionState->injectionResult = injectionResult;
Jeff Brown51d45a72010-06-17 20:52:56 -07002484 mInjectionResultAvailableCondition.broadcast();
2485 }
2486}
2487
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002488void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2489 InjectionState* injectionState = entry->injectionState;
2490 if (injectionState) {
2491 injectionState->pendingForegroundDispatches += 1;
2492 }
2493}
2494
Jeff Brown53a415e2010-09-15 15:18:56 -07002495void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002496 InjectionState* injectionState = entry->injectionState;
2497 if (injectionState) {
2498 injectionState->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002499
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002500 if (injectionState->pendingForegroundDispatches == 0) {
2501 mInjectionSyncFinishedCondition.broadcast();
2502 }
Jeff Browna665ca82010-09-08 11:49:43 -07002503 }
2504}
2505
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002506const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2507 for (size_t i = 0; i < mWindows.size(); i++) {
2508 const InputWindow* window = & mWindows[i];
2509 if (window->inputChannel == inputChannel) {
2510 return window;
2511 }
2512 }
2513 return NULL;
2514}
2515
Jeff Browna665ca82010-09-08 11:49:43 -07002516void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2517#if DEBUG_FOCUS
2518 LOGD("setInputWindows");
2519#endif
2520 { // acquire lock
2521 AutoMutex _l(mLock);
2522
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002523 // Clear old window pointers.
Jeff Brown90f0cee2010-10-08 22:31:17 -07002524 sp<InputChannel> oldFocusedWindowChannel;
2525 if (mFocusedWindow) {
2526 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2527 mFocusedWindow = NULL;
2528 }
2529
Jeff Browna665ca82010-09-08 11:49:43 -07002530 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002531
2532 // Loop over new windows and rebuild the necessary window pointers for
2533 // tracking focus and touch.
Jeff Browna665ca82010-09-08 11:49:43 -07002534 mWindows.appendVector(inputWindows);
2535
2536 size_t numWindows = mWindows.size();
2537 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002538 const InputWindow* window = & mWindows.itemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07002539 if (window->hasFocus) {
2540 mFocusedWindow = window;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002541 break;
Jeff Browna665ca82010-09-08 11:49:43 -07002542 }
2543 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002544
Jeff Brown90f0cee2010-10-08 22:31:17 -07002545 if (oldFocusedWindowChannel != NULL) {
2546 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2547#if DEBUG_FOCUS
2548 LOGD("Focus left window: %s",
2549 oldFocusedWindowChannel->getName().string());
2550#endif
2551 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2552 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2553 oldFocusedWindowChannel.clear();
2554 }
2555 }
2556 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2557#if DEBUG_FOCUS
2558 LOGD("Focus entered window: %s",
2559 mFocusedWindow->inputChannel->getName().string());
2560#endif
2561 }
2562
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002563 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2564 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2565 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2566 if (window) {
2567 touchedWindow.window = window;
2568 i += 1;
2569 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -07002570#if DEBUG_FOCUS
2571 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2572#endif
Jeff Brown90f0cee2010-10-08 22:31:17 -07002573 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2574 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownb13d7b52010-10-15 16:20:51 -07002575 mTouchState.windows.removeAt(i);
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002576 }
2577 }
Jeff Browna665ca82010-09-08 11:49:43 -07002578
Jeff Browna665ca82010-09-08 11:49:43 -07002579#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002580 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002581#endif
2582 } // release lock
2583
2584 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002585 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002586}
2587
2588void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2589#if DEBUG_FOCUS
2590 LOGD("setFocusedApplication");
2591#endif
2592 { // acquire lock
2593 AutoMutex _l(mLock);
2594
2595 releaseFocusedApplicationLocked();
2596
2597 if (inputApplication) {
2598 mFocusedApplicationStorage = *inputApplication;
2599 mFocusedApplication = & mFocusedApplicationStorage;
2600 }
2601
2602#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002603 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002604#endif
2605 } // release lock
2606
2607 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002608 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002609}
2610
2611void InputDispatcher::releaseFocusedApplicationLocked() {
2612 if (mFocusedApplication) {
2613 mFocusedApplication = NULL;
2614 mFocusedApplicationStorage.handle.clear();
2615 }
2616}
2617
2618void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2619#if DEBUG_FOCUS
2620 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2621#endif
2622
2623 bool changed;
2624 { // acquire lock
2625 AutoMutex _l(mLock);
2626
2627 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brownfef5b042010-10-27 18:43:51 -07002628 if (mDispatchFrozen && !frozen) {
Jeff Browna665ca82010-09-08 11:49:43 -07002629 resetANRTimeoutsLocked();
2630 }
2631
Jeff Brownfef5b042010-10-27 18:43:51 -07002632 if (mDispatchEnabled && !enabled) {
2633 resetAndDropEverythingLocked("dispatcher is being disabled");
2634 }
2635
Jeff Browna665ca82010-09-08 11:49:43 -07002636 mDispatchEnabled = enabled;
2637 mDispatchFrozen = frozen;
2638 changed = true;
2639 } else {
2640 changed = false;
2641 }
2642
2643#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002644 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002645#endif
2646 } // release lock
2647
2648 if (changed) {
2649 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002650 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002651 }
2652}
2653
Jeff Brownfef5b042010-10-27 18:43:51 -07002654void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2655#if DEBUG_FOCUS
2656 LOGD("Resetting and dropping all events (%s).", reason);
2657#endif
2658
2659 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2660
2661 resetKeyRepeatLocked();
2662 releasePendingEventLocked();
2663 drainInboundQueueLocked();
2664 resetTargetsLocked();
2665
2666 mTouchState.reset();
2667}
2668
Jeff Browna665ca82010-09-08 11:49:43 -07002669void InputDispatcher::logDispatchStateLocked() {
2670 String8 dump;
2671 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002672
2673 char* text = dump.lockBuffer(dump.size());
2674 char* start = text;
2675 while (*start != '\0') {
2676 char* end = strchr(start, '\n');
2677 if (*end == '\n') {
2678 *(end++) = '\0';
2679 }
2680 LOGD("%s", start);
2681 start = end;
2682 }
Jeff Browna665ca82010-09-08 11:49:43 -07002683}
2684
2685void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002686 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2687 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002688
2689 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002690 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002691 mFocusedApplication->name.string(),
2692 mFocusedApplication->dispatchingTimeout / 1000000.0);
2693 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002694 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002695 }
Jeff Brown2806e382010-10-01 17:46:21 -07002696 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002697 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-10-01 17:46:21 -07002698
2699 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2700 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2701 if (!mTouchState.windows.isEmpty()) {
2702 dump.append(INDENT "TouchedWindows:\n");
2703 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2704 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2705 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2706 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2707 touchedWindow.targetFlags);
2708 }
2709 } else {
2710 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002711 }
2712
Jeff Brown2806e382010-10-01 17:46:21 -07002713 if (!mWindows.isEmpty()) {
2714 dump.append(INDENT "Windows:\n");
2715 for (size_t i = 0; i < mWindows.size(); i++) {
2716 const InputWindow& window = mWindows[i];
2717 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2718 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2719 "frame=[%d,%d][%d,%d], "
2720 "visibleFrame=[%d,%d][%d,%d], "
2721 "touchableArea=[%d,%d][%d,%d], "
2722 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2723 i, window.name.string(),
2724 toString(window.paused),
2725 toString(window.hasFocus),
2726 toString(window.hasWallpaper),
2727 toString(window.visible),
2728 toString(window.canReceiveKeys),
2729 window.layoutParamsFlags, window.layoutParamsType,
2730 window.layer,
2731 window.frameLeft, window.frameTop,
2732 window.frameRight, window.frameBottom,
2733 window.visibleFrameLeft, window.visibleFrameTop,
2734 window.visibleFrameRight, window.visibleFrameBottom,
2735 window.touchableAreaLeft, window.touchableAreaTop,
2736 window.touchableAreaRight, window.touchableAreaBottom,
2737 window.ownerPid, window.ownerUid,
2738 window.dispatchingTimeout / 1000000.0);
2739 }
2740 } else {
2741 dump.append(INDENT "Windows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002742 }
2743
Jeff Brown2806e382010-10-01 17:46:21 -07002744 if (!mMonitoringChannels.isEmpty()) {
2745 dump.append(INDENT "MonitoringChannels:\n");
2746 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2747 const sp<InputChannel>& channel = mMonitoringChannels[i];
2748 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2749 }
2750 } else {
2751 dump.append(INDENT "MonitoringChannels: <none>\n");
2752 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002753
Jeff Brown2806e382010-10-01 17:46:21 -07002754 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2755
2756 if (!mActiveConnections.isEmpty()) {
2757 dump.append(INDENT "ActiveConnections:\n");
2758 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2759 const Connection* connection = mActiveConnections[i];
2760 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
Jeff Brown90f0cee2010-10-08 22:31:17 -07002761 "inputState.isNeutral=%s\n",
Jeff Brown2806e382010-10-01 17:46:21 -07002762 i, connection->getInputChannelName(), connection->getStatusLabel(),
2763 connection->outboundQueue.count(),
Jeff Brown90f0cee2010-10-08 22:31:17 -07002764 toString(connection->inputState.isNeutral()));
Jeff Brown2806e382010-10-01 17:46:21 -07002765 }
2766 } else {
2767 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002768 }
2769
2770 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002771 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002772 (mAppSwitchDueTime - now()) / 1000000.0);
2773 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002774 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002775 }
2776}
2777
2778status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002779#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002780 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2781 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002782#endif
2783
Jeff Browne839a582010-04-22 18:58:52 -07002784 { // acquire lock
2785 AutoMutex _l(mLock);
2786
Jeff Brown53a415e2010-09-15 15:18:56 -07002787 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002788 LOGW("Attempted to register already registered input channel '%s'",
2789 inputChannel->getName().string());
2790 return BAD_VALUE;
2791 }
2792
2793 sp<Connection> connection = new Connection(inputChannel);
2794 status_t status = connection->initialize();
2795 if (status) {
2796 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2797 inputChannel->getName().string(), status);
2798 return status;
2799 }
2800
Jeff Brown0cacb872010-08-17 15:59:26 -07002801 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002802 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002803
Jeff Browna665ca82010-09-08 11:49:43 -07002804 if (monitor) {
2805 mMonitoringChannels.push(inputChannel);
2806 }
2807
Jeff Brown59abe7e2010-09-13 23:17:30 -07002808 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002809
Jeff Brown54bc2812010-06-15 01:31:58 -07002810 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002811 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002812 return OK;
2813}
2814
2815status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002816#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002817 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002818#endif
2819
Jeff Browne839a582010-04-22 18:58:52 -07002820 { // acquire lock
2821 AutoMutex _l(mLock);
2822
Jeff Brown53a415e2010-09-15 15:18:56 -07002823 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002824 if (connectionIndex < 0) {
2825 LOGW("Attempted to unregister already unregistered input channel '%s'",
2826 inputChannel->getName().string());
2827 return BAD_VALUE;
2828 }
2829
2830 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2831 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2832
2833 connection->status = Connection::STATUS_ZOMBIE;
2834
Jeff Browna665ca82010-09-08 11:49:43 -07002835 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2836 if (mMonitoringChannels[i] == inputChannel) {
2837 mMonitoringChannels.removeAt(i);
2838 break;
2839 }
2840 }
2841
Jeff Brown59abe7e2010-09-13 23:17:30 -07002842 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002843
Jeff Brown51d45a72010-06-17 20:52:56 -07002844 nsecs_t currentTime = now();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002845 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002846
2847 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002848 } // release lock
2849
Jeff Browne839a582010-04-22 18:58:52 -07002850 // Wake the poll loop because removing the connection may have changed the current
2851 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002852 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002853 return OK;
2854}
2855
Jeff Brown53a415e2010-09-15 15:18:56 -07002856ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002857 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2858 if (connectionIndex >= 0) {
2859 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2860 if (connection->inputChannel.get() == inputChannel.get()) {
2861 return connectionIndex;
2862 }
2863 }
2864
2865 return -1;
2866}
2867
Jeff Browne839a582010-04-22 18:58:52 -07002868void InputDispatcher::activateConnectionLocked(Connection* connection) {
2869 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2870 if (mActiveConnections.itemAt(i) == connection) {
2871 return;
2872 }
2873 }
2874 mActiveConnections.add(connection);
2875}
2876
2877void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2878 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2879 if (mActiveConnections.itemAt(i) == connection) {
2880 mActiveConnections.removeAt(i);
2881 return;
2882 }
2883 }
2884}
2885
Jeff Brown54bc2812010-06-15 01:31:58 -07002886void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002887 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002888}
2889
Jeff Brown54bc2812010-06-15 01:31:58 -07002890void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002891 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002892}
2893
Jeff Brown54bc2812010-06-15 01:31:58 -07002894void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002895 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002896 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2897 connection->getInputChannelName());
2898
Jeff Brown54bc2812010-06-15 01:31:58 -07002899 CommandEntry* commandEntry = postCommandLocked(
2900 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002901 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002902}
2903
Jeff Brown53a415e2010-09-15 15:18:56 -07002904void InputDispatcher::onANRLocked(
2905 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2906 nsecs_t eventTime, nsecs_t waitStartTime) {
2907 LOGI("Application is not responding: %s. "
2908 "%01.1fms since event, %01.1fms since wait started",
2909 getApplicationWindowLabelLocked(application, window).string(),
2910 (currentTime - eventTime) / 1000000.0,
2911 (currentTime - waitStartTime) / 1000000.0);
2912
2913 CommandEntry* commandEntry = postCommandLocked(
2914 & InputDispatcher::doNotifyANRLockedInterruptible);
2915 if (application) {
2916 commandEntry->inputApplicationHandle = application->handle;
2917 }
2918 if (window) {
2919 commandEntry->inputChannel = window->inputChannel;
2920 }
2921}
2922
Jeff Browna665ca82010-09-08 11:49:43 -07002923void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2924 CommandEntry* commandEntry) {
2925 mLock.unlock();
2926
2927 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2928
2929 mLock.lock();
2930}
2931
Jeff Brown54bc2812010-06-15 01:31:58 -07002932void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2933 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002934 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002935
Jeff Brown51d45a72010-06-17 20:52:56 -07002936 if (connection->status != Connection::STATUS_ZOMBIE) {
2937 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002938
Jeff Brown51d45a72010-06-17 20:52:56 -07002939 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2940
2941 mLock.lock();
2942 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002943}
2944
Jeff Brown53a415e2010-09-15 15:18:56 -07002945void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002946 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002947 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002948
Jeff Brown53a415e2010-09-15 15:18:56 -07002949 nsecs_t newTimeout = mPolicy->notifyANR(
2950 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002951
Jeff Brown53a415e2010-09-15 15:18:56 -07002952 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002953
Jeff Brown53a415e2010-09-15 15:18:56 -07002954 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002955}
2956
Jeff Browna665ca82010-09-08 11:49:43 -07002957void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2958 CommandEntry* commandEntry) {
2959 KeyEntry* entry = commandEntry->keyEntry;
2960 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2961 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2962 entry->downTime, entry->eventTime);
2963
2964 mLock.unlock();
2965
2966 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2967 & mReusableKeyEvent, entry->policyFlags);
2968
2969 mLock.lock();
2970
2971 entry->interceptKeyResult = consumed
2972 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2973 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2974 mAllocator.releaseKeyEntry(entry);
2975}
2976
2977void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2978 mLock.unlock();
2979
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002980 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07002981
2982 mLock.lock();
2983}
2984
Jeff Brown53a415e2010-09-15 15:18:56 -07002985void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
2986 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
2987 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07002988}
2989
2990void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002991 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002992 dumpDispatchStateLocked(dump);
2993}
2994
Jeff Brown54bc2812010-06-15 01:31:58 -07002995
Jeff Brown53a415e2010-09-15 15:18:56 -07002996// --- InputDispatcher::Queue ---
2997
2998template <typename T>
2999uint32_t InputDispatcher::Queue<T>::count() const {
3000 uint32_t result = 0;
3001 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3002 result += 1;
3003 }
3004 return result;
3005}
3006
3007
Jeff Browne839a582010-04-22 18:58:52 -07003008// --- InputDispatcher::Allocator ---
3009
3010InputDispatcher::Allocator::Allocator() {
3011}
3012
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003013InputDispatcher::InjectionState*
3014InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3015 InjectionState* injectionState = mInjectionStatePool.alloc();
3016 injectionState->refCount = 1;
3017 injectionState->injectorPid = injectorPid;
3018 injectionState->injectorUid = injectorUid;
3019 injectionState->injectionIsAsync = false;
3020 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3021 injectionState->pendingForegroundDispatches = 0;
3022 return injectionState;
3023}
3024
Jeff Brown51d45a72010-06-17 20:52:56 -07003025void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brown90f0cee2010-10-08 22:31:17 -07003026 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown51d45a72010-06-17 20:52:56 -07003027 entry->type = type;
3028 entry->refCount = 1;
3029 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07003030 entry->eventTime = eventTime;
Jeff Brown90f0cee2010-10-08 22:31:17 -07003031 entry->policyFlags = policyFlags;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003032 entry->injectionState = NULL;
3033}
3034
3035void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3036 if (entry->injectionState) {
3037 releaseInjectionState(entry->injectionState);
3038 entry->injectionState = NULL;
3039 }
Jeff Brown51d45a72010-06-17 20:52:56 -07003040}
3041
Jeff Browne839a582010-04-22 18:58:52 -07003042InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07003043InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003044 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003045 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Browne839a582010-04-22 18:58:52 -07003046 return entry;
3047}
3048
Jeff Brown51d45a72010-06-17 20:52:56 -07003049InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07003050 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07003051 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3052 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003053 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003054 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003055
3056 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003057 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003058 entry->action = action;
3059 entry->flags = flags;
3060 entry->keyCode = keyCode;
3061 entry->scanCode = scanCode;
3062 entry->metaState = metaState;
3063 entry->repeatCount = repeatCount;
3064 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07003065 entry->syntheticRepeat = false;
3066 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07003067 return entry;
3068}
3069
Jeff Brown51d45a72010-06-17 20:52:56 -07003070InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07003071 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07003072 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3073 nsecs_t downTime, uint32_t pointerCount,
3074 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003075 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003076 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003077
3078 entry->eventTime = eventTime;
3079 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003080 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003081 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07003082 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07003083 entry->metaState = metaState;
3084 entry->edgeFlags = edgeFlags;
3085 entry->xPrecision = xPrecision;
3086 entry->yPrecision = yPrecision;
3087 entry->downTime = downTime;
3088 entry->pointerCount = pointerCount;
3089 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07003090 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07003091 entry->lastSample = & entry->firstSample;
3092 for (uint32_t i = 0; i < pointerCount; i++) {
3093 entry->pointerIds[i] = pointerIds[i];
3094 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3095 }
Jeff Browne839a582010-04-22 18:58:52 -07003096 return entry;
3097}
3098
3099InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07003100 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07003101 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07003102 DispatchEntry* entry = mDispatchEntryPool.alloc();
3103 entry->eventEntry = eventEntry;
3104 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07003105 entry->targetFlags = targetFlags;
3106 entry->xOffset = xOffset;
3107 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07003108 entry->inProgress = false;
3109 entry->headMotionSample = NULL;
3110 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07003111 return entry;
3112}
3113
Jeff Brown54bc2812010-06-15 01:31:58 -07003114InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3115 CommandEntry* entry = mCommandEntryPool.alloc();
3116 entry->command = command;
3117 return entry;
3118}
3119
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003120void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3121 injectionState->refCount -= 1;
3122 if (injectionState->refCount == 0) {
3123 mInjectionStatePool.free(injectionState);
3124 } else {
3125 assert(injectionState->refCount > 0);
3126 }
3127}
3128
Jeff Browne839a582010-04-22 18:58:52 -07003129void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3130 switch (entry->type) {
3131 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3132 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3133 break;
3134 case EventEntry::TYPE_KEY:
3135 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3136 break;
3137 case EventEntry::TYPE_MOTION:
3138 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3139 break;
3140 default:
3141 assert(false);
3142 break;
3143 }
3144}
3145
3146void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3147 ConfigurationChangedEntry* entry) {
3148 entry->refCount -= 1;
3149 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003150 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003151 mConfigurationChangeEntryPool.free(entry);
3152 } else {
3153 assert(entry->refCount > 0);
3154 }
3155}
3156
3157void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3158 entry->refCount -= 1;
3159 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003160 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003161 mKeyEntryPool.free(entry);
3162 } else {
3163 assert(entry->refCount > 0);
3164 }
3165}
3166
3167void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3168 entry->refCount -= 1;
3169 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003170 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -07003171 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3172 MotionSample* next = sample->next;
3173 mMotionSamplePool.free(sample);
3174 sample = next;
3175 }
Jeff Browne839a582010-04-22 18:58:52 -07003176 mMotionEntryPool.free(entry);
3177 } else {
3178 assert(entry->refCount > 0);
3179 }
3180}
3181
3182void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3183 releaseEventEntry(entry->eventEntry);
3184 mDispatchEntryPool.free(entry);
3185}
3186
Jeff Brown54bc2812010-06-15 01:31:58 -07003187void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3188 mCommandEntryPool.free(entry);
3189}
3190
Jeff Browne839a582010-04-22 18:58:52 -07003191void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003192 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003193 MotionSample* sample = mMotionSamplePool.alloc();
3194 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003195 uint32_t pointerCount = motionEntry->pointerCount;
3196 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07003197 sample->pointerCoords[i] = pointerCoords[i];
3198 }
3199
3200 sample->next = NULL;
3201 motionEntry->lastSample->next = sample;
3202 motionEntry->lastSample = sample;
3203}
3204
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003205void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3206 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003207
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003208 keyEntry->dispatchInProgress = false;
3209 keyEntry->syntheticRepeat = false;
3210 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003211}
3212
3213
Jeff Brown542412c2010-08-18 15:51:08 -07003214// --- InputDispatcher::MotionEntry ---
3215
3216uint32_t InputDispatcher::MotionEntry::countSamples() const {
3217 uint32_t count = 1;
3218 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3219 count += 1;
3220 }
3221 return count;
3222}
3223
Jeff Browna665ca82010-09-08 11:49:43 -07003224
3225// --- InputDispatcher::InputState ---
3226
Jeff Brown90f0cee2010-10-08 22:31:17 -07003227InputDispatcher::InputState::InputState() {
Jeff Browna665ca82010-09-08 11:49:43 -07003228}
3229
3230InputDispatcher::InputState::~InputState() {
3231}
3232
3233bool InputDispatcher::InputState::isNeutral() const {
3234 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3235}
3236
Jeff Browna665ca82010-09-08 11:49:43 -07003237InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3238 const EventEntry* entry) {
3239 switch (entry->type) {
3240 case EventEntry::TYPE_KEY:
3241 return trackKey(static_cast<const KeyEntry*>(entry));
3242
3243 case EventEntry::TYPE_MOTION:
3244 return trackMotion(static_cast<const MotionEntry*>(entry));
3245
3246 default:
3247 return CONSISTENT;
3248 }
3249}
3250
3251InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3252 const KeyEntry* entry) {
3253 int32_t action = entry->action;
3254 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3255 KeyMemento& memento = mKeyMementos.editItemAt(i);
3256 if (memento.deviceId == entry->deviceId
3257 && memento.source == entry->source
3258 && memento.keyCode == entry->keyCode
3259 && memento.scanCode == entry->scanCode) {
3260 switch (action) {
3261 case AKEY_EVENT_ACTION_UP:
3262 mKeyMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003263 return CONSISTENT;
3264
3265 case AKEY_EVENT_ACTION_DOWN:
3266 return TOLERABLE;
3267
3268 default:
3269 return BROKEN;
3270 }
3271 }
3272 }
3273
3274 switch (action) {
3275 case AKEY_EVENT_ACTION_DOWN: {
3276 mKeyMementos.push();
3277 KeyMemento& memento = mKeyMementos.editTop();
3278 memento.deviceId = entry->deviceId;
3279 memento.source = entry->source;
3280 memento.keyCode = entry->keyCode;
3281 memento.scanCode = entry->scanCode;
3282 memento.downTime = entry->downTime;
3283 return CONSISTENT;
3284 }
3285
3286 default:
3287 return BROKEN;
3288 }
3289}
3290
3291InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3292 const MotionEntry* entry) {
3293 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3294 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3295 MotionMemento& memento = mMotionMementos.editItemAt(i);
3296 if (memento.deviceId == entry->deviceId
3297 && memento.source == entry->source) {
3298 switch (action) {
3299 case AMOTION_EVENT_ACTION_UP:
3300 case AMOTION_EVENT_ACTION_CANCEL:
3301 mMotionMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003302 return CONSISTENT;
3303
3304 case AMOTION_EVENT_ACTION_DOWN:
3305 return TOLERABLE;
3306
3307 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3308 if (entry->pointerCount == memento.pointerCount + 1) {
3309 memento.setPointers(entry);
3310 return CONSISTENT;
3311 }
3312 return BROKEN;
3313
3314 case AMOTION_EVENT_ACTION_POINTER_UP:
3315 if (entry->pointerCount == memento.pointerCount - 1) {
3316 memento.setPointers(entry);
3317 return CONSISTENT;
3318 }
3319 return BROKEN;
3320
3321 case AMOTION_EVENT_ACTION_MOVE:
3322 if (entry->pointerCount == memento.pointerCount) {
3323 return CONSISTENT;
3324 }
3325 return BROKEN;
3326
3327 default:
3328 return BROKEN;
3329 }
3330 }
3331 }
3332
3333 switch (action) {
3334 case AMOTION_EVENT_ACTION_DOWN: {
3335 mMotionMementos.push();
3336 MotionMemento& memento = mMotionMementos.editTop();
3337 memento.deviceId = entry->deviceId;
3338 memento.source = entry->source;
3339 memento.xPrecision = entry->xPrecision;
3340 memento.yPrecision = entry->yPrecision;
3341 memento.downTime = entry->downTime;
3342 memento.setPointers(entry);
3343 return CONSISTENT;
3344 }
3345
3346 default:
3347 return BROKEN;
3348 }
3349}
3350
3351void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3352 pointerCount = entry->pointerCount;
3353 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3354 pointerIds[i] = entry->pointerIds[i];
3355 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3356 }
3357}
3358
Jeff Brown90f0cee2010-10-08 22:31:17 -07003359void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3360 Allocator* allocator, Vector<EventEntry*>& outEvents,
3361 CancelationOptions options) {
3362 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003363 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003364 if (shouldCancelEvent(memento.source, options)) {
3365 outEvents.push(allocator->obtainKeyEntry(currentTime,
3366 memento.deviceId, memento.source, 0,
3367 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3368 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3369 mKeyMementos.removeAt(i);
3370 } else {
3371 i += 1;
3372 }
Jeff Browna665ca82010-09-08 11:49:43 -07003373 }
3374
Jeff Brown316237d2010-10-11 18:22:53 -07003375 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003376 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003377 if (shouldCancelEvent(memento.source, options)) {
3378 outEvents.push(allocator->obtainMotionEntry(currentTime,
3379 memento.deviceId, memento.source, 0,
3380 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3381 memento.xPrecision, memento.yPrecision, memento.downTime,
3382 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3383 mMotionMementos.removeAt(i);
3384 } else {
3385 i += 1;
3386 }
Jeff Browna665ca82010-09-08 11:49:43 -07003387 }
3388}
3389
3390void InputDispatcher::InputState::clear() {
3391 mKeyMementos.clear();
3392 mMotionMementos.clear();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003393}
3394
3395bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3396 CancelationOptions options) {
3397 switch (options) {
3398 case CANCEL_POINTER_EVENTS:
3399 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3400 case CANCEL_NON_POINTER_EVENTS:
3401 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3402 default:
3403 return true;
3404 }
Jeff Browna665ca82010-09-08 11:49:43 -07003405}
3406
3407
Jeff Browne839a582010-04-22 18:58:52 -07003408// --- InputDispatcher::Connection ---
3409
3410InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3411 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003412 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003413}
3414
3415InputDispatcher::Connection::~Connection() {
3416}
3417
3418status_t InputDispatcher::Connection::initialize() {
3419 return inputPublisher.initialize();
3420}
3421
Jeff Brown54bc2812010-06-15 01:31:58 -07003422const char* InputDispatcher::Connection::getStatusLabel() const {
3423 switch (status) {
3424 case STATUS_NORMAL:
3425 return "NORMAL";
3426
3427 case STATUS_BROKEN:
3428 return "BROKEN";
3429
Jeff Brown54bc2812010-06-15 01:31:58 -07003430 case STATUS_ZOMBIE:
3431 return "ZOMBIE";
3432
3433 default:
3434 return "UNKNOWN";
3435 }
3436}
3437
Jeff Browne839a582010-04-22 18:58:52 -07003438InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3439 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003440 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3441 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003442 if (dispatchEntry->eventEntry == eventEntry) {
3443 return dispatchEntry;
3444 }
3445 }
3446 return NULL;
3447}
3448
Jeff Browna665ca82010-09-08 11:49:43 -07003449
Jeff Brown54bc2812010-06-15 01:31:58 -07003450// --- InputDispatcher::CommandEntry ---
3451
Jeff Browna665ca82010-09-08 11:49:43 -07003452InputDispatcher::CommandEntry::CommandEntry() :
3453 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003454}
3455
3456InputDispatcher::CommandEntry::~CommandEntry() {
3457}
3458
Jeff Browne839a582010-04-22 18:58:52 -07003459
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003460// --- InputDispatcher::TouchState ---
3461
3462InputDispatcher::TouchState::TouchState() :
3463 down(false), split(false) {
3464}
3465
3466InputDispatcher::TouchState::~TouchState() {
3467}
3468
3469void InputDispatcher::TouchState::reset() {
3470 down = false;
3471 split = false;
3472 windows.clear();
3473}
3474
3475void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3476 down = other.down;
3477 split = other.split;
3478 windows.clear();
3479 windows.appendVector(other.windows);
3480}
3481
3482void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3483 int32_t targetFlags, BitSet32 pointerIds) {
3484 if (targetFlags & InputTarget::FLAG_SPLIT) {
3485 split = true;
3486 }
3487
3488 for (size_t i = 0; i < windows.size(); i++) {
3489 TouchedWindow& touchedWindow = windows.editItemAt(i);
3490 if (touchedWindow.window == window) {
3491 touchedWindow.targetFlags |= targetFlags;
3492 touchedWindow.pointerIds.value |= pointerIds.value;
3493 return;
3494 }
3495 }
3496
3497 windows.push();
3498
3499 TouchedWindow& touchedWindow = windows.editTop();
3500 touchedWindow.window = window;
3501 touchedWindow.targetFlags = targetFlags;
3502 touchedWindow.pointerIds = pointerIds;
3503 touchedWindow.channel = window->inputChannel;
3504}
3505
3506void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3507 for (size_t i = 0 ; i < windows.size(); ) {
3508 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3509 windows.removeAt(i);
3510 } else {
3511 i += 1;
3512 }
3513 }
3514}
3515
3516const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3517 for (size_t i = 0; i < windows.size(); i++) {
3518 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3519 return windows[i].window;
3520 }
3521 }
3522 return NULL;
3523}
3524
3525
Jeff Browne839a582010-04-22 18:58:52 -07003526// --- InputDispatcherThread ---
3527
3528InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3529 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3530}
3531
3532InputDispatcherThread::~InputDispatcherThread() {
3533}
3534
3535bool InputDispatcherThread::threadLoop() {
3536 mDispatcher->dispatchOnce();
3537 return true;
3538}
3539
3540} // namespace android