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