blob: 41b6ff318d47bbe77a9b0a8c1b44ad0dee3f4563 [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// Delay between reporting long touch events to the power manager.
55const nsecs_t EVENT_IGNORE_DURATION = 300 * 1000000LL; // 300 ms
56
57// Default input dispatching timeout if there is no focused application or paused window
58// from which to determine an appropriate dispatching timeout.
59const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
60
61// Amount of time to allow for all pending events to be processed when an app switch
62// key is on the way. This is used to preempt input dispatch and drop input events
63// when an application takes too long to respond and the user has pressed an app switch key.
64const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
65
Jeff Browne839a582010-04-22 18:58:52 -070066
Jeff Brown51d45a72010-06-17 20:52:56 -070067static inline nsecs_t now() {
68 return systemTime(SYSTEM_TIME_MONOTONIC);
69}
70
Jeff Browna665ca82010-09-08 11:49:43 -070071static inline const char* toString(bool value) {
72 return value ? "true" : "false";
73}
74
Jeff Brownd1b0a2b2010-09-26 22:20:12 -070075static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
76 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
77 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
78}
79
80static bool isValidKeyAction(int32_t action) {
81 switch (action) {
82 case AKEY_EVENT_ACTION_DOWN:
83 case AKEY_EVENT_ACTION_UP:
84 return true;
85 default:
86 return false;
87 }
88}
89
90static bool validateKeyEvent(int32_t action) {
91 if (! isValidKeyAction(action)) {
92 LOGE("Key event has invalid action code 0x%x", action);
93 return false;
94 }
95 return true;
96}
97
Jeff Brown90f0cee2010-10-08 22:31:17 -070098static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -070099 switch (action & AMOTION_EVENT_ACTION_MASK) {
100 case AMOTION_EVENT_ACTION_DOWN:
101 case AMOTION_EVENT_ACTION_UP:
102 case AMOTION_EVENT_ACTION_CANCEL:
103 case AMOTION_EVENT_ACTION_MOVE:
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700104 case AMOTION_EVENT_ACTION_OUTSIDE:
105 return true;
Jeff Brown90f0cee2010-10-08 22:31:17 -0700106 case AMOTION_EVENT_ACTION_POINTER_DOWN:
107 case AMOTION_EVENT_ACTION_POINTER_UP: {
108 int32_t index = getMotionEventActionPointerIndex(action);
109 return index >= 0 && size_t(index) < pointerCount;
110 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700111 default:
112 return false;
113 }
114}
115
116static bool validateMotionEvent(int32_t action, size_t pointerCount,
117 const int32_t* pointerIds) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700118 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700119 LOGE("Motion event has invalid action code 0x%x", action);
120 return false;
121 }
122 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
123 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
124 pointerCount, MAX_POINTERS);
125 return false;
126 }
127 for (size_t i = 0; i < pointerCount; i++) {
128 if (pointerIds[i] < 0 || pointerIds[i] > MAX_POINTER_ID) {
129 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
130 pointerIds[i], MAX_POINTER_ID);
131 return false;
132 }
133 }
134 return true;
135}
136
Jeff Browna665ca82010-09-08 11:49:43 -0700137
138// --- InputWindow ---
139
Jeff Browna665ca82010-09-08 11:49:43 -0700140bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
141 return x >= touchableAreaLeft && x <= touchableAreaRight
142 && y >= touchableAreaTop && y <= touchableAreaBottom;
143}
144
Jeff Brown35cf0e92010-10-05 12:26:23 -0700145bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
146 return x >= frameLeft && x <= frameRight
147 && y >= frameTop && y <= frameBottom;
148}
149
150bool InputWindow::isTrustedOverlay() const {
151 return layoutParamsType == TYPE_INPUT_METHOD
152 || layoutParamsType == TYPE_INPUT_METHOD_DIALOG;
153}
154
Jeff Browna665ca82010-09-08 11:49:43 -0700155
Jeff Browne839a582010-04-22 18:58:52 -0700156// --- InputDispatcher ---
157
Jeff Brown54bc2812010-06-15 01:31:58 -0700158InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Browna665ca82010-09-08 11:49:43 -0700159 mPolicy(policy),
160 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
161 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700162 mFocusedWindow(NULL),
Jeff Browna665ca82010-09-08 11:49:43 -0700163 mFocusedApplication(NULL),
164 mCurrentInputTargetsValid(false),
165 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown59abe7e2010-09-13 23:17:30 -0700166 mLooper = new Looper(false);
Jeff Browne839a582010-04-22 18:58:52 -0700167
Jeff Browna665ca82010-09-08 11:49:43 -0700168 mInboundQueue.headSentinel.refCount = -1;
169 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
170 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Browne839a582010-04-22 18:58:52 -0700171
Jeff Browna665ca82010-09-08 11:49:43 -0700172 mInboundQueue.tailSentinel.refCount = -1;
173 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
174 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Browne839a582010-04-22 18:58:52 -0700175
176 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown54bc2812010-06-15 01:31:58 -0700177
Jeff Brown542412c2010-08-18 15:51:08 -0700178 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
179 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
180 mThrottleState.lastDeviceId = -1;
181
182#if DEBUG_THROTTLING
183 mThrottleState.originalSampleCount = 0;
184 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
185#endif
Jeff Browne839a582010-04-22 18:58:52 -0700186}
187
188InputDispatcher::~InputDispatcher() {
Jeff Browna665ca82010-09-08 11:49:43 -0700189 { // acquire lock
190 AutoMutex _l(mLock);
191
192 resetKeyRepeatLocked();
Jeff Brownd8816c32010-09-16 14:07:33 -0700193 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700194 drainInboundQueueLocked();
195 }
Jeff Browne839a582010-04-22 18:58:52 -0700196
197 while (mConnectionsByReceiveFd.size() != 0) {
198 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
199 }
Jeff Browne839a582010-04-22 18:58:52 -0700200}
201
202void InputDispatcher::dispatchOnce() {
Jeff Brown54bc2812010-06-15 01:31:58 -0700203 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brown61ce3982010-09-07 10:44:57 -0700204 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Browne839a582010-04-22 18:58:52 -0700205
Jeff Browne839a582010-04-22 18:58:52 -0700206 nsecs_t nextWakeupTime = LONG_LONG_MAX;
207 { // acquire lock
208 AutoMutex _l(mLock);
Jeff Browna665ca82010-09-08 11:49:43 -0700209 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Browne839a582010-04-22 18:58:52 -0700210
Jeff Browna665ca82010-09-08 11:49:43 -0700211 if (runCommandsLockedInterruptible()) {
212 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Browne839a582010-04-22 18:58:52 -0700213 }
Jeff Browne839a582010-04-22 18:58:52 -0700214 } // release lock
215
Jeff Browna665ca82010-09-08 11:49:43 -0700216 // Wait for callback or timeout or wake. (make sure we round up, not down)
217 nsecs_t currentTime = now();
218 int32_t timeoutMillis;
219 if (nextWakeupTime > currentTime) {
220 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
221 timeout = (timeout + 999999LL) / 1000000LL;
222 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
223 } else {
224 timeoutMillis = 0;
225 }
226
Jeff Brown59abe7e2010-09-13 23:17:30 -0700227 mLooper->pollOnce(timeoutMillis);
Jeff Browna665ca82010-09-08 11:49:43 -0700228}
229
230void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
231 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
232 nsecs_t currentTime = now();
233
234 // Reset the key repeat timer whenever we disallow key events, even if the next event
235 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
236 // out of sleep.
237 if (keyRepeatTimeout < 0) {
238 resetKeyRepeatLocked();
239 }
240
Jeff Browna665ca82010-09-08 11:49:43 -0700241 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
242 if (mDispatchFrozen) {
243#if DEBUG_FOCUS
244 LOGD("Dispatch frozen. Waiting some more.");
245#endif
246 return;
247 }
248
249 // Optimize latency of app switches.
250 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
251 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
252 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
253 if (mAppSwitchDueTime < *nextWakeupTime) {
254 *nextWakeupTime = mAppSwitchDueTime;
255 }
256
Jeff Browna665ca82010-09-08 11:49:43 -0700257 // Ready to start a new event.
258 // If we don't already have a pending event, go grab one.
259 if (! mPendingEvent) {
260 if (mInboundQueue.isEmpty()) {
261 if (isAppSwitchDue) {
262 // The inbound queue is empty so the app switch key we were waiting
263 // for will never arrive. Stop waiting for it.
264 resetPendingAppSwitchLocked(false);
265 isAppSwitchDue = false;
266 }
267
268 // Synthesize a key repeat if appropriate.
269 if (mKeyRepeatState.lastKeyEntry) {
270 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
271 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
272 } else {
273 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
274 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
275 }
276 }
277 }
278 if (! mPendingEvent) {
279 return;
280 }
281 } else {
282 // Inbound queue has at least one entry.
283 EventEntry* entry = mInboundQueue.headSentinel.next;
284
285 // Throttle the entry if it is a move event and there are no
286 // other events behind it in the queue. Due to movement batching, additional
287 // samples may be appended to this event by the time the throttling timeout
288 // expires.
289 // TODO Make this smarter and consider throttling per device independently.
Jeff Brown90f0cee2010-10-08 22:31:17 -0700290 if (entry->type == EventEntry::TYPE_MOTION
291 && !isAppSwitchDue
292 && mDispatchEnabled
293 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
294 && !entry->isInjected()) {
Jeff Browna665ca82010-09-08 11:49:43 -0700295 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
296 int32_t deviceId = motionEntry->deviceId;
297 uint32_t source = motionEntry->source;
298 if (! isAppSwitchDue
299 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
300 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
301 && deviceId == mThrottleState.lastDeviceId
302 && source == mThrottleState.lastSource) {
303 nsecs_t nextTime = mThrottleState.lastEventTime
304 + mThrottleState.minTimeBetweenEvents;
305 if (currentTime < nextTime) {
306 // Throttle it!
307#if DEBUG_THROTTLING
308 LOGD("Throttling - Delaying motion event for "
309 "device 0x%x, source 0x%08x by up to %0.3fms.",
310 deviceId, source, (nextTime - currentTime) * 0.000001);
311#endif
312 if (nextTime < *nextWakeupTime) {
313 *nextWakeupTime = nextTime;
314 }
315 if (mThrottleState.originalSampleCount == 0) {
316 mThrottleState.originalSampleCount =
317 motionEntry->countSamples();
318 }
319 return;
320 }
321 }
322
323#if DEBUG_THROTTLING
324 if (mThrottleState.originalSampleCount != 0) {
325 uint32_t count = motionEntry->countSamples();
326 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
327 count - mThrottleState.originalSampleCount,
328 mThrottleState.originalSampleCount, count);
329 mThrottleState.originalSampleCount = 0;
330 }
331#endif
332
333 mThrottleState.lastEventTime = entry->eventTime < currentTime
334 ? entry->eventTime : currentTime;
335 mThrottleState.lastDeviceId = deviceId;
336 mThrottleState.lastSource = source;
337 }
338
339 mInboundQueue.dequeue(entry);
340 mPendingEvent = entry;
341 }
342 }
343
344 // Now we have an event to dispatch.
345 assert(mPendingEvent != NULL);
Jeff Brownd8816c32010-09-16 14:07:33 -0700346 bool done = false;
Jeff Brown90f0cee2010-10-08 22:31:17 -0700347 DropReason dropReason = DROP_REASON_NOT_DROPPED;
348 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
349 dropReason = DROP_REASON_POLICY;
350 } else if (!mDispatchEnabled) {
351 dropReason = DROP_REASON_DISABLED;
352 }
Jeff Browna665ca82010-09-08 11:49:43 -0700353 switch (mPendingEvent->type) {
354 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
355 ConfigurationChangedEntry* typedEntry =
356 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brownd8816c32010-09-16 14:07:33 -0700357 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700358 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Browna665ca82010-09-08 11:49:43 -0700359 break;
360 }
361
362 case EventEntry::TYPE_KEY: {
363 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700364 if (isAppSwitchDue) {
365 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700366 resetPendingAppSwitchLocked(true);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700367 isAppSwitchDue = false;
368 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
369 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700370 }
371 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700372 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700373 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700374 break;
375 }
376
377 case EventEntry::TYPE_MOTION: {
378 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700379 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
380 dropReason = DROP_REASON_APP_SWITCH;
Jeff Browna665ca82010-09-08 11:49:43 -0700381 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700382 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700383 &dropReason, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700384 break;
385 }
386
387 default:
388 assert(false);
Jeff Browna665ca82010-09-08 11:49:43 -0700389 break;
390 }
391
Jeff Brownd8816c32010-09-16 14:07:33 -0700392 if (done) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700393 if (dropReason != DROP_REASON_NOT_DROPPED) {
394 dropInboundEventLocked(mPendingEvent, dropReason);
395 }
396
Jeff Brownd8816c32010-09-16 14:07:33 -0700397 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700398 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
399 }
400}
401
402bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
403 bool needWake = mInboundQueue.isEmpty();
404 mInboundQueue.enqueueAtTail(entry);
405
406 switch (entry->type) {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700407 case EventEntry::TYPE_KEY: {
408 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
409 if (isAppSwitchKeyEventLocked(keyEntry)) {
410 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
411 mAppSwitchSawKeyDown = true;
412 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
413 if (mAppSwitchSawKeyDown) {
414#if DEBUG_APP_SWITCH
415 LOGD("App switch is pending!");
416#endif
417 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
418 mAppSwitchSawKeyDown = false;
419 needWake = true;
420 }
421 }
422 }
Jeff Browna665ca82010-09-08 11:49:43 -0700423 break;
424 }
Jeff Brown90f0cee2010-10-08 22:31:17 -0700425 }
Jeff Browna665ca82010-09-08 11:49:43 -0700426
427 return needWake;
428}
429
Jeff Brown90f0cee2010-10-08 22:31:17 -0700430void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
431 const char* reason;
432 switch (dropReason) {
433 case DROP_REASON_POLICY:
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700434#if DEBUG_INBOUND_EVENT_DETAILS
435 LOGD("Dropped event because policy requested that it not be delivered to the application.");
436#endif
Jeff Brown90f0cee2010-10-08 22:31:17 -0700437 reason = "inbound event was dropped because the policy requested that it not be "
438 "delivered to the application";
439 break;
440 case DROP_REASON_DISABLED:
441 LOGI("Dropped event because input dispatch is disabled.");
442 reason = "inbound event was dropped because input dispatch is disabled";
443 break;
444 case DROP_REASON_APP_SWITCH:
445 LOGI("Dropped event because of pending overdue app switch.");
446 reason = "inbound event was dropped because of pending overdue app switch";
447 break;
448 default:
449 assert(false);
450 return;
451 }
452
453 switch (entry->type) {
454 case EventEntry::TYPE_KEY:
455 synthesizeCancelationEventsForAllConnectionsLocked(
456 InputState::CANCEL_NON_POINTER_EVENTS, reason);
457 break;
458 case EventEntry::TYPE_MOTION: {
459 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
460 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
461 synthesizeCancelationEventsForAllConnectionsLocked(
462 InputState::CANCEL_POINTER_EVENTS, reason);
463 } else {
464 synthesizeCancelationEventsForAllConnectionsLocked(
465 InputState::CANCEL_NON_POINTER_EVENTS, reason);
466 }
467 break;
468 }
469 }
470}
471
472bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Browna665ca82010-09-08 11:49:43 -0700473 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
474}
475
Jeff Brown90f0cee2010-10-08 22:31:17 -0700476bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
477 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
478 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700479 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brown90f0cee2010-10-08 22:31:17 -0700480 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
481}
482
Jeff Browna665ca82010-09-08 11:49:43 -0700483bool InputDispatcher::isAppSwitchPendingLocked() {
484 return mAppSwitchDueTime != LONG_LONG_MAX;
485}
486
Jeff Browna665ca82010-09-08 11:49:43 -0700487void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
488 mAppSwitchDueTime = LONG_LONG_MAX;
489
490#if DEBUG_APP_SWITCH
491 if (handled) {
492 LOGD("App switch has arrived.");
493 } else {
494 LOGD("App switch was abandoned.");
495 }
496#endif
Jeff Browne839a582010-04-22 18:58:52 -0700497}
498
Jeff Brown54bc2812010-06-15 01:31:58 -0700499bool InputDispatcher::runCommandsLockedInterruptible() {
500 if (mCommandQueue.isEmpty()) {
501 return false;
502 }
Jeff Browne839a582010-04-22 18:58:52 -0700503
Jeff Brown54bc2812010-06-15 01:31:58 -0700504 do {
505 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
506
507 Command command = commandEntry->command;
508 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
509
Jeff Brown51d45a72010-06-17 20:52:56 -0700510 commandEntry->connection.clear();
Jeff Brown54bc2812010-06-15 01:31:58 -0700511 mAllocator.releaseCommandEntry(commandEntry);
512 } while (! mCommandQueue.isEmpty());
513 return true;
Jeff Browne839a582010-04-22 18:58:52 -0700514}
515
Jeff Brown54bc2812010-06-15 01:31:58 -0700516InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
517 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
518 mCommandQueue.enqueueAtTail(commandEntry);
519 return commandEntry;
520}
521
Jeff Browna665ca82010-09-08 11:49:43 -0700522void InputDispatcher::drainInboundQueueLocked() {
523 while (! mInboundQueue.isEmpty()) {
524 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brownd8816c32010-09-16 14:07:33 -0700525 releaseInboundEventLocked(entry);
Jeff Browne839a582010-04-22 18:58:52 -0700526 }
Jeff Browne839a582010-04-22 18:58:52 -0700527}
528
Jeff Brownd8816c32010-09-16 14:07:33 -0700529void InputDispatcher::releasePendingEventLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700530 if (mPendingEvent) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700531 releaseInboundEventLocked(mPendingEvent);
Jeff Browna665ca82010-09-08 11:49:43 -0700532 mPendingEvent = NULL;
533 }
534}
535
Jeff Brownd8816c32010-09-16 14:07:33 -0700536void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700537 InjectionState* injectionState = entry->injectionState;
538 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Browna665ca82010-09-08 11:49:43 -0700539#if DEBUG_DISPATCH_CYCLE
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700540 LOGD("Injected inbound event was dropped.");
Jeff Browna665ca82010-09-08 11:49:43 -0700541#endif
542 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
543 }
544 mAllocator.releaseEventEntry(entry);
545}
546
Jeff Browna665ca82010-09-08 11:49:43 -0700547void InputDispatcher::resetKeyRepeatLocked() {
548 if (mKeyRepeatState.lastKeyEntry) {
549 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
550 mKeyRepeatState.lastKeyEntry = NULL;
551 }
552}
553
554InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brown61ce3982010-09-07 10:44:57 -0700555 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown50de30a2010-06-22 01:27:15 -0700556 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
557
Jeff Brown50de30a2010-06-22 01:27:15 -0700558 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700559 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
560 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Browne839a582010-04-22 18:58:52 -0700561 if (entry->refCount == 1) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700562 mAllocator.recycleKeyEntry(entry);
Jeff Brown51d45a72010-06-17 20:52:56 -0700563 entry->eventTime = currentTime;
Jeff Brown51d45a72010-06-17 20:52:56 -0700564 entry->policyFlags = policyFlags;
Jeff Browne839a582010-04-22 18:58:52 -0700565 entry->repeatCount += 1;
566 } else {
Jeff Brown51d45a72010-06-17 20:52:56 -0700567 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700568 entry->deviceId, entry->source, policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700569 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brownf16c26d2010-07-02 15:37:36 -0700570 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Browne839a582010-04-22 18:58:52 -0700571
572 mKeyRepeatState.lastKeyEntry = newEntry;
573 mAllocator.releaseKeyEntry(entry);
574
575 entry = newEntry;
576 }
Jeff Browna665ca82010-09-08 11:49:43 -0700577 entry->syntheticRepeat = true;
578
579 // Increment reference count since we keep a reference to the event in
580 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
581 entry->refCount += 1;
Jeff Browne839a582010-04-22 18:58:52 -0700582
Jeff Brownf16c26d2010-07-02 15:37:36 -0700583 if (entry->repeatCount == 1) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700584 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brownf16c26d2010-07-02 15:37:36 -0700585 }
586
Jeff Brown61ce3982010-09-07 10:44:57 -0700587 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Browna665ca82010-09-08 11:49:43 -0700588 return entry;
Jeff Browne839a582010-04-22 18:58:52 -0700589}
590
Jeff Browna665ca82010-09-08 11:49:43 -0700591bool InputDispatcher::dispatchConfigurationChangedLocked(
592 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Browne839a582010-04-22 18:58:52 -0700593#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Browna665ca82010-09-08 11:49:43 -0700594 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
595#endif
596
597 // Reset key repeating in case a keyboard device was added or removed or something.
598 resetKeyRepeatLocked();
599
600 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
601 CommandEntry* commandEntry = postCommandLocked(
602 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
603 commandEntry->eventTime = entry->eventTime;
604 return true;
605}
606
607bool InputDispatcher::dispatchKeyLocked(
608 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700609 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700610 // Give the policy a chance to intercept the key.
611 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700612 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700613 CommandEntry* commandEntry = postCommandLocked(
614 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700615 if (mFocusedWindow) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700616 commandEntry->inputChannel = mFocusedWindow->inputChannel;
617 }
618 commandEntry->keyEntry = entry;
619 entry->refCount += 1;
620 return false; // wait for the command to run
621 } else {
622 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
623 }
624 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700625 if (*dropReason == DROP_REASON_NOT_DROPPED) {
626 *dropReason = DROP_REASON_POLICY;
627 }
Jeff Brownd8816c32010-09-16 14:07:33 -0700628 resetTargetsLocked();
629 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
630 return true;
631 }
632
633 // Clean up if dropping the event.
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700634 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700635 resetTargetsLocked();
636 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
637 return true;
638 }
639
Jeff Browna665ca82010-09-08 11:49:43 -0700640 // Preprocessing.
641 if (! entry->dispatchInProgress) {
642 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
643
644 if (entry->repeatCount == 0
645 && entry->action == AKEY_EVENT_ACTION_DOWN
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700646 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
647 && !entry->isInjected()) {
Jeff Browna665ca82010-09-08 11:49:43 -0700648 if (mKeyRepeatState.lastKeyEntry
649 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
650 // We have seen two identical key downs in a row which indicates that the device
651 // driver is automatically generating key repeats itself. We take note of the
652 // repeat here, but we disable our own next key repeat timer since it is clear that
653 // we will not need to synthesize key repeats ourselves.
654 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
655 resetKeyRepeatLocked();
656 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
657 } else {
658 // Not a repeat. Save key down state in case we do see a repeat later.
659 resetKeyRepeatLocked();
660 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
661 }
662 mKeyRepeatState.lastKeyEntry = entry;
663 entry->refCount += 1;
664 } else if (! entry->syntheticRepeat) {
665 resetKeyRepeatLocked();
666 }
667
668 entry->dispatchInProgress = true;
Jeff Brownd8816c32010-09-16 14:07:33 -0700669 resetTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700670 }
671
672 // Identify targets.
673 if (! mCurrentInputTargetsValid) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700674 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
675 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700676 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
677 return false;
678 }
679
680 setInjectionResultLocked(entry, injectionResult);
681 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
682 return true;
683 }
684
685 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700686 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700687 }
688
689 // Dispatch the key.
690 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
691
692 // Poke user activity.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700693 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
694 pokeUserActivityLocked(entry->eventTime, POWER_MANAGER_BUTTON_EVENT);
695 }
Jeff Browna665ca82010-09-08 11:49:43 -0700696 return true;
697}
698
699void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
700#if DEBUG_OUTBOUND_EVENT_DETAILS
701 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
702 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
703 "downTime=%lld",
704 prefix,
705 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
706 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
707 entry->downTime);
708#endif
709}
710
711bool InputDispatcher::dispatchMotionLocked(
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700712 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700713 // Clean up if dropping the event.
Jeff Brown1fe6dec2010-10-11 14:20:19 -0700714 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700715 resetTargetsLocked();
716 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
717 return true;
718 }
719
Jeff Browna665ca82010-09-08 11:49:43 -0700720 // Preprocessing.
721 if (! entry->dispatchInProgress) {
722 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
723
724 entry->dispatchInProgress = true;
Jeff Brownd8816c32010-09-16 14:07:33 -0700725 resetTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700726 }
727
728 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
729
730 // Identify targets.
731 if (! mCurrentInputTargetsValid) {
Jeff Browna665ca82010-09-08 11:49:43 -0700732 int32_t injectionResult;
733 if (isPointerEvent) {
734 // Pointer event. (eg. touchscreen)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700735 injectionResult = findTouchedWindowTargetsLocked(currentTime,
736 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700737 } else {
738 // Non touch event. (eg. trackball)
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700739 injectionResult = findFocusedWindowTargetsLocked(currentTime,
740 entry, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700741 }
742 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
743 return false;
744 }
745
746 setInjectionResultLocked(entry, injectionResult);
747 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
748 return true;
749 }
750
751 addMonitoringTargetsLocked();
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700752 commitTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700753 }
754
755 // Dispatch the motion.
756 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
757
758 // Poke user activity.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700759 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
760 int32_t eventType;
761 if (isPointerEvent) {
762 switch (entry->action) {
763 case AMOTION_EVENT_ACTION_DOWN:
Jeff Browna665ca82010-09-08 11:49:43 -0700764 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700765 break;
766 case AMOTION_EVENT_ACTION_UP:
767 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
768 break;
769 default:
770 if (entry->eventTime - entry->downTime >= EVENT_IGNORE_DURATION) {
771 eventType = POWER_MANAGER_TOUCH_EVENT;
772 } else {
773 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
774 }
775 break;
Jeff Browna665ca82010-09-08 11:49:43 -0700776 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700777 } else {
778 eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Browna665ca82010-09-08 11:49:43 -0700779 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700780 pokeUserActivityLocked(entry->eventTime, eventType);
Jeff Browna665ca82010-09-08 11:49:43 -0700781 }
Jeff Browna665ca82010-09-08 11:49:43 -0700782 return true;
783}
784
785
786void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
787#if DEBUG_OUTBOUND_EVENT_DETAILS
788 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700789 "action=0x%x, flags=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700790 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700791 prefix,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700792 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
793 entry->action, entry->flags,
Jeff Browne839a582010-04-22 18:58:52 -0700794 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
795 entry->downTime);
796
797 // Print the most recent sample that we have available, this may change due to batching.
798 size_t sampleCount = 1;
Jeff Browna665ca82010-09-08 11:49:43 -0700799 const MotionSample* sample = & entry->firstSample;
Jeff Browne839a582010-04-22 18:58:52 -0700800 for (; sample->next != NULL; sample = sample->next) {
801 sampleCount += 1;
802 }
803 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -0700804 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700805 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -0700806 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -0700807 i, entry->pointerIds[i],
Jeff Brown38a7fab2010-08-30 03:02:23 -0700808 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
809 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
810 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
811 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
812 sample->pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -0700813 }
814
815 // Keep in mind that due to batching, it is possible for the number of samples actually
816 // dispatched to change before the application finally consumed them.
Jeff Brown5c1ed842010-07-14 18:48:53 -0700817 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -0700818 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
819 }
820#endif
Jeff Browne839a582010-04-22 18:58:52 -0700821}
822
823void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
824 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
825#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700826 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700827 "resumeWithAppendedMotionSample=%s",
Jeff Browna665ca82010-09-08 11:49:43 -0700828 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -0700829#endif
830
Jeff Brown54bc2812010-06-15 01:31:58 -0700831 assert(eventEntry->dispatchInProgress); // should already have been set to true
832
Jeff Browne839a582010-04-22 18:58:52 -0700833 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
834 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
835
Jeff Brown53a415e2010-09-15 15:18:56 -0700836 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -0700837 if (connectionIndex >= 0) {
838 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown51d45a72010-06-17 20:52:56 -0700839 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -0700840 resumeWithAppendedMotionSample);
841 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -0700842#if DEBUG_FOCUS
843 LOGD("Dropping event delivery to target with channel '%s' because it "
844 "is no longer registered with the input dispatcher.",
Jeff Browne839a582010-04-22 18:58:52 -0700845 inputTarget.inputChannel->getName().string());
Jeff Brown90f0cee2010-10-08 22:31:17 -0700846#endif
Jeff Browne839a582010-04-22 18:58:52 -0700847 }
848 }
849}
850
Jeff Brownd8816c32010-09-16 14:07:33 -0700851void InputDispatcher::resetTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700852 mCurrentInputTargetsValid = false;
853 mCurrentInputTargets.clear();
Jeff Browna665ca82010-09-08 11:49:43 -0700854 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
855}
856
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700857void InputDispatcher::commitTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700858 mCurrentInputTargetsValid = true;
859}
860
861int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
862 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
863 nsecs_t* nextWakeupTime) {
864 if (application == NULL && window == NULL) {
865 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
866#if DEBUG_FOCUS
867 LOGD("Waiting for system to become ready for input.");
868#endif
869 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
870 mInputTargetWaitStartTime = currentTime;
871 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
872 mInputTargetWaitTimeoutExpired = false;
873 }
874 } else {
875 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
876#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700877 LOGD("Waiting for application to become ready for input: %s",
878 getApplicationWindowLabelLocked(application, window).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700879#endif
880 nsecs_t timeout = window ? window->dispatchingTimeout :
881 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
882
883 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
884 mInputTargetWaitStartTime = currentTime;
885 mInputTargetWaitTimeoutTime = currentTime + timeout;
886 mInputTargetWaitTimeoutExpired = false;
887 }
888 }
889
890 if (mInputTargetWaitTimeoutExpired) {
891 return INPUT_EVENT_INJECTION_TIMED_OUT;
892 }
893
894 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown53a415e2010-09-15 15:18:56 -0700895 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700896
897 // Force poll loop to wake up immediately on next iteration once we get the
898 // ANR response back from the policy.
899 *nextWakeupTime = LONG_LONG_MIN;
900 return INPUT_EVENT_INJECTION_PENDING;
901 } else {
902 // Force poll loop to wake up when timeout is due.
903 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
904 *nextWakeupTime = mInputTargetWaitTimeoutTime;
905 }
906 return INPUT_EVENT_INJECTION_PENDING;
907 }
908}
909
Jeff Brown53a415e2010-09-15 15:18:56 -0700910void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
911 const sp<InputChannel>& inputChannel) {
Jeff Browna665ca82010-09-08 11:49:43 -0700912 if (newTimeout > 0) {
913 // Extend the timeout.
914 mInputTargetWaitTimeoutTime = now() + newTimeout;
915 } else {
916 // Give up.
917 mInputTargetWaitTimeoutExpired = true;
Jeff Brown53a415e2010-09-15 15:18:56 -0700918
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700919 // Release the touch targets.
920 mTouchState.reset();
Jeff Brown405a1d32010-09-16 12:31:46 -0700921
Jeff Brown53a415e2010-09-15 15:18:56 -0700922 // Input state will not be realistic. Mark it out of sync.
Jeff Brown40ad4702010-09-16 11:02:16 -0700923 if (inputChannel.get()) {
924 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
925 if (connectionIndex >= 0) {
926 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown90f0cee2010-10-08 22:31:17 -0700927 synthesizeCancelationEventsForConnectionLocked(
928 connection, InputState::CANCEL_ALL_EVENTS,
929 "application not responding");
Jeff Brown40ad4702010-09-16 11:02:16 -0700930 }
Jeff Brown53a415e2010-09-15 15:18:56 -0700931 }
Jeff Browna665ca82010-09-08 11:49:43 -0700932 }
933}
934
Jeff Brown53a415e2010-09-15 15:18:56 -0700935nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Browna665ca82010-09-08 11:49:43 -0700936 nsecs_t currentTime) {
937 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
938 return currentTime - mInputTargetWaitStartTime;
939 }
940 return 0;
941}
942
943void InputDispatcher::resetANRTimeoutsLocked() {
944#if DEBUG_FOCUS
945 LOGD("Resetting ANR timeouts.");
946#endif
947
Jeff Browna665ca82010-09-08 11:49:43 -0700948 // Reset input target wait timeout.
949 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
950}
951
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700952int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
953 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -0700954 mCurrentInputTargets.clear();
955
956 int32_t injectionResult;
957
958 // If there is no currently focused window and no focused application
959 // then drop the event.
960 if (! mFocusedWindow) {
961 if (mFocusedApplication) {
962#if DEBUG_FOCUS
963 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -0700964 "focused application that may eventually add a window: %s.",
965 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700966#endif
967 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
968 mFocusedApplication, NULL, nextWakeupTime);
969 goto Unresponsive;
970 }
971
972 LOGI("Dropping event because there is no focused window or focused application.");
973 injectionResult = INPUT_EVENT_INJECTION_FAILED;
974 goto Failed;
975 }
976
977 // Check permissions.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -0700978 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -0700979 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
980 goto Failed;
981 }
982
983 // If the currently focused window is paused then keep waiting.
984 if (mFocusedWindow->paused) {
985#if DEBUG_FOCUS
986 LOGD("Waiting because focused window is paused.");
987#endif
988 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
989 mFocusedApplication, mFocusedWindow, nextWakeupTime);
990 goto Unresponsive;
991 }
992
Jeff Brown53a415e2010-09-15 15:18:56 -0700993 // If the currently focused window is still working on previous events then keep waiting.
994 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
995#if DEBUG_FOCUS
996 LOGD("Waiting because focused window still processing previous input.");
997#endif
998 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
999 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1000 goto Unresponsive;
1001 }
1002
Jeff Browna665ca82010-09-08 11:49:43 -07001003 // Success! Output targets.
1004 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001005 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -07001006
1007 // Done.
1008Failed:
1009Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -07001010 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1011 updateDispatchStatisticsLocked(currentTime, entry,
1012 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001013#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -07001014 LOGD("findFocusedWindow finished: injectionResult=%d, "
1015 "timeSpendWaitingForApplication=%0.1fms",
1016 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001017#endif
1018 return injectionResult;
1019}
1020
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001021int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1022 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Browna665ca82010-09-08 11:49:43 -07001023 enum InjectionPermission {
1024 INJECTION_PERMISSION_UNKNOWN,
1025 INJECTION_PERMISSION_GRANTED,
1026 INJECTION_PERMISSION_DENIED
1027 };
1028
Jeff Browna665ca82010-09-08 11:49:43 -07001029 mCurrentInputTargets.clear();
1030
1031 nsecs_t startTime = now();
1032
1033 // For security reasons, we defer updating the touch state until we are sure that
1034 // event injection will be allowed.
1035 //
1036 // FIXME In the original code, screenWasOff could never be set to true.
1037 // The reason is that the POLICY_FLAG_WOKE_HERE
1038 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1039 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1040 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1041 // events upon which no preprocessing took place. So policyFlags was always 0.
1042 // In the new native input dispatcher we're a bit more careful about event
1043 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1044 // Unfortunately we obtain undesirable behavior.
1045 //
1046 // Here's what happens:
1047 //
1048 // When the device dims in anticipation of going to sleep, touches
1049 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1050 // the device to brighten and reset the user activity timer.
1051 // Touches on other windows (such as the launcher window)
1052 // are dropped. Then after a moment, the device goes to sleep. Oops.
1053 //
1054 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1055 // instead of POLICY_FLAG_WOKE_HERE...
1056 //
1057 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1058
1059 int32_t action = entry->action;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001060 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Browna665ca82010-09-08 11:49:43 -07001061
1062 // Update the touch state as needed based on the properties of the touch event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001063 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1064 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1065 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1066 mTempTouchState.reset();
1067 mTempTouchState.down = true;
1068 } else {
1069 mTempTouchState.copyFrom(mTouchState);
1070 }
Jeff Browna665ca82010-09-08 11:49:43 -07001071
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001072 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1073 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1074 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1075 /* Case 1: New splittable pointer going down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001076
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001077 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1078 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1079 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1080 const InputWindow* newTouchedWindow = NULL;
1081 const InputWindow* topErrorWindow = NULL;
Jeff Browna665ca82010-09-08 11:49:43 -07001082
1083 // Traverse windows from front to back to find touched window and outside targets.
1084 size_t numWindows = mWindows.size();
1085 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001086 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07001087 int32_t flags = window->layoutParamsFlags;
1088
1089 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1090 if (! topErrorWindow) {
1091 topErrorWindow = window;
1092 }
1093 }
1094
1095 if (window->visible) {
1096 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1097 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1098 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1099 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1100 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1101 newTouchedWindow = window;
Jeff Browna665ca82010-09-08 11:49:43 -07001102 }
1103 break; // found touched window, exit window loop
1104 }
1105 }
1106
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001107 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1108 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001109 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1110 if (isWindowObscuredAtPointLocked(window, x, y)) {
1111 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1112 }
1113
1114 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Browna665ca82010-09-08 11:49:43 -07001115 }
1116 }
1117 }
1118
1119 // If there is an error window but it is not taking focus (typically because
1120 // it is invisible) then wait for it. Any other focused window may in
1121 // fact be in ANR state.
1122 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1123#if DEBUG_FOCUS
1124 LOGD("Waiting because system error window is pending.");
1125#endif
1126 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1127 NULL, NULL, nextWakeupTime);
1128 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1129 goto Unresponsive;
1130 }
1131
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001132 // Figure out whether splitting will be allowed for this window.
Jeff Brown1c322582010-09-28 13:24:41 -07001133 if (newTouchedWindow
1134 && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001135 // New window supports splitting.
1136 isSplit = true;
1137 } else if (isSplit) {
1138 // New window does not support splitting but we have already split events.
1139 // Assign the pointer to the first foreground window we find.
1140 // (May be NULL which is why we put this code block before the next check.)
1141 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1142 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001143
Jeff Browna665ca82010-09-08 11:49:43 -07001144 // If we did not find a touched window then fail.
1145 if (! newTouchedWindow) {
1146 if (mFocusedApplication) {
1147#if DEBUG_FOCUS
1148 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -07001149 "focused application that may eventually add a new window: %s.",
1150 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -07001151#endif
1152 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1153 mFocusedApplication, NULL, nextWakeupTime);
Jeff Browna665ca82010-09-08 11:49:43 -07001154 goto Unresponsive;
1155 }
1156
1157 LOGI("Dropping event because there is no touched window or focused application.");
1158 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001159 goto Failed;
1160 }
1161
Jeff Brown35cf0e92010-10-05 12:26:23 -07001162 // Set target flags.
1163 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1164 if (isSplit) {
1165 targetFlags |= InputTarget::FLAG_SPLIT;
1166 }
1167 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1168 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1169 }
1170
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001171 // Update the temporary touch state.
1172 BitSet32 pointerIds;
1173 if (isSplit) {
1174 uint32_t pointerId = entry->pointerIds[pointerIndex];
1175 pointerIds.markBit(pointerId);
Jeff Browna665ca82010-09-08 11:49:43 -07001176 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001177 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001178 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001179 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Browna665ca82010-09-08 11:49:43 -07001180
1181 // If the pointer is not currently down, then ignore the event.
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001182 if (! mTempTouchState.down) {
Jeff Browna665ca82010-09-08 11:49:43 -07001183 LOGI("Dropping event because the pointer is not down.");
1184 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001185 goto Failed;
1186 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001187 }
Jeff Browna665ca82010-09-08 11:49:43 -07001188
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001189 // Check permission to inject into all touched foreground windows and ensure there
1190 // is at least one touched foreground window.
1191 {
1192 bool haveForegroundWindow = false;
1193 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1194 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1195 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1196 haveForegroundWindow = true;
1197 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1198 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1199 injectionPermission = INJECTION_PERMISSION_DENIED;
1200 goto Failed;
1201 }
1202 }
1203 }
1204 if (! haveForegroundWindow) {
Jeff Browna665ca82010-09-08 11:49:43 -07001205#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001206 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Browna665ca82010-09-08 11:49:43 -07001207#endif
1208 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Browna665ca82010-09-08 11:49:43 -07001209 goto Failed;
1210 }
1211
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001212 // Permission granted to injection into all touched foreground windows.
1213 injectionPermission = INJECTION_PERMISSION_GRANTED;
1214 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001215
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001216 // Ensure all touched foreground windows are ready for new input.
1217 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1218 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1219 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1220 // If the touched window is paused then keep waiting.
1221 if (touchedWindow.window->paused) {
1222#if DEBUG_INPUT_DISPATCHER_POLICY
1223 LOGD("Waiting because touched window is paused.");
Jeff Brown53a415e2010-09-15 15:18:56 -07001224#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001225 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1226 NULL, touchedWindow.window, nextWakeupTime);
1227 goto Unresponsive;
1228 }
1229
1230 // If the touched window is still working on previous events then keep waiting.
1231 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1232#if DEBUG_FOCUS
1233 LOGD("Waiting because touched window still processing previous input.");
1234#endif
1235 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1236 NULL, touchedWindow.window, nextWakeupTime);
1237 goto Unresponsive;
1238 }
1239 }
1240 }
1241
1242 // If this is the first pointer going down and the touched window has a wallpaper
1243 // then also add the touched wallpaper windows so they are locked in for the duration
1244 // of the touch gesture.
1245 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1246 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1247 if (foregroundWindow->hasWallpaper) {
1248 for (size_t i = 0; i < mWindows.size(); i++) {
1249 const InputWindow* window = & mWindows[i];
1250 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown35cf0e92010-10-05 12:26:23 -07001251 mTempTouchState.addOrUpdateWindow(window,
1252 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001253 }
1254 }
1255 }
1256 }
1257
Jeff Browna665ca82010-09-08 11:49:43 -07001258 // Success! Output targets.
1259 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Browna665ca82010-09-08 11:49:43 -07001260
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001261 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1262 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1263 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1264 touchedWindow.pointerIds);
Jeff Browna665ca82010-09-08 11:49:43 -07001265 }
1266
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001267 // Drop the outside touch window since we will not care about them in the next iteration.
1268 mTempTouchState.removeOutsideTouchWindows();
1269
Jeff Browna665ca82010-09-08 11:49:43 -07001270Failed:
1271 // Check injection permission once and for all.
1272 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001273 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001274 injectionPermission = INJECTION_PERMISSION_GRANTED;
1275 } else {
1276 injectionPermission = INJECTION_PERMISSION_DENIED;
1277 }
1278 }
1279
1280 // Update final pieces of touch state if the injector had permission.
1281 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001282 if (maskedAction == AMOTION_EVENT_ACTION_UP
1283 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1284 // All pointers up or canceled.
1285 mTempTouchState.reset();
1286 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1287 // First pointer went down.
1288 if (mTouchState.down) {
Jeff Brown90f0cee2010-10-08 22:31:17 -07001289#if DEBUG_FOCUS
1290 LOGD("Pointer down received while already down.");
1291#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001292 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001293 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1294 // One pointer went up.
1295 if (isSplit) {
1296 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1297 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Browna665ca82010-09-08 11:49:43 -07001298
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001299 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1300 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1301 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1302 touchedWindow.pointerIds.clearBit(pointerId);
1303 if (touchedWindow.pointerIds.isEmpty()) {
1304 mTempTouchState.windows.removeAt(i);
1305 continue;
1306 }
1307 }
1308 i += 1;
1309 }
Jeff Browna665ca82010-09-08 11:49:43 -07001310 }
Jeff Browna665ca82010-09-08 11:49:43 -07001311 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001312
1313 // Save changes to touch state.
1314 mTouchState.copyFrom(mTempTouchState);
Jeff Browna665ca82010-09-08 11:49:43 -07001315 } else {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001316#if DEBUG_FOCUS
1317 LOGD("Not updating touch focus because injection was denied.");
1318#endif
Jeff Browna665ca82010-09-08 11:49:43 -07001319 }
1320
1321Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -07001322 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1323 updateDispatchStatisticsLocked(currentTime, entry,
1324 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001325#if DEBUG_FOCUS
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001326 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1327 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown53a415e2010-09-15 15:18:56 -07001328 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001329#endif
1330 return injectionResult;
1331}
1332
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001333void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1334 BitSet32 pointerIds) {
Jeff Browna665ca82010-09-08 11:49:43 -07001335 mCurrentInputTargets.push();
1336
1337 InputTarget& target = mCurrentInputTargets.editTop();
1338 target.inputChannel = window->inputChannel;
1339 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001340 target.xOffset = - window->frameLeft;
1341 target.yOffset = - window->frameTop;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001342 target.windowType = window->layoutParamsType;
1343 target.pointerIds = pointerIds;
Jeff Browna665ca82010-09-08 11:49:43 -07001344}
1345
1346void InputDispatcher::addMonitoringTargetsLocked() {
1347 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1348 mCurrentInputTargets.push();
1349
1350 InputTarget& target = mCurrentInputTargets.editTop();
1351 target.inputChannel = mMonitoringChannels[i];
1352 target.flags = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07001353 target.xOffset = 0;
1354 target.yOffset = 0;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001355 target.windowType = InputWindow::TYPE_SYSTEM_OVERLAY;
Jeff Browna665ca82010-09-08 11:49:43 -07001356 }
1357}
1358
1359bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001360 const InjectionState* injectionState) {
1361 if (injectionState
Jeff Brown90f0cee2010-10-08 22:31:17 -07001362 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1363 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1364 if (window) {
1365 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1366 "with input channel %s owned by uid %d",
1367 injectionState->injectorPid, injectionState->injectorUid,
1368 window->inputChannel->getName().string(),
1369 window->ownerUid);
1370 } else {
1371 LOGW("Permission denied: injecting event from pid %d uid %d",
1372 injectionState->injectorPid, injectionState->injectorUid);
Jeff Browna665ca82010-09-08 11:49:43 -07001373 }
Jeff Brown90f0cee2010-10-08 22:31:17 -07001374 return false;
Jeff Browna665ca82010-09-08 11:49:43 -07001375 }
1376 return true;
1377}
1378
Jeff Brown35cf0e92010-10-05 12:26:23 -07001379bool InputDispatcher::isWindowObscuredAtPointLocked(
1380 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Browna665ca82010-09-08 11:49:43 -07001381 size_t numWindows = mWindows.size();
1382 for (size_t i = 0; i < numWindows; i++) {
1383 const InputWindow* other = & mWindows.itemAt(i);
1384 if (other == window) {
1385 break;
1386 }
Jeff Brown35cf0e92010-10-05 12:26:23 -07001387 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Browna665ca82010-09-08 11:49:43 -07001388 return true;
1389 }
1390 }
1391 return false;
1392}
1393
Jeff Brown53a415e2010-09-15 15:18:56 -07001394bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1395 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1396 if (connectionIndex >= 0) {
1397 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1398 return connection->outboundQueue.isEmpty();
1399 } else {
1400 return true;
1401 }
1402}
1403
1404String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1405 const InputWindow* window) {
1406 if (application) {
1407 if (window) {
1408 String8 label(application->name);
1409 label.append(" - ");
1410 label.append(window->name);
1411 return label;
1412 } else {
1413 return application->name;
1414 }
1415 } else if (window) {
1416 return window->name;
1417 } else {
1418 return String8("<unknown application or window>");
1419 }
1420}
1421
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07001422bool InputDispatcher::shouldPokeUserActivityForCurrentInputTargetsLocked() {
1423 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
1424 if (mCurrentInputTargets[i].windowType == InputWindow::TYPE_KEYGUARD) {
1425 return false;
1426 }
1427 }
1428 return true;
1429}
1430
1431void InputDispatcher::pokeUserActivityLocked(nsecs_t eventTime, int32_t eventType) {
Jeff Browna665ca82010-09-08 11:49:43 -07001432 CommandEntry* commandEntry = postCommandLocked(
1433 & InputDispatcher::doPokeUserActivityLockedInterruptible);
1434 commandEntry->eventTime = 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,
1759 const sp<Connection>& connection) {
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 Browne839a582010-04-22 18:58:52 -07001762 "%01.1fms since dispatch",
1763 connection->getInputChannelName(),
1764 connection->getEventLatencyMillis(currentTime),
1765 connection->getDispatchLatencyMillis(currentTime));
1766#endif
1767
Jeff Brown54bc2812010-06-15 01:31:58 -07001768 if (connection->status == Connection::STATUS_BROKEN
1769 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001770 return;
1771 }
1772
Jeff Brown53a415e2010-09-15 15:18:56 -07001773 // Notify other system components.
1774 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001775
1776 // Reset the publisher since the event has been consumed.
1777 // We do this now so that the publisher can release some of its internal resources
1778 // while waiting for the next dispatch cycle to begin.
1779 status_t status = connection->inputPublisher.reset();
1780 if (status) {
1781 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1782 connection->getInputChannelName(), status);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001783 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001784 return;
1785 }
1786
Jeff Browna665ca82010-09-08 11:49:43 -07001787 startNextDispatchCycleLocked(currentTime, connection);
1788}
1789
1790void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1791 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001792 // Start the next dispatch cycle for this connection.
1793 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001794 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001795 if (dispatchEntry->inProgress) {
1796 // Finish or resume current event in progress.
1797 if (dispatchEntry->tailMotionSample) {
1798 // We have a tail of undispatched motion samples.
1799 // Reuse the same DispatchEntry and start a new cycle.
1800 dispatchEntry->inProgress = false;
1801 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1802 dispatchEntry->tailMotionSample = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07001803 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001804 return;
1805 }
1806 // Finished.
1807 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001808 if (dispatchEntry->hasForegroundTarget()) {
1809 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001810 }
Jeff Browne839a582010-04-22 18:58:52 -07001811 mAllocator.releaseDispatchEntry(dispatchEntry);
1812 } else {
1813 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown53a415e2010-09-15 15:18:56 -07001814 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001815 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001816 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001817 return;
1818 }
1819 }
1820
1821 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001822 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001823}
1824
Jeff Brown90f0cee2010-10-08 22:31:17 -07001825void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1826 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001827#if DEBUG_DISPATCH_CYCLE
Jeff Brown90f0cee2010-10-08 22:31:17 -07001828 LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001829 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001830#endif
1831
Jeff Browna665ca82010-09-08 11:49:43 -07001832 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001833 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001834
Jeff Brown90f0cee2010-10-08 22:31:17 -07001835 // The connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001836 // Ignore already broken or zombie connections.
Jeff Brown90f0cee2010-10-08 22:31:17 -07001837 if (connection->status == Connection::STATUS_NORMAL) {
1838 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001839
Jeff Brown90f0cee2010-10-08 22:31:17 -07001840 // Notify other system components.
1841 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001842 }
Jeff Browne839a582010-04-22 18:58:52 -07001843}
1844
Jeff Brown53a415e2010-09-15 15:18:56 -07001845void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1846 while (! connection->outboundQueue.isEmpty()) {
1847 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1848 if (dispatchEntry->hasForegroundTarget()) {
1849 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001850 }
1851 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001852 }
1853
Jeff Brown53a415e2010-09-15 15:18:56 -07001854 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001855}
1856
Jeff Brown59abe7e2010-09-13 23:17:30 -07001857int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-04-22 18:58:52 -07001858 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1859
1860 { // acquire lock
1861 AutoMutex _l(d->mLock);
1862
1863 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1864 if (connectionIndex < 0) {
1865 LOGE("Received spurious receive callback for unknown input channel. "
1866 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001867 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001868 }
1869
Jeff Brown51d45a72010-06-17 20:52:56 -07001870 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001871
1872 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001873 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-04-22 18:58:52 -07001874 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1875 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown90f0cee2010-10-08 22:31:17 -07001876 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001877 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001878 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001879 }
1880
Jeff Brown59abe7e2010-09-13 23:17:30 -07001881 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001882 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1883 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001884 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001885 }
1886
1887 status_t status = connection->inputPublisher.receiveFinishedSignal();
1888 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 Brown51d45a72010-06-17 20:52:56 -07001896 d->finishDispatchCycleLocked(currentTime, connection);
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 Brown5c1ed842010-07-14 18:48:53 -07002075 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, 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 Brown1fe6dec2010-10-11 14:20:19 -07002084 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002085 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2086 keyCode, scanCode, /*byref*/ policyFlags);
2087
Jeff Browna665ca82010-09-08 11:49:43 -07002088 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002089 { // acquire lock
2090 AutoMutex _l(mLock);
2091
Jeff Brown51d45a72010-06-17 20:52:56 -07002092 int32_t repeatCount = 0;
2093 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002094 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07002095 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07002096
Jeff Browna665ca82010-09-08 11:49:43 -07002097 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002098 } // release lock
2099
Jeff Browna665ca82010-09-08 11:49:43 -07002100 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002101 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002102 }
2103}
2104
Jeff Brown5c1ed842010-07-14 18:48:53 -07002105void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002106 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002107 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2108 float xPrecision, float yPrecision, nsecs_t downTime) {
2109#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07002110 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002111 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2112 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2113 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07002114 xPrecision, yPrecision, downTime);
2115 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07002116 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07002117 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07002118 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07002119 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-08-30 03:02:23 -07002120 pointerCoords[i].pressure, pointerCoords[i].size,
2121 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2122 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2123 pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -07002124 }
2125#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002126 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2127 return;
2128 }
Jeff Browne839a582010-04-22 18:58:52 -07002129
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002130 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002131 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2132
Jeff Browna665ca82010-09-08 11:49:43 -07002133 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07002134 { // acquire lock
2135 AutoMutex _l(mLock);
2136
2137 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07002138 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07002139 // BATCHING CASE
2140 //
2141 // Try to append a move sample to the tail of the inbound queue for this device.
2142 // Give up if we encounter a non-move motion event for this device since that
2143 // means we cannot append any new samples until a new motion event has started.
Jeff Browna665ca82010-09-08 11:49:43 -07002144 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2145 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07002146 if (entry->type != EventEntry::TYPE_MOTION) {
2147 // Keep looking for motion events.
2148 continue;
2149 }
2150
2151 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2152 if (motionEntry->deviceId != deviceId) {
2153 // Keep looking for this device.
2154 continue;
2155 }
2156
Jeff Brown5c1ed842010-07-14 18:48:53 -07002157 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07002158 || motionEntry->pointerCount != pointerCount
2159 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07002160 // Last motion event in the queue for this device is not compatible for
2161 // appending new samples. Stop here.
2162 goto NoBatchingOrStreaming;
2163 }
2164
2165 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07002166 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07002167 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002168#if DEBUG_BATCHING
2169 LOGD("Appended motion sample onto batch for most recent "
2170 "motion event for this device in the inbound queue.");
2171#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07002172 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002173 }
2174
2175 // STREAMING CASE
2176 //
2177 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07002178 // Search the outbound queue for the current foreground targets to find a dispatched
2179 // motion event that is still in progress. If found, then, appen the new sample to
2180 // that event and push it out to all current targets. The logic in
2181 // prepareDispatchCycleLocked takes care of the case where some targets may
2182 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown54bc2812010-06-15 01:31:58 -07002183 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002184 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2185 const InputTarget& inputTarget = mCurrentInputTargets[i];
2186 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2187 // Skip non-foreground targets. We only want to stream if there is at
2188 // least one foreground target whose dispatch is still in progress.
2189 continue;
Jeff Browne839a582010-04-22 18:58:52 -07002190 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002191
2192 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2193 if (connectionIndex < 0) {
2194 // Connection must no longer be valid.
2195 continue;
2196 }
2197
2198 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2199 if (connection->outboundQueue.isEmpty()) {
2200 // This foreground target has an empty outbound queue.
2201 continue;
2202 }
2203
2204 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2205 if (! dispatchEntry->inProgress
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002206 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2207 || dispatchEntry->isSplit()) {
2208 // No motion event is being dispatched, or it is being split across
2209 // windows in which case we cannot stream.
Jeff Brown53a415e2010-09-15 15:18:56 -07002210 continue;
2211 }
2212
2213 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2214 dispatchEntry->eventEntry);
2215 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2216 || motionEntry->deviceId != deviceId
2217 || motionEntry->pointerCount != pointerCount
2218 || motionEntry->isInjected()) {
2219 // The motion event is not compatible with this move.
2220 continue;
2221 }
2222
2223 // Hurray! This foreground target is currently dispatching a move event
2224 // that we can stream onto. Append the motion sample and resume dispatch.
2225 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2226#if DEBUG_BATCHING
2227 LOGD("Appended motion sample onto batch for most recently dispatched "
2228 "motion event for this device in the outbound queues. "
2229 "Attempting to stream the motion sample.");
2230#endif
2231 nsecs_t currentTime = now();
2232 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2233 true /*resumeWithAppendedMotionSample*/);
2234
2235 runCommandsLockedInterruptible();
2236 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07002237 }
2238 }
2239
2240NoBatchingOrStreaming:;
2241 }
2242
2243 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07002244 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002245 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002246 xPrecision, yPrecision, downTime,
2247 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07002248
Jeff Browna665ca82010-09-08 11:49:43 -07002249 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07002250 } // release lock
2251
Jeff Browna665ca82010-09-08 11:49:43 -07002252 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002253 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002254 }
2255}
2256
Jeff Brown90f0cee2010-10-08 22:31:17 -07002257void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2258 uint32_t policyFlags) {
2259#if DEBUG_INBOUND_EVENT_DETAILS
2260 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2261 switchCode, switchValue, policyFlags);
2262#endif
2263
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002264 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002265 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2266}
2267
Jeff Brown51d45a72010-06-17 20:52:56 -07002268int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07002269 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002270#if DEBUG_INBOUND_EVENT_DETAILS
2271 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002272 "syncMode=%d, timeoutMillis=%d",
2273 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07002274#endif
2275
2276 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002277
2278 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2279 if (hasInjectionPermission(injectorPid, injectorUid)) {
2280 policyFlags |= POLICY_FLAG_TRUSTED;
2281 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002282
Jeff Brown90f0cee2010-10-08 22:31:17 -07002283 EventEntry* injectedEntry;
2284 switch (event->getType()) {
2285 case AINPUT_EVENT_TYPE_KEY: {
2286 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2287 int32_t action = keyEvent->getAction();
2288 if (! validateKeyEvent(action)) {
Jeff Browna665ca82010-09-08 11:49:43 -07002289 return INPUT_EVENT_INJECTION_FAILED;
2290 }
2291
Jeff Brown90f0cee2010-10-08 22:31:17 -07002292 nsecs_t eventTime = keyEvent->getEventTime();
2293 int32_t deviceId = keyEvent->getDeviceId();
2294 int32_t flags = keyEvent->getFlags();
2295 int32_t keyCode = keyEvent->getKeyCode();
2296 int32_t scanCode = keyEvent->getScanCode();
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002297 mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
2298 keyCode, scanCode, /*byref*/ policyFlags);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002299
Jeff Brown90f0cee2010-10-08 22:31:17 -07002300 mLock.lock();
2301 injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
2302 policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
2303 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2304 break;
2305 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002306
Jeff Brown90f0cee2010-10-08 22:31:17 -07002307 case AINPUT_EVENT_TYPE_MOTION: {
2308 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2309 int32_t action = motionEvent->getAction();
2310 size_t pointerCount = motionEvent->getPointerCount();
2311 const int32_t* pointerIds = motionEvent->getPointerIds();
2312 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2313 return INPUT_EVENT_INJECTION_FAILED;
2314 }
2315
2316 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown1fe6dec2010-10-11 14:20:19 -07002317 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002318
2319 mLock.lock();
2320 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2321 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2322 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2323 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2324 action, motionEvent->getFlags(),
2325 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2326 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2327 motionEvent->getDownTime(), uint32_t(pointerCount),
2328 pointerIds, samplePointerCoords);
2329 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2330 sampleEventTimes += 1;
2331 samplePointerCoords += pointerCount;
2332 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2333 }
2334 injectedEntry = motionEntry;
2335 break;
2336 }
2337
2338 default:
2339 LOGW("Cannot inject event of type %d", event->getType());
2340 return INPUT_EVENT_INJECTION_FAILED;
2341 }
2342
2343 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2344 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2345 injectionState->injectionIsAsync = true;
2346 }
2347
2348 injectionState->refCount += 1;
2349 injectedEntry->injectionState = injectionState;
2350
2351 bool needWake = enqueueInboundEventLocked(injectedEntry);
2352 mLock.unlock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002353
Jeff Browna665ca82010-09-08 11:49:43 -07002354 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07002355 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07002356 }
2357
2358 int32_t injectionResult;
2359 { // acquire lock
2360 AutoMutex _l(mLock);
2361
Jeff Brownf67c53e2010-07-28 15:48:59 -07002362 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2363 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2364 } else {
2365 for (;;) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002366 injectionResult = injectionState->injectionResult;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002367 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2368 break;
2369 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002370
Jeff Brown51d45a72010-06-17 20:52:56 -07002371 nsecs_t remainingTimeout = endTime - now();
2372 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002373#if DEBUG_INJECTION
2374 LOGD("injectInputEvent - Timed out waiting for injection result "
2375 "to become available.");
2376#endif
Jeff Brown51d45a72010-06-17 20:52:56 -07002377 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2378 break;
2379 }
2380
Jeff Brownf67c53e2010-07-28 15:48:59 -07002381 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2382 }
2383
2384 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2385 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002386 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002387#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002388 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002389 injectionState->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002390#endif
2391 nsecs_t remainingTimeout = endTime - now();
2392 if (remainingTimeout <= 0) {
2393#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002394 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002395 "dispatches to finish.");
2396#endif
2397 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2398 break;
2399 }
2400
2401 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2402 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002403 }
2404 }
2405
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002406 mAllocator.releaseInjectionState(injectionState);
Jeff Brown51d45a72010-06-17 20:52:56 -07002407 } // release lock
2408
Jeff Brownf67c53e2010-07-28 15:48:59 -07002409#if DEBUG_INJECTION
2410 LOGD("injectInputEvent - Finished with result %d. "
2411 "injectorPid=%d, injectorUid=%d",
2412 injectionResult, injectorPid, injectorUid);
2413#endif
2414
Jeff Brown51d45a72010-06-17 20:52:56 -07002415 return injectionResult;
2416}
2417
Jeff Brown90f0cee2010-10-08 22:31:17 -07002418bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2419 return injectorUid == 0
2420 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2421}
2422
Jeff Brown51d45a72010-06-17 20:52:56 -07002423void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002424 InjectionState* injectionState = entry->injectionState;
2425 if (injectionState) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002426#if DEBUG_INJECTION
2427 LOGD("Setting input event injection result to %d. "
2428 "injectorPid=%d, injectorUid=%d",
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002429 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown51d45a72010-06-17 20:52:56 -07002430#endif
2431
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002432 if (injectionState->injectionIsAsync) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002433 // Log the outcome since the injector did not wait for the injection result.
2434 switch (injectionResult) {
2435 case INPUT_EVENT_INJECTION_SUCCEEDED:
2436 LOGV("Asynchronous input event injection succeeded.");
2437 break;
2438 case INPUT_EVENT_INJECTION_FAILED:
2439 LOGW("Asynchronous input event injection failed.");
2440 break;
2441 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2442 LOGW("Asynchronous input event injection permission denied.");
2443 break;
2444 case INPUT_EVENT_INJECTION_TIMED_OUT:
2445 LOGW("Asynchronous input event injection timed out.");
2446 break;
2447 }
2448 }
2449
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002450 injectionState->injectionResult = injectionResult;
Jeff Brown51d45a72010-06-17 20:52:56 -07002451 mInjectionResultAvailableCondition.broadcast();
2452 }
2453}
2454
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002455void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2456 InjectionState* injectionState = entry->injectionState;
2457 if (injectionState) {
2458 injectionState->pendingForegroundDispatches += 1;
2459 }
2460}
2461
Jeff Brown53a415e2010-09-15 15:18:56 -07002462void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002463 InjectionState* injectionState = entry->injectionState;
2464 if (injectionState) {
2465 injectionState->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002466
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002467 if (injectionState->pendingForegroundDispatches == 0) {
2468 mInjectionSyncFinishedCondition.broadcast();
2469 }
Jeff Browna665ca82010-09-08 11:49:43 -07002470 }
2471}
2472
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002473const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2474 for (size_t i = 0; i < mWindows.size(); i++) {
2475 const InputWindow* window = & mWindows[i];
2476 if (window->inputChannel == inputChannel) {
2477 return window;
2478 }
2479 }
2480 return NULL;
2481}
2482
Jeff Browna665ca82010-09-08 11:49:43 -07002483void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2484#if DEBUG_FOCUS
2485 LOGD("setInputWindows");
2486#endif
2487 { // acquire lock
2488 AutoMutex _l(mLock);
2489
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002490 // Clear old window pointers.
Jeff Brown90f0cee2010-10-08 22:31:17 -07002491 sp<InputChannel> oldFocusedWindowChannel;
2492 if (mFocusedWindow) {
2493 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2494 mFocusedWindow = NULL;
2495 }
2496
Jeff Browna665ca82010-09-08 11:49:43 -07002497 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002498
2499 // Loop over new windows and rebuild the necessary window pointers for
2500 // tracking focus and touch.
Jeff Browna665ca82010-09-08 11:49:43 -07002501 mWindows.appendVector(inputWindows);
2502
2503 size_t numWindows = mWindows.size();
2504 for (size_t i = 0; i < numWindows; i++) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002505 const InputWindow* window = & mWindows.itemAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07002506 if (window->hasFocus) {
2507 mFocusedWindow = window;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002508 break;
Jeff Browna665ca82010-09-08 11:49:43 -07002509 }
2510 }
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002511
Jeff Brown90f0cee2010-10-08 22:31:17 -07002512 if (oldFocusedWindowChannel != NULL) {
2513 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2514#if DEBUG_FOCUS
2515 LOGD("Focus left window: %s",
2516 oldFocusedWindowChannel->getName().string());
2517#endif
2518 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2519 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2520 oldFocusedWindowChannel.clear();
2521 }
2522 }
2523 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2524#if DEBUG_FOCUS
2525 LOGD("Focus entered window: %s",
2526 mFocusedWindow->inputChannel->getName().string());
2527#endif
2528 }
2529
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002530 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2531 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2532 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2533 if (window) {
2534 touchedWindow.window = window;
2535 i += 1;
2536 } else {
Jeff Brown90f0cee2010-10-08 22:31:17 -07002537#if DEBUG_FOCUS
2538 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2539#endif
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002540 mTouchState.windows.removeAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07002541 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2542 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002543 }
2544 }
Jeff Browna665ca82010-09-08 11:49:43 -07002545
Jeff Browna665ca82010-09-08 11:49:43 -07002546#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002547 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002548#endif
2549 } // release lock
2550
2551 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002552 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002553}
2554
2555void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2556#if DEBUG_FOCUS
2557 LOGD("setFocusedApplication");
2558#endif
2559 { // acquire lock
2560 AutoMutex _l(mLock);
2561
2562 releaseFocusedApplicationLocked();
2563
2564 if (inputApplication) {
2565 mFocusedApplicationStorage = *inputApplication;
2566 mFocusedApplication = & mFocusedApplicationStorage;
2567 }
2568
2569#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002570 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002571#endif
2572 } // release lock
2573
2574 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002575 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002576}
2577
2578void InputDispatcher::releaseFocusedApplicationLocked() {
2579 if (mFocusedApplication) {
2580 mFocusedApplication = NULL;
2581 mFocusedApplicationStorage.handle.clear();
2582 }
2583}
2584
2585void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2586#if DEBUG_FOCUS
2587 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2588#endif
2589
2590 bool changed;
2591 { // acquire lock
2592 AutoMutex _l(mLock);
2593
2594 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2595 if (mDispatchFrozen && ! frozen) {
2596 resetANRTimeoutsLocked();
2597 }
2598
2599 mDispatchEnabled = enabled;
2600 mDispatchFrozen = frozen;
2601 changed = true;
2602 } else {
2603 changed = false;
2604 }
2605
2606#if DEBUG_FOCUS
Jeff Brown90f0cee2010-10-08 22:31:17 -07002607 //logDispatchStateLocked();
Jeff Browna665ca82010-09-08 11:49:43 -07002608#endif
2609 } // release lock
2610
2611 if (changed) {
2612 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002613 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002614 }
2615}
2616
Jeff Browna665ca82010-09-08 11:49:43 -07002617void InputDispatcher::logDispatchStateLocked() {
2618 String8 dump;
2619 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002620
2621 char* text = dump.lockBuffer(dump.size());
2622 char* start = text;
2623 while (*start != '\0') {
2624 char* end = strchr(start, '\n');
2625 if (*end == '\n') {
2626 *(end++) = '\0';
2627 }
2628 LOGD("%s", start);
2629 start = end;
2630 }
Jeff Browna665ca82010-09-08 11:49:43 -07002631}
2632
2633void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002634 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2635 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Browna665ca82010-09-08 11:49:43 -07002636
2637 if (mFocusedApplication) {
Jeff Brown2806e382010-10-01 17:46:21 -07002638 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002639 mFocusedApplication->name.string(),
2640 mFocusedApplication->dispatchingTimeout / 1000000.0);
2641 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002642 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002643 }
Jeff Brown2806e382010-10-01 17:46:21 -07002644 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002645 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown2806e382010-10-01 17:46:21 -07002646
2647 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2648 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2649 if (!mTouchState.windows.isEmpty()) {
2650 dump.append(INDENT "TouchedWindows:\n");
2651 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2652 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2653 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2654 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2655 touchedWindow.targetFlags);
2656 }
2657 } else {
2658 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002659 }
2660
Jeff Brown2806e382010-10-01 17:46:21 -07002661 if (!mWindows.isEmpty()) {
2662 dump.append(INDENT "Windows:\n");
2663 for (size_t i = 0; i < mWindows.size(); i++) {
2664 const InputWindow& window = mWindows[i];
2665 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2666 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2667 "frame=[%d,%d][%d,%d], "
2668 "visibleFrame=[%d,%d][%d,%d], "
2669 "touchableArea=[%d,%d][%d,%d], "
2670 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2671 i, window.name.string(),
2672 toString(window.paused),
2673 toString(window.hasFocus),
2674 toString(window.hasWallpaper),
2675 toString(window.visible),
2676 toString(window.canReceiveKeys),
2677 window.layoutParamsFlags, window.layoutParamsType,
2678 window.layer,
2679 window.frameLeft, window.frameTop,
2680 window.frameRight, window.frameBottom,
2681 window.visibleFrameLeft, window.visibleFrameTop,
2682 window.visibleFrameRight, window.visibleFrameBottom,
2683 window.touchableAreaLeft, window.touchableAreaTop,
2684 window.touchableAreaRight, window.touchableAreaBottom,
2685 window.ownerPid, window.ownerUid,
2686 window.dispatchingTimeout / 1000000.0);
2687 }
2688 } else {
2689 dump.append(INDENT "Windows: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002690 }
2691
Jeff Brown2806e382010-10-01 17:46:21 -07002692 if (!mMonitoringChannels.isEmpty()) {
2693 dump.append(INDENT "MonitoringChannels:\n");
2694 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2695 const sp<InputChannel>& channel = mMonitoringChannels[i];
2696 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2697 }
2698 } else {
2699 dump.append(INDENT "MonitoringChannels: <none>\n");
2700 }
Jeff Brown53a415e2010-09-15 15:18:56 -07002701
Jeff Brown2806e382010-10-01 17:46:21 -07002702 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2703
2704 if (!mActiveConnections.isEmpty()) {
2705 dump.append(INDENT "ActiveConnections:\n");
2706 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2707 const Connection* connection = mActiveConnections[i];
2708 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
Jeff Brown90f0cee2010-10-08 22:31:17 -07002709 "inputState.isNeutral=%s\n",
Jeff Brown2806e382010-10-01 17:46:21 -07002710 i, connection->getInputChannelName(), connection->getStatusLabel(),
2711 connection->outboundQueue.count(),
Jeff Brown90f0cee2010-10-08 22:31:17 -07002712 toString(connection->inputState.isNeutral()));
Jeff Brown2806e382010-10-01 17:46:21 -07002713 }
2714 } else {
2715 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002716 }
2717
2718 if (isAppSwitchPendingLocked()) {
Jeff Brown2806e382010-10-01 17:46:21 -07002719 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Browna665ca82010-09-08 11:49:43 -07002720 (mAppSwitchDueTime - now()) / 1000000.0);
2721 } else {
Jeff Brown2806e382010-10-01 17:46:21 -07002722 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002723 }
2724}
2725
2726status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002727#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002728 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2729 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002730#endif
2731
Jeff Browne839a582010-04-22 18:58:52 -07002732 { // acquire lock
2733 AutoMutex _l(mLock);
2734
Jeff Brown53a415e2010-09-15 15:18:56 -07002735 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002736 LOGW("Attempted to register already registered input channel '%s'",
2737 inputChannel->getName().string());
2738 return BAD_VALUE;
2739 }
2740
2741 sp<Connection> connection = new Connection(inputChannel);
2742 status_t status = connection->initialize();
2743 if (status) {
2744 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2745 inputChannel->getName().string(), status);
2746 return status;
2747 }
2748
Jeff Brown0cacb872010-08-17 15:59:26 -07002749 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002750 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002751
Jeff Browna665ca82010-09-08 11:49:43 -07002752 if (monitor) {
2753 mMonitoringChannels.push(inputChannel);
2754 }
2755
Jeff Brown59abe7e2010-09-13 23:17:30 -07002756 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002757
Jeff Brown54bc2812010-06-15 01:31:58 -07002758 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002759 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002760 return OK;
2761}
2762
2763status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002764#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002765 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002766#endif
2767
Jeff Browne839a582010-04-22 18:58:52 -07002768 { // acquire lock
2769 AutoMutex _l(mLock);
2770
Jeff Brown53a415e2010-09-15 15:18:56 -07002771 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002772 if (connectionIndex < 0) {
2773 LOGW("Attempted to unregister already unregistered input channel '%s'",
2774 inputChannel->getName().string());
2775 return BAD_VALUE;
2776 }
2777
2778 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2779 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2780
2781 connection->status = Connection::STATUS_ZOMBIE;
2782
Jeff Browna665ca82010-09-08 11:49:43 -07002783 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2784 if (mMonitoringChannels[i] == inputChannel) {
2785 mMonitoringChannels.removeAt(i);
2786 break;
2787 }
2788 }
2789
Jeff Brown59abe7e2010-09-13 23:17:30 -07002790 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002791
Jeff Brown51d45a72010-06-17 20:52:56 -07002792 nsecs_t currentTime = now();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002793 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002794
2795 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002796 } // release lock
2797
Jeff Browne839a582010-04-22 18:58:52 -07002798 // Wake the poll loop because removing the connection may have changed the current
2799 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002800 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002801 return OK;
2802}
2803
Jeff Brown53a415e2010-09-15 15:18:56 -07002804ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002805 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2806 if (connectionIndex >= 0) {
2807 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2808 if (connection->inputChannel.get() == inputChannel.get()) {
2809 return connectionIndex;
2810 }
2811 }
2812
2813 return -1;
2814}
2815
Jeff Browne839a582010-04-22 18:58:52 -07002816void InputDispatcher::activateConnectionLocked(Connection* connection) {
2817 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2818 if (mActiveConnections.itemAt(i) == connection) {
2819 return;
2820 }
2821 }
2822 mActiveConnections.add(connection);
2823}
2824
2825void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2826 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2827 if (mActiveConnections.itemAt(i) == connection) {
2828 mActiveConnections.removeAt(i);
2829 return;
2830 }
2831 }
2832}
2833
Jeff Brown54bc2812010-06-15 01:31:58 -07002834void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002835 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002836}
2837
Jeff Brown54bc2812010-06-15 01:31:58 -07002838void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002839 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002840}
2841
Jeff Brown54bc2812010-06-15 01:31:58 -07002842void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002843 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002844 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2845 connection->getInputChannelName());
2846
Jeff Brown54bc2812010-06-15 01:31:58 -07002847 CommandEntry* commandEntry = postCommandLocked(
2848 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002849 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002850}
2851
Jeff Brown53a415e2010-09-15 15:18:56 -07002852void InputDispatcher::onANRLocked(
2853 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2854 nsecs_t eventTime, nsecs_t waitStartTime) {
2855 LOGI("Application is not responding: %s. "
2856 "%01.1fms since event, %01.1fms since wait started",
2857 getApplicationWindowLabelLocked(application, window).string(),
2858 (currentTime - eventTime) / 1000000.0,
2859 (currentTime - waitStartTime) / 1000000.0);
2860
2861 CommandEntry* commandEntry = postCommandLocked(
2862 & InputDispatcher::doNotifyANRLockedInterruptible);
2863 if (application) {
2864 commandEntry->inputApplicationHandle = application->handle;
2865 }
2866 if (window) {
2867 commandEntry->inputChannel = window->inputChannel;
2868 }
2869}
2870
Jeff Browna665ca82010-09-08 11:49:43 -07002871void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2872 CommandEntry* commandEntry) {
2873 mLock.unlock();
2874
2875 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2876
2877 mLock.lock();
2878}
2879
Jeff Brown54bc2812010-06-15 01:31:58 -07002880void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2881 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002882 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002883
Jeff Brown51d45a72010-06-17 20:52:56 -07002884 if (connection->status != Connection::STATUS_ZOMBIE) {
2885 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002886
Jeff Brown51d45a72010-06-17 20:52:56 -07002887 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2888
2889 mLock.lock();
2890 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002891}
2892
Jeff Brown53a415e2010-09-15 15:18:56 -07002893void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002894 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002895 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002896
Jeff Brown53a415e2010-09-15 15:18:56 -07002897 nsecs_t newTimeout = mPolicy->notifyANR(
2898 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002899
Jeff Brown53a415e2010-09-15 15:18:56 -07002900 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002901
Jeff Brown53a415e2010-09-15 15:18:56 -07002902 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002903}
2904
Jeff Browna665ca82010-09-08 11:49:43 -07002905void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2906 CommandEntry* commandEntry) {
2907 KeyEntry* entry = commandEntry->keyEntry;
2908 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2909 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2910 entry->downTime, entry->eventTime);
2911
2912 mLock.unlock();
2913
2914 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2915 & mReusableKeyEvent, entry->policyFlags);
2916
2917 mLock.lock();
2918
2919 entry->interceptKeyResult = consumed
2920 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2921 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2922 mAllocator.releaseKeyEntry(entry);
2923}
2924
2925void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2926 mLock.unlock();
2927
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002928 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Browna665ca82010-09-08 11:49:43 -07002929
2930 mLock.lock();
2931}
2932
Jeff Brown53a415e2010-09-15 15:18:56 -07002933void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
2934 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
2935 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07002936}
2937
2938void InputDispatcher::dump(String8& dump) {
Jeff Brown2806e382010-10-01 17:46:21 -07002939 dump.append("Input Dispatcher State:\n");
Jeff Browna665ca82010-09-08 11:49:43 -07002940 dumpDispatchStateLocked(dump);
2941}
2942
Jeff Brown54bc2812010-06-15 01:31:58 -07002943
Jeff Brown53a415e2010-09-15 15:18:56 -07002944// --- InputDispatcher::Queue ---
2945
2946template <typename T>
2947uint32_t InputDispatcher::Queue<T>::count() const {
2948 uint32_t result = 0;
2949 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
2950 result += 1;
2951 }
2952 return result;
2953}
2954
2955
Jeff Browne839a582010-04-22 18:58:52 -07002956// --- InputDispatcher::Allocator ---
2957
2958InputDispatcher::Allocator::Allocator() {
2959}
2960
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002961InputDispatcher::InjectionState*
2962InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
2963 InjectionState* injectionState = mInjectionStatePool.alloc();
2964 injectionState->refCount = 1;
2965 injectionState->injectorPid = injectorPid;
2966 injectionState->injectorUid = injectorUid;
2967 injectionState->injectionIsAsync = false;
2968 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
2969 injectionState->pendingForegroundDispatches = 0;
2970 return injectionState;
2971}
2972
Jeff Brown51d45a72010-06-17 20:52:56 -07002973void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brown90f0cee2010-10-08 22:31:17 -07002974 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002975 entry->type = type;
2976 entry->refCount = 1;
2977 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07002978 entry->eventTime = eventTime;
Jeff Brown90f0cee2010-10-08 22:31:17 -07002979 entry->policyFlags = policyFlags;
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07002980 entry->injectionState = NULL;
2981}
2982
2983void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
2984 if (entry->injectionState) {
2985 releaseInjectionState(entry->injectionState);
2986 entry->injectionState = NULL;
2987 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002988}
2989
Jeff Browne839a582010-04-22 18:58:52 -07002990InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07002991InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002992 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07002993 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Browne839a582010-04-22 18:58:52 -07002994 return entry;
2995}
2996
Jeff Brown51d45a72010-06-17 20:52:56 -07002997InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002998 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07002999 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3000 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07003001 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003002 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003003
3004 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003005 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003006 entry->action = action;
3007 entry->flags = flags;
3008 entry->keyCode = keyCode;
3009 entry->scanCode = scanCode;
3010 entry->metaState = metaState;
3011 entry->repeatCount = repeatCount;
3012 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07003013 entry->syntheticRepeat = false;
3014 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07003015 return entry;
3016}
3017
Jeff Brown51d45a72010-06-17 20:52:56 -07003018InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07003019 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07003020 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3021 nsecs_t downTime, uint32_t pointerCount,
3022 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003023 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003024 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown51d45a72010-06-17 20:52:56 -07003025
3026 entry->eventTime = eventTime;
3027 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07003028 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07003029 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07003030 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07003031 entry->metaState = metaState;
3032 entry->edgeFlags = edgeFlags;
3033 entry->xPrecision = xPrecision;
3034 entry->yPrecision = yPrecision;
3035 entry->downTime = downTime;
3036 entry->pointerCount = pointerCount;
3037 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07003038 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07003039 entry->lastSample = & entry->firstSample;
3040 for (uint32_t i = 0; i < pointerCount; i++) {
3041 entry->pointerIds[i] = pointerIds[i];
3042 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3043 }
Jeff Browne839a582010-04-22 18:58:52 -07003044 return entry;
3045}
3046
3047InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07003048 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07003049 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07003050 DispatchEntry* entry = mDispatchEntryPool.alloc();
3051 entry->eventEntry = eventEntry;
3052 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07003053 entry->targetFlags = targetFlags;
3054 entry->xOffset = xOffset;
3055 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07003056 entry->inProgress = false;
3057 entry->headMotionSample = NULL;
3058 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07003059 return entry;
3060}
3061
Jeff Brown54bc2812010-06-15 01:31:58 -07003062InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3063 CommandEntry* entry = mCommandEntryPool.alloc();
3064 entry->command = command;
3065 return entry;
3066}
3067
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003068void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3069 injectionState->refCount -= 1;
3070 if (injectionState->refCount == 0) {
3071 mInjectionStatePool.free(injectionState);
3072 } else {
3073 assert(injectionState->refCount > 0);
3074 }
3075}
3076
Jeff Browne839a582010-04-22 18:58:52 -07003077void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3078 switch (entry->type) {
3079 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3080 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3081 break;
3082 case EventEntry::TYPE_KEY:
3083 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3084 break;
3085 case EventEntry::TYPE_MOTION:
3086 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3087 break;
3088 default:
3089 assert(false);
3090 break;
3091 }
3092}
3093
3094void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3095 ConfigurationChangedEntry* entry) {
3096 entry->refCount -= 1;
3097 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003098 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003099 mConfigurationChangeEntryPool.free(entry);
3100 } else {
3101 assert(entry->refCount > 0);
3102 }
3103}
3104
3105void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3106 entry->refCount -= 1;
3107 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003108 releaseEventEntryInjectionState(entry);
Jeff Browne839a582010-04-22 18:58:52 -07003109 mKeyEntryPool.free(entry);
3110 } else {
3111 assert(entry->refCount > 0);
3112 }
3113}
3114
3115void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3116 entry->refCount -= 1;
3117 if (entry->refCount == 0) {
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003118 releaseEventEntryInjectionState(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -07003119 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3120 MotionSample* next = sample->next;
3121 mMotionSamplePool.free(sample);
3122 sample = next;
3123 }
Jeff Browne839a582010-04-22 18:58:52 -07003124 mMotionEntryPool.free(entry);
3125 } else {
3126 assert(entry->refCount > 0);
3127 }
3128}
3129
3130void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3131 releaseEventEntry(entry->eventEntry);
3132 mDispatchEntryPool.free(entry);
3133}
3134
Jeff Brown54bc2812010-06-15 01:31:58 -07003135void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3136 mCommandEntryPool.free(entry);
3137}
3138
Jeff Browne839a582010-04-22 18:58:52 -07003139void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07003140 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07003141 MotionSample* sample = mMotionSamplePool.alloc();
3142 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07003143 uint32_t pointerCount = motionEntry->pointerCount;
3144 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07003145 sample->pointerCoords[i] = pointerCoords[i];
3146 }
3147
3148 sample->next = NULL;
3149 motionEntry->lastSample->next = sample;
3150 motionEntry->lastSample = sample;
3151}
3152
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003153void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3154 releaseEventEntryInjectionState(keyEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07003155
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003156 keyEntry->dispatchInProgress = false;
3157 keyEntry->syntheticRepeat = false;
3158 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browna665ca82010-09-08 11:49:43 -07003159}
3160
3161
Jeff Brown542412c2010-08-18 15:51:08 -07003162// --- InputDispatcher::MotionEntry ---
3163
3164uint32_t InputDispatcher::MotionEntry::countSamples() const {
3165 uint32_t count = 1;
3166 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3167 count += 1;
3168 }
3169 return count;
3170}
3171
Jeff Browna665ca82010-09-08 11:49:43 -07003172
3173// --- InputDispatcher::InputState ---
3174
Jeff Brown90f0cee2010-10-08 22:31:17 -07003175InputDispatcher::InputState::InputState() {
Jeff Browna665ca82010-09-08 11:49:43 -07003176}
3177
3178InputDispatcher::InputState::~InputState() {
3179}
3180
3181bool InputDispatcher::InputState::isNeutral() const {
3182 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3183}
3184
Jeff Browna665ca82010-09-08 11:49:43 -07003185InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3186 const EventEntry* entry) {
3187 switch (entry->type) {
3188 case EventEntry::TYPE_KEY:
3189 return trackKey(static_cast<const KeyEntry*>(entry));
3190
3191 case EventEntry::TYPE_MOTION:
3192 return trackMotion(static_cast<const MotionEntry*>(entry));
3193
3194 default:
3195 return CONSISTENT;
3196 }
3197}
3198
3199InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3200 const KeyEntry* entry) {
3201 int32_t action = entry->action;
3202 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3203 KeyMemento& memento = mKeyMementos.editItemAt(i);
3204 if (memento.deviceId == entry->deviceId
3205 && memento.source == entry->source
3206 && memento.keyCode == entry->keyCode
3207 && memento.scanCode == entry->scanCode) {
3208 switch (action) {
3209 case AKEY_EVENT_ACTION_UP:
3210 mKeyMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003211 return CONSISTENT;
3212
3213 case AKEY_EVENT_ACTION_DOWN:
3214 return TOLERABLE;
3215
3216 default:
3217 return BROKEN;
3218 }
3219 }
3220 }
3221
3222 switch (action) {
3223 case AKEY_EVENT_ACTION_DOWN: {
3224 mKeyMementos.push();
3225 KeyMemento& memento = mKeyMementos.editTop();
3226 memento.deviceId = entry->deviceId;
3227 memento.source = entry->source;
3228 memento.keyCode = entry->keyCode;
3229 memento.scanCode = entry->scanCode;
3230 memento.downTime = entry->downTime;
3231 return CONSISTENT;
3232 }
3233
3234 default:
3235 return BROKEN;
3236 }
3237}
3238
3239InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3240 const MotionEntry* entry) {
3241 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3242 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3243 MotionMemento& memento = mMotionMementos.editItemAt(i);
3244 if (memento.deviceId == entry->deviceId
3245 && memento.source == entry->source) {
3246 switch (action) {
3247 case AMOTION_EVENT_ACTION_UP:
3248 case AMOTION_EVENT_ACTION_CANCEL:
3249 mMotionMementos.removeAt(i);
Jeff Browna665ca82010-09-08 11:49:43 -07003250 return CONSISTENT;
3251
3252 case AMOTION_EVENT_ACTION_DOWN:
3253 return TOLERABLE;
3254
3255 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3256 if (entry->pointerCount == memento.pointerCount + 1) {
3257 memento.setPointers(entry);
3258 return CONSISTENT;
3259 }
3260 return BROKEN;
3261
3262 case AMOTION_EVENT_ACTION_POINTER_UP:
3263 if (entry->pointerCount == memento.pointerCount - 1) {
3264 memento.setPointers(entry);
3265 return CONSISTENT;
3266 }
3267 return BROKEN;
3268
3269 case AMOTION_EVENT_ACTION_MOVE:
3270 if (entry->pointerCount == memento.pointerCount) {
3271 return CONSISTENT;
3272 }
3273 return BROKEN;
3274
3275 default:
3276 return BROKEN;
3277 }
3278 }
3279 }
3280
3281 switch (action) {
3282 case AMOTION_EVENT_ACTION_DOWN: {
3283 mMotionMementos.push();
3284 MotionMemento& memento = mMotionMementos.editTop();
3285 memento.deviceId = entry->deviceId;
3286 memento.source = entry->source;
3287 memento.xPrecision = entry->xPrecision;
3288 memento.yPrecision = entry->yPrecision;
3289 memento.downTime = entry->downTime;
3290 memento.setPointers(entry);
3291 return CONSISTENT;
3292 }
3293
3294 default:
3295 return BROKEN;
3296 }
3297}
3298
3299void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3300 pointerCount = entry->pointerCount;
3301 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3302 pointerIds[i] = entry->pointerIds[i];
3303 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3304 }
3305}
3306
Jeff Brown90f0cee2010-10-08 22:31:17 -07003307void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3308 Allocator* allocator, Vector<EventEntry*>& outEvents,
3309 CancelationOptions options) {
3310 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Browna665ca82010-09-08 11:49:43 -07003311 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003312 if (shouldCancelEvent(memento.source, options)) {
3313 outEvents.push(allocator->obtainKeyEntry(currentTime,
3314 memento.deviceId, memento.source, 0,
3315 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3316 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3317 mKeyMementos.removeAt(i);
3318 } else {
3319 i += 1;
3320 }
Jeff Browna665ca82010-09-08 11:49:43 -07003321 }
3322
3323 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3324 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown90f0cee2010-10-08 22:31:17 -07003325 if (shouldCancelEvent(memento.source, options)) {
3326 outEvents.push(allocator->obtainMotionEntry(currentTime,
3327 memento.deviceId, memento.source, 0,
3328 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3329 memento.xPrecision, memento.yPrecision, memento.downTime,
3330 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3331 mMotionMementos.removeAt(i);
3332 } else {
3333 i += 1;
3334 }
Jeff Browna665ca82010-09-08 11:49:43 -07003335 }
3336}
3337
3338void InputDispatcher::InputState::clear() {
3339 mKeyMementos.clear();
3340 mMotionMementos.clear();
Jeff Brown90f0cee2010-10-08 22:31:17 -07003341}
3342
3343bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
3344 CancelationOptions options) {
3345 switch (options) {
3346 case CANCEL_POINTER_EVENTS:
3347 return eventSource & AINPUT_SOURCE_CLASS_POINTER;
3348 case CANCEL_NON_POINTER_EVENTS:
3349 return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
3350 default:
3351 return true;
3352 }
Jeff Browna665ca82010-09-08 11:49:43 -07003353}
3354
3355
Jeff Browne839a582010-04-22 18:58:52 -07003356// --- InputDispatcher::Connection ---
3357
3358InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3359 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003360 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003361}
3362
3363InputDispatcher::Connection::~Connection() {
3364}
3365
3366status_t InputDispatcher::Connection::initialize() {
3367 return inputPublisher.initialize();
3368}
3369
Jeff Brown54bc2812010-06-15 01:31:58 -07003370const char* InputDispatcher::Connection::getStatusLabel() const {
3371 switch (status) {
3372 case STATUS_NORMAL:
3373 return "NORMAL";
3374
3375 case STATUS_BROKEN:
3376 return "BROKEN";
3377
Jeff Brown54bc2812010-06-15 01:31:58 -07003378 case STATUS_ZOMBIE:
3379 return "ZOMBIE";
3380
3381 default:
3382 return "UNKNOWN";
3383 }
3384}
3385
Jeff Browne839a582010-04-22 18:58:52 -07003386InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3387 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003388 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3389 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003390 if (dispatchEntry->eventEntry == eventEntry) {
3391 return dispatchEntry;
3392 }
3393 }
3394 return NULL;
3395}
3396
Jeff Browna665ca82010-09-08 11:49:43 -07003397
Jeff Brown54bc2812010-06-15 01:31:58 -07003398// --- InputDispatcher::CommandEntry ---
3399
Jeff Browna665ca82010-09-08 11:49:43 -07003400InputDispatcher::CommandEntry::CommandEntry() :
3401 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003402}
3403
3404InputDispatcher::CommandEntry::~CommandEntry() {
3405}
3406
Jeff Browne839a582010-04-22 18:58:52 -07003407
Jeff Brownd1b0a2b2010-09-26 22:20:12 -07003408// --- InputDispatcher::TouchState ---
3409
3410InputDispatcher::TouchState::TouchState() :
3411 down(false), split(false) {
3412}
3413
3414InputDispatcher::TouchState::~TouchState() {
3415}
3416
3417void InputDispatcher::TouchState::reset() {
3418 down = false;
3419 split = false;
3420 windows.clear();
3421}
3422
3423void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3424 down = other.down;
3425 split = other.split;
3426 windows.clear();
3427 windows.appendVector(other.windows);
3428}
3429
3430void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3431 int32_t targetFlags, BitSet32 pointerIds) {
3432 if (targetFlags & InputTarget::FLAG_SPLIT) {
3433 split = true;
3434 }
3435
3436 for (size_t i = 0; i < windows.size(); i++) {
3437 TouchedWindow& touchedWindow = windows.editItemAt(i);
3438 if (touchedWindow.window == window) {
3439 touchedWindow.targetFlags |= targetFlags;
3440 touchedWindow.pointerIds.value |= pointerIds.value;
3441 return;
3442 }
3443 }
3444
3445 windows.push();
3446
3447 TouchedWindow& touchedWindow = windows.editTop();
3448 touchedWindow.window = window;
3449 touchedWindow.targetFlags = targetFlags;
3450 touchedWindow.pointerIds = pointerIds;
3451 touchedWindow.channel = window->inputChannel;
3452}
3453
3454void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3455 for (size_t i = 0 ; i < windows.size(); ) {
3456 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3457 windows.removeAt(i);
3458 } else {
3459 i += 1;
3460 }
3461 }
3462}
3463
3464const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3465 for (size_t i = 0; i < windows.size(); i++) {
3466 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3467 return windows[i].window;
3468 }
3469 }
3470 return NULL;
3471}
3472
3473
Jeff Browne839a582010-04-22 18:58:52 -07003474// --- InputDispatcherThread ---
3475
3476InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3477 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3478}
3479
3480InputDispatcherThread::~InputDispatcherThread() {
3481}
3482
3483bool InputDispatcherThread::threadLoop() {
3484 mDispatcher->dispatchOnce();
3485 return true;
3486}
3487
3488} // namespace android