blob: 1cf7592ff5da529e08d33499fab9a7b0a0fa4a28 [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
49namespace android {
50
Jeff Browna665ca82010-09-08 11:49:43 -070051// Delay between reporting long touch events to the power manager.
52const nsecs_t EVENT_IGNORE_DURATION = 300 * 1000000LL; // 300 ms
53
54// Default input dispatching timeout if there is no focused application or paused window
55// from which to determine an appropriate dispatching timeout.
56const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
57
58// Amount of time to allow for all pending events to be processed when an app switch
59// key is on the way. This is used to preempt input dispatch and drop input events
60// when an application takes too long to respond and the user has pressed an app switch key.
61const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
62
Jeff Browne839a582010-04-22 18:58:52 -070063
Jeff Brown51d45a72010-06-17 20:52:56 -070064static inline nsecs_t now() {
65 return systemTime(SYSTEM_TIME_MONOTONIC);
66}
67
Jeff Browna665ca82010-09-08 11:49:43 -070068static inline const char* toString(bool value) {
69 return value ? "true" : "false";
70}
71
72
73// --- InputWindow ---
74
75bool InputWindow::visibleFrameIntersects(const InputWindow* other) const {
76 return visibleFrameRight > other->visibleFrameLeft
77 && visibleFrameLeft < other->visibleFrameRight
78 && visibleFrameBottom > other->visibleFrameTop
79 && visibleFrameTop < other->visibleFrameBottom;
80}
81
82bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
83 return x >= touchableAreaLeft && x <= touchableAreaRight
84 && y >= touchableAreaTop && y <= touchableAreaBottom;
85}
86
87
Jeff Browne839a582010-04-22 18:58:52 -070088// --- InputDispatcher ---
89
Jeff Brown54bc2812010-06-15 01:31:58 -070090InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Browna665ca82010-09-08 11:49:43 -070091 mPolicy(policy),
92 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
93 mDispatchEnabled(true), mDispatchFrozen(false),
94 mFocusedWindow(NULL), mTouchDown(false), mTouchedWindow(NULL),
95 mFocusedApplication(NULL),
96 mCurrentInputTargetsValid(false),
97 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown59abe7e2010-09-13 23:17:30 -070098 mLooper = new Looper(false);
Jeff Browne839a582010-04-22 18:58:52 -070099
Jeff Browna665ca82010-09-08 11:49:43 -0700100 mInboundQueue.headSentinel.refCount = -1;
101 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
102 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Browne839a582010-04-22 18:58:52 -0700103
Jeff Browna665ca82010-09-08 11:49:43 -0700104 mInboundQueue.tailSentinel.refCount = -1;
105 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
106 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Browne839a582010-04-22 18:58:52 -0700107
108 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown54bc2812010-06-15 01:31:58 -0700109
Jeff Brown542412c2010-08-18 15:51:08 -0700110 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
111 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
112 mThrottleState.lastDeviceId = -1;
113
114#if DEBUG_THROTTLING
115 mThrottleState.originalSampleCount = 0;
116 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
117#endif
Jeff Browne839a582010-04-22 18:58:52 -0700118}
119
120InputDispatcher::~InputDispatcher() {
Jeff Browna665ca82010-09-08 11:49:43 -0700121 { // acquire lock
122 AutoMutex _l(mLock);
123
124 resetKeyRepeatLocked();
Jeff Brownd8816c32010-09-16 14:07:33 -0700125 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700126 drainInboundQueueLocked();
127 }
Jeff Browne839a582010-04-22 18:58:52 -0700128
129 while (mConnectionsByReceiveFd.size() != 0) {
130 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
131 }
Jeff Browne839a582010-04-22 18:58:52 -0700132}
133
134void InputDispatcher::dispatchOnce() {
Jeff Brown54bc2812010-06-15 01:31:58 -0700135 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brown61ce3982010-09-07 10:44:57 -0700136 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Browne839a582010-04-22 18:58:52 -0700137
Jeff Browne839a582010-04-22 18:58:52 -0700138 nsecs_t nextWakeupTime = LONG_LONG_MAX;
139 { // acquire lock
140 AutoMutex _l(mLock);
Jeff Browna665ca82010-09-08 11:49:43 -0700141 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Browne839a582010-04-22 18:58:52 -0700142
Jeff Browna665ca82010-09-08 11:49:43 -0700143 if (runCommandsLockedInterruptible()) {
144 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Browne839a582010-04-22 18:58:52 -0700145 }
Jeff Browne839a582010-04-22 18:58:52 -0700146 } // release lock
147
Jeff Browna665ca82010-09-08 11:49:43 -0700148 // Wait for callback or timeout or wake. (make sure we round up, not down)
149 nsecs_t currentTime = now();
150 int32_t timeoutMillis;
151 if (nextWakeupTime > currentTime) {
152 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
153 timeout = (timeout + 999999LL) / 1000000LL;
154 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
155 } else {
156 timeoutMillis = 0;
157 }
158
Jeff Brown59abe7e2010-09-13 23:17:30 -0700159 mLooper->pollOnce(timeoutMillis);
Jeff Browna665ca82010-09-08 11:49:43 -0700160}
161
162void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
163 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
164 nsecs_t currentTime = now();
165
166 // Reset the key repeat timer whenever we disallow key events, even if the next event
167 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
168 // out of sleep.
169 if (keyRepeatTimeout < 0) {
170 resetKeyRepeatLocked();
171 }
172
173 // If dispatching is disabled, drop all events in the queue.
174 if (! mDispatchEnabled) {
175 if (mPendingEvent || ! mInboundQueue.isEmpty()) {
176 LOGI("Dropping pending events because input dispatch is disabled.");
Jeff Brownd8816c32010-09-16 14:07:33 -0700177 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700178 drainInboundQueueLocked();
179 }
Jeff Brown54bc2812010-06-15 01:31:58 -0700180 return;
181 }
182
Jeff Browna665ca82010-09-08 11:49:43 -0700183 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
184 if (mDispatchFrozen) {
185#if DEBUG_FOCUS
186 LOGD("Dispatch frozen. Waiting some more.");
187#endif
188 return;
189 }
190
191 // Optimize latency of app switches.
192 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
193 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
194 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
195 if (mAppSwitchDueTime < *nextWakeupTime) {
196 *nextWakeupTime = mAppSwitchDueTime;
197 }
198
Jeff Browna665ca82010-09-08 11:49:43 -0700199 // Ready to start a new event.
200 // If we don't already have a pending event, go grab one.
201 if (! mPendingEvent) {
202 if (mInboundQueue.isEmpty()) {
203 if (isAppSwitchDue) {
204 // The inbound queue is empty so the app switch key we were waiting
205 // for will never arrive. Stop waiting for it.
206 resetPendingAppSwitchLocked(false);
207 isAppSwitchDue = false;
208 }
209
210 // Synthesize a key repeat if appropriate.
211 if (mKeyRepeatState.lastKeyEntry) {
212 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
213 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
214 } else {
215 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
216 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
217 }
218 }
219 }
220 if (! mPendingEvent) {
221 return;
222 }
223 } else {
224 // Inbound queue has at least one entry.
225 EventEntry* entry = mInboundQueue.headSentinel.next;
226
227 // Throttle the entry if it is a move event and there are no
228 // other events behind it in the queue. Due to movement batching, additional
229 // samples may be appended to this event by the time the throttling timeout
230 // expires.
231 // TODO Make this smarter and consider throttling per device independently.
232 if (entry->type == EventEntry::TYPE_MOTION) {
233 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
234 int32_t deviceId = motionEntry->deviceId;
235 uint32_t source = motionEntry->source;
236 if (! isAppSwitchDue
237 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
238 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
239 && deviceId == mThrottleState.lastDeviceId
240 && source == mThrottleState.lastSource) {
241 nsecs_t nextTime = mThrottleState.lastEventTime
242 + mThrottleState.minTimeBetweenEvents;
243 if (currentTime < nextTime) {
244 // Throttle it!
245#if DEBUG_THROTTLING
246 LOGD("Throttling - Delaying motion event for "
247 "device 0x%x, source 0x%08x by up to %0.3fms.",
248 deviceId, source, (nextTime - currentTime) * 0.000001);
249#endif
250 if (nextTime < *nextWakeupTime) {
251 *nextWakeupTime = nextTime;
252 }
253 if (mThrottleState.originalSampleCount == 0) {
254 mThrottleState.originalSampleCount =
255 motionEntry->countSamples();
256 }
257 return;
258 }
259 }
260
261#if DEBUG_THROTTLING
262 if (mThrottleState.originalSampleCount != 0) {
263 uint32_t count = motionEntry->countSamples();
264 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
265 count - mThrottleState.originalSampleCount,
266 mThrottleState.originalSampleCount, count);
267 mThrottleState.originalSampleCount = 0;
268 }
269#endif
270
271 mThrottleState.lastEventTime = entry->eventTime < currentTime
272 ? entry->eventTime : currentTime;
273 mThrottleState.lastDeviceId = deviceId;
274 mThrottleState.lastSource = source;
275 }
276
277 mInboundQueue.dequeue(entry);
278 mPendingEvent = entry;
279 }
280 }
281
282 // Now we have an event to dispatch.
283 assert(mPendingEvent != NULL);
Jeff Brownd8816c32010-09-16 14:07:33 -0700284 bool done = false;
Jeff Browna665ca82010-09-08 11:49:43 -0700285 switch (mPendingEvent->type) {
286 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
287 ConfigurationChangedEntry* typedEntry =
288 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brownd8816c32010-09-16 14:07:33 -0700289 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Browna665ca82010-09-08 11:49:43 -0700290 break;
291 }
292
293 case EventEntry::TYPE_KEY: {
294 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brownd8816c32010-09-16 14:07:33 -0700295 bool appSwitchKey = isAppSwitchKey(typedEntry->keyCode);
296 bool dropEvent = isAppSwitchDue && ! appSwitchKey;
297 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout, dropEvent,
298 nextWakeupTime);
299 if (done) {
300 if (dropEvent) {
301 LOGI("Dropped key because of pending overdue app switch.");
302 } else if (appSwitchKey) {
Jeff Browna665ca82010-09-08 11:49:43 -0700303 resetPendingAppSwitchLocked(true);
Jeff Browna665ca82010-09-08 11:49:43 -0700304 }
305 }
Jeff Browna665ca82010-09-08 11:49:43 -0700306 break;
307 }
308
309 case EventEntry::TYPE_MOTION: {
310 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brownd8816c32010-09-16 14:07:33 -0700311 bool dropEvent = isAppSwitchDue;
312 done = dispatchMotionLocked(currentTime, typedEntry, dropEvent, nextWakeupTime);
313 if (done) {
314 if (dropEvent) {
315 LOGI("Dropped motion because of pending overdue app switch.");
316 }
Jeff Browna665ca82010-09-08 11:49:43 -0700317 }
Jeff Browna665ca82010-09-08 11:49:43 -0700318 break;
319 }
320
321 default:
322 assert(false);
Jeff Browna665ca82010-09-08 11:49:43 -0700323 break;
324 }
325
Jeff Brownd8816c32010-09-16 14:07:33 -0700326 if (done) {
327 releasePendingEventLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700328 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
329 }
330}
331
332bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
333 bool needWake = mInboundQueue.isEmpty();
334 mInboundQueue.enqueueAtTail(entry);
335
336 switch (entry->type) {
337 case EventEntry::TYPE_KEY:
338 needWake |= detectPendingAppSwitchLocked(static_cast<KeyEntry*>(entry));
339 break;
340 }
341
342 return needWake;
343}
344
345bool InputDispatcher::isAppSwitchKey(int32_t keyCode) {
346 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
347}
348
349bool InputDispatcher::isAppSwitchPendingLocked() {
350 return mAppSwitchDueTime != LONG_LONG_MAX;
351}
352
353bool InputDispatcher::detectPendingAppSwitchLocked(KeyEntry* inboundKeyEntry) {
354 if (inboundKeyEntry->action == AKEY_EVENT_ACTION_UP
355 && ! (inboundKeyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
356 && isAppSwitchKey(inboundKeyEntry->keyCode)
357 && isEventFromReliableSourceLocked(inboundKeyEntry)) {
358#if DEBUG_APP_SWITCH
359 LOGD("App switch is pending!");
360#endif
361 mAppSwitchDueTime = inboundKeyEntry->eventTime + APP_SWITCH_TIMEOUT;
362 return true; // need wake
363 }
364 return false;
365}
366
367void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
368 mAppSwitchDueTime = LONG_LONG_MAX;
369
370#if DEBUG_APP_SWITCH
371 if (handled) {
372 LOGD("App switch has arrived.");
373 } else {
374 LOGD("App switch was abandoned.");
375 }
376#endif
Jeff Browne839a582010-04-22 18:58:52 -0700377}
378
Jeff Brown54bc2812010-06-15 01:31:58 -0700379bool InputDispatcher::runCommandsLockedInterruptible() {
380 if (mCommandQueue.isEmpty()) {
381 return false;
382 }
Jeff Browne839a582010-04-22 18:58:52 -0700383
Jeff Brown54bc2812010-06-15 01:31:58 -0700384 do {
385 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
386
387 Command command = commandEntry->command;
388 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
389
Jeff Brown51d45a72010-06-17 20:52:56 -0700390 commandEntry->connection.clear();
Jeff Brown54bc2812010-06-15 01:31:58 -0700391 mAllocator.releaseCommandEntry(commandEntry);
392 } while (! mCommandQueue.isEmpty());
393 return true;
Jeff Browne839a582010-04-22 18:58:52 -0700394}
395
Jeff Brown54bc2812010-06-15 01:31:58 -0700396InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
397 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
398 mCommandQueue.enqueueAtTail(commandEntry);
399 return commandEntry;
400}
401
Jeff Browna665ca82010-09-08 11:49:43 -0700402void InputDispatcher::drainInboundQueueLocked() {
403 while (! mInboundQueue.isEmpty()) {
404 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brownd8816c32010-09-16 14:07:33 -0700405 releaseInboundEventLocked(entry);
Jeff Browne839a582010-04-22 18:58:52 -0700406 }
Jeff Browne839a582010-04-22 18:58:52 -0700407}
408
Jeff Brownd8816c32010-09-16 14:07:33 -0700409void InputDispatcher::releasePendingEventLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700410 if (mPendingEvent) {
Jeff Brownd8816c32010-09-16 14:07:33 -0700411 releaseInboundEventLocked(mPendingEvent);
Jeff Browna665ca82010-09-08 11:49:43 -0700412 mPendingEvent = NULL;
413 }
414}
415
Jeff Brownd8816c32010-09-16 14:07:33 -0700416void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
417 if (entry->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Browna665ca82010-09-08 11:49:43 -0700418#if DEBUG_DISPATCH_CYCLE
Jeff Brownd8816c32010-09-16 14:07:33 -0700419 LOGD("Inbound event was dropped. Setting injection result to failed.");
Jeff Browna665ca82010-09-08 11:49:43 -0700420#endif
421 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
422 }
423 mAllocator.releaseEventEntry(entry);
424}
425
426bool InputDispatcher::isEventFromReliableSourceLocked(EventEntry* entry) {
427 return ! entry->isInjected()
428 || entry->injectorUid == 0
429 || mPolicy->checkInjectEventsPermissionNonReentrant(
430 entry->injectorPid, entry->injectorUid);
431}
432
433void InputDispatcher::resetKeyRepeatLocked() {
434 if (mKeyRepeatState.lastKeyEntry) {
435 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
436 mKeyRepeatState.lastKeyEntry = NULL;
437 }
438}
439
440InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brown61ce3982010-09-07 10:44:57 -0700441 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown50de30a2010-06-22 01:27:15 -0700442 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
443
Jeff Brown50de30a2010-06-22 01:27:15 -0700444 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown51d45a72010-06-17 20:52:56 -0700445 uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK;
Jeff Browne839a582010-04-22 18:58:52 -0700446 if (entry->refCount == 1) {
Jeff Browna665ca82010-09-08 11:49:43 -0700447 entry->recycle();
Jeff Brown51d45a72010-06-17 20:52:56 -0700448 entry->eventTime = currentTime;
Jeff Brown51d45a72010-06-17 20:52:56 -0700449 entry->policyFlags = policyFlags;
Jeff Browne839a582010-04-22 18:58:52 -0700450 entry->repeatCount += 1;
451 } else {
Jeff Brown51d45a72010-06-17 20:52:56 -0700452 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700453 entry->deviceId, entry->source, policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700454 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brownf16c26d2010-07-02 15:37:36 -0700455 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Browne839a582010-04-22 18:58:52 -0700456
457 mKeyRepeatState.lastKeyEntry = newEntry;
458 mAllocator.releaseKeyEntry(entry);
459
460 entry = newEntry;
461 }
Jeff Browna665ca82010-09-08 11:49:43 -0700462 entry->syntheticRepeat = true;
463
464 // Increment reference count since we keep a reference to the event in
465 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
466 entry->refCount += 1;
Jeff Browne839a582010-04-22 18:58:52 -0700467
Jeff Brownf16c26d2010-07-02 15:37:36 -0700468 if (entry->repeatCount == 1) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700469 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brownf16c26d2010-07-02 15:37:36 -0700470 }
471
Jeff Brown61ce3982010-09-07 10:44:57 -0700472 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Browna665ca82010-09-08 11:49:43 -0700473 return entry;
Jeff Browne839a582010-04-22 18:58:52 -0700474}
475
Jeff Browna665ca82010-09-08 11:49:43 -0700476bool InputDispatcher::dispatchConfigurationChangedLocked(
477 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Browne839a582010-04-22 18:58:52 -0700478#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Browna665ca82010-09-08 11:49:43 -0700479 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
480#endif
481
482 // Reset key repeating in case a keyboard device was added or removed or something.
483 resetKeyRepeatLocked();
484
485 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
486 CommandEntry* commandEntry = postCommandLocked(
487 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
488 commandEntry->eventTime = entry->eventTime;
489 return true;
490}
491
492bool InputDispatcher::dispatchKeyLocked(
493 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brownd8816c32010-09-16 14:07:33 -0700494 bool dropEvent, nsecs_t* nextWakeupTime) {
495 // Give the policy a chance to intercept the key.
496 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
497 bool trusted;
498 if (! dropEvent && mFocusedWindow) {
499 trusted = checkInjectionPermission(mFocusedWindow,
500 entry->injectorPid, entry->injectorUid);
501 } else {
502 trusted = isEventFromReliableSourceLocked(entry);
503 }
504 if (trusted) {
505 CommandEntry* commandEntry = postCommandLocked(
506 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
507 if (! dropEvent && mFocusedWindow) {
508 commandEntry->inputChannel = mFocusedWindow->inputChannel;
509 }
510 commandEntry->keyEntry = entry;
511 entry->refCount += 1;
512 return false; // wait for the command to run
513 } else {
514 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
515 }
516 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
517 resetTargetsLocked();
518 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
519 return true;
520 }
521
522 // Clean up if dropping the event.
523 if (dropEvent) {
524 resetTargetsLocked();
525 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
526 return true;
527 }
528
Jeff Browna665ca82010-09-08 11:49:43 -0700529 // Preprocessing.
530 if (! entry->dispatchInProgress) {
531 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
532
533 if (entry->repeatCount == 0
534 && entry->action == AKEY_EVENT_ACTION_DOWN
535 && ! entry->isInjected()) {
536 if (mKeyRepeatState.lastKeyEntry
537 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
538 // We have seen two identical key downs in a row which indicates that the device
539 // driver is automatically generating key repeats itself. We take note of the
540 // repeat here, but we disable our own next key repeat timer since it is clear that
541 // we will not need to synthesize key repeats ourselves.
542 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
543 resetKeyRepeatLocked();
544 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
545 } else {
546 // Not a repeat. Save key down state in case we do see a repeat later.
547 resetKeyRepeatLocked();
548 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
549 }
550 mKeyRepeatState.lastKeyEntry = entry;
551 entry->refCount += 1;
552 } else if (! entry->syntheticRepeat) {
553 resetKeyRepeatLocked();
554 }
555
556 entry->dispatchInProgress = true;
Jeff Brownd8816c32010-09-16 14:07:33 -0700557 resetTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700558 }
559
560 // Identify targets.
561 if (! mCurrentInputTargetsValid) {
562 InputWindow* window = NULL;
563 int32_t injectionResult = findFocusedWindowLocked(currentTime,
564 entry, nextWakeupTime, & window);
565 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
566 return false;
567 }
568
569 setInjectionResultLocked(entry, injectionResult);
570 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
571 return true;
572 }
573
574 addMonitoringTargetsLocked();
Jeff Brownd8816c32010-09-16 14:07:33 -0700575 commitTargetsLocked(window);
Jeff Browna665ca82010-09-08 11:49:43 -0700576 }
577
578 // Dispatch the key.
579 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
580
581 // Poke user activity.
582 pokeUserActivityLocked(entry->eventTime, mCurrentInputWindowType, POWER_MANAGER_BUTTON_EVENT);
583 return true;
584}
585
586void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
587#if DEBUG_OUTBOUND_EVENT_DETAILS
588 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
589 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
590 "downTime=%lld",
591 prefix,
592 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
593 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
594 entry->downTime);
595#endif
596}
597
598bool InputDispatcher::dispatchMotionLocked(
Jeff Brownd8816c32010-09-16 14:07:33 -0700599 nsecs_t currentTime, MotionEntry* entry, bool dropEvent, nsecs_t* nextWakeupTime) {
600 // Clean up if dropping the event.
601 if (dropEvent) {
602 resetTargetsLocked();
603 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
604 return true;
605 }
606
Jeff Browna665ca82010-09-08 11:49:43 -0700607 // Preprocessing.
608 if (! entry->dispatchInProgress) {
609 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
610
611 entry->dispatchInProgress = true;
Jeff Brownd8816c32010-09-16 14:07:33 -0700612 resetTargetsLocked();
Jeff Browna665ca82010-09-08 11:49:43 -0700613 }
614
615 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
616
617 // Identify targets.
618 if (! mCurrentInputTargetsValid) {
619 InputWindow* window = NULL;
620 int32_t injectionResult;
621 if (isPointerEvent) {
622 // Pointer event. (eg. touchscreen)
623 injectionResult = findTouchedWindowLocked(currentTime,
624 entry, nextWakeupTime, & window);
625 } else {
626 // Non touch event. (eg. trackball)
627 injectionResult = findFocusedWindowLocked(currentTime,
628 entry, nextWakeupTime, & window);
629 }
630 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
631 return false;
632 }
633
634 setInjectionResultLocked(entry, injectionResult);
635 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
636 return true;
637 }
638
639 addMonitoringTargetsLocked();
Jeff Brownd8816c32010-09-16 14:07:33 -0700640 commitTargetsLocked(window);
Jeff Browna665ca82010-09-08 11:49:43 -0700641 }
642
643 // Dispatch the motion.
644 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
645
646 // Poke user activity.
647 int32_t eventType;
648 if (isPointerEvent) {
649 switch (entry->action) {
650 case AMOTION_EVENT_ACTION_DOWN:
651 eventType = POWER_MANAGER_TOUCH_EVENT;
652 break;
653 case AMOTION_EVENT_ACTION_UP:
654 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
655 break;
656 default:
657 if (entry->eventTime - entry->downTime >= EVENT_IGNORE_DURATION) {
658 eventType = POWER_MANAGER_TOUCH_EVENT;
659 } else {
660 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
661 }
662 break;
663 }
664 } else {
665 eventType = POWER_MANAGER_BUTTON_EVENT;
666 }
667 pokeUserActivityLocked(entry->eventTime, mCurrentInputWindowType, eventType);
668 return true;
669}
670
671
672void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
673#if DEBUG_OUTBOUND_EVENT_DETAILS
674 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700675 "action=0x%x, flags=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700676 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Browna665ca82010-09-08 11:49:43 -0700677 prefix,
Jeff Brownaf30ff62010-09-01 17:01:00 -0700678 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
679 entry->action, entry->flags,
Jeff Browne839a582010-04-22 18:58:52 -0700680 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
681 entry->downTime);
682
683 // Print the most recent sample that we have available, this may change due to batching.
684 size_t sampleCount = 1;
Jeff Browna665ca82010-09-08 11:49:43 -0700685 const MotionSample* sample = & entry->firstSample;
Jeff Browne839a582010-04-22 18:58:52 -0700686 for (; sample->next != NULL; sample = sample->next) {
687 sampleCount += 1;
688 }
689 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -0700690 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -0700691 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -0700692 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -0700693 i, entry->pointerIds[i],
Jeff Brown38a7fab2010-08-30 03:02:23 -0700694 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
695 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
696 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
697 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
698 sample->pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -0700699 }
700
701 // Keep in mind that due to batching, it is possible for the number of samples actually
702 // dispatched to change before the application finally consumed them.
Jeff Brown5c1ed842010-07-14 18:48:53 -0700703 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -0700704 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
705 }
706#endif
Jeff Browne839a582010-04-22 18:58:52 -0700707}
708
709void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
710 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
711#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700712 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700713 "resumeWithAppendedMotionSample=%s",
Jeff Browna665ca82010-09-08 11:49:43 -0700714 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -0700715#endif
716
Jeff Brown54bc2812010-06-15 01:31:58 -0700717 assert(eventEntry->dispatchInProgress); // should already have been set to true
718
Jeff Browne839a582010-04-22 18:58:52 -0700719 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
720 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
721
Jeff Brown53a415e2010-09-15 15:18:56 -0700722 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -0700723 if (connectionIndex >= 0) {
724 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown51d45a72010-06-17 20:52:56 -0700725 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -0700726 resumeWithAppendedMotionSample);
727 } else {
728 LOGW("Framework requested delivery of an input event to channel '%s' but it "
729 "is not registered with the input dispatcher.",
730 inputTarget.inputChannel->getName().string());
731 }
732 }
733}
734
Jeff Brownd8816c32010-09-16 14:07:33 -0700735void InputDispatcher::resetTargetsLocked() {
Jeff Browna665ca82010-09-08 11:49:43 -0700736 mCurrentInputTargetsValid = false;
737 mCurrentInputTargets.clear();
738 mCurrentInputChannel.clear();
739 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
740}
741
Jeff Brownd8816c32010-09-16 14:07:33 -0700742void InputDispatcher::commitTargetsLocked(const InputWindow* window) {
Jeff Browna665ca82010-09-08 11:49:43 -0700743 mCurrentInputWindowType = window->layoutParamsType;
744 mCurrentInputChannel = window->inputChannel;
745 mCurrentInputTargetsValid = true;
746}
747
748int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
749 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
750 nsecs_t* nextWakeupTime) {
751 if (application == NULL && window == NULL) {
752 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
753#if DEBUG_FOCUS
754 LOGD("Waiting for system to become ready for input.");
755#endif
756 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
757 mInputTargetWaitStartTime = currentTime;
758 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
759 mInputTargetWaitTimeoutExpired = false;
760 }
761 } else {
762 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
763#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700764 LOGD("Waiting for application to become ready for input: %s",
765 getApplicationWindowLabelLocked(application, window).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700766#endif
767 nsecs_t timeout = window ? window->dispatchingTimeout :
768 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
769
770 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
771 mInputTargetWaitStartTime = currentTime;
772 mInputTargetWaitTimeoutTime = currentTime + timeout;
773 mInputTargetWaitTimeoutExpired = false;
774 }
775 }
776
777 if (mInputTargetWaitTimeoutExpired) {
778 return INPUT_EVENT_INJECTION_TIMED_OUT;
779 }
780
781 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown53a415e2010-09-15 15:18:56 -0700782 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Browna665ca82010-09-08 11:49:43 -0700783
784 // Force poll loop to wake up immediately on next iteration once we get the
785 // ANR response back from the policy.
786 *nextWakeupTime = LONG_LONG_MIN;
787 return INPUT_EVENT_INJECTION_PENDING;
788 } else {
789 // Force poll loop to wake up when timeout is due.
790 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
791 *nextWakeupTime = mInputTargetWaitTimeoutTime;
792 }
793 return INPUT_EVENT_INJECTION_PENDING;
794 }
795}
796
Jeff Brown53a415e2010-09-15 15:18:56 -0700797void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
798 const sp<InputChannel>& inputChannel) {
Jeff Browna665ca82010-09-08 11:49:43 -0700799 if (newTimeout > 0) {
800 // Extend the timeout.
801 mInputTargetWaitTimeoutTime = now() + newTimeout;
802 } else {
803 // Give up.
804 mInputTargetWaitTimeoutExpired = true;
Jeff Brown53a415e2010-09-15 15:18:56 -0700805
Jeff Brown405a1d32010-09-16 12:31:46 -0700806 // Release the touch target.
807 releaseTouchedWindowLocked();
808
Jeff Brown53a415e2010-09-15 15:18:56 -0700809 // Input state will not be realistic. Mark it out of sync.
Jeff Brown40ad4702010-09-16 11:02:16 -0700810 if (inputChannel.get()) {
811 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
812 if (connectionIndex >= 0) {
813 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
814 connection->inputState.setOutOfSync();
815 }
Jeff Brown53a415e2010-09-15 15:18:56 -0700816 }
Jeff Browna665ca82010-09-08 11:49:43 -0700817 }
818}
819
Jeff Brown53a415e2010-09-15 15:18:56 -0700820nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Browna665ca82010-09-08 11:49:43 -0700821 nsecs_t currentTime) {
822 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
823 return currentTime - mInputTargetWaitStartTime;
824 }
825 return 0;
826}
827
828void InputDispatcher::resetANRTimeoutsLocked() {
829#if DEBUG_FOCUS
830 LOGD("Resetting ANR timeouts.");
831#endif
832
Jeff Browna665ca82010-09-08 11:49:43 -0700833 // Reset input target wait timeout.
834 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
835}
836
837int32_t InputDispatcher::findFocusedWindowLocked(nsecs_t currentTime, const EventEntry* entry,
838 nsecs_t* nextWakeupTime, InputWindow** outWindow) {
839 *outWindow = NULL;
840 mCurrentInputTargets.clear();
841
842 int32_t injectionResult;
843
844 // If there is no currently focused window and no focused application
845 // then drop the event.
846 if (! mFocusedWindow) {
847 if (mFocusedApplication) {
848#if DEBUG_FOCUS
849 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -0700850 "focused application that may eventually add a window: %s.",
851 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -0700852#endif
853 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
854 mFocusedApplication, NULL, nextWakeupTime);
855 goto Unresponsive;
856 }
857
858 LOGI("Dropping event because there is no focused window or focused application.");
859 injectionResult = INPUT_EVENT_INJECTION_FAILED;
860 goto Failed;
861 }
862
863 // Check permissions.
864 if (! checkInjectionPermission(mFocusedWindow, entry->injectorPid, entry->injectorUid)) {
865 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
866 goto Failed;
867 }
868
869 // If the currently focused window is paused then keep waiting.
870 if (mFocusedWindow->paused) {
871#if DEBUG_FOCUS
872 LOGD("Waiting because focused window is paused.");
873#endif
874 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
875 mFocusedApplication, mFocusedWindow, nextWakeupTime);
876 goto Unresponsive;
877 }
878
Jeff Brown53a415e2010-09-15 15:18:56 -0700879 // If the currently focused window is still working on previous events then keep waiting.
880 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
881#if DEBUG_FOCUS
882 LOGD("Waiting because focused window still processing previous input.");
883#endif
884 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
885 mFocusedApplication, mFocusedWindow, nextWakeupTime);
886 goto Unresponsive;
887 }
888
Jeff Browna665ca82010-09-08 11:49:43 -0700889 // Success! Output targets.
890 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
891 *outWindow = mFocusedWindow;
Jeff Brown53a415e2010-09-15 15:18:56 -0700892 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND);
Jeff Browna665ca82010-09-08 11:49:43 -0700893
894 // Done.
895Failed:
896Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -0700897 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
898 updateDispatchStatisticsLocked(currentTime, entry,
899 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -0700900#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -0700901 LOGD("findFocusedWindow finished: injectionResult=%d, "
902 "timeSpendWaitingForApplication=%0.1fms",
903 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -0700904#endif
905 return injectionResult;
906}
907
908int32_t InputDispatcher::findTouchedWindowLocked(nsecs_t currentTime, const MotionEntry* entry,
909 nsecs_t* nextWakeupTime, InputWindow** outWindow) {
910 enum InjectionPermission {
911 INJECTION_PERMISSION_UNKNOWN,
912 INJECTION_PERMISSION_GRANTED,
913 INJECTION_PERMISSION_DENIED
914 };
915
916 *outWindow = NULL;
917 mCurrentInputTargets.clear();
918
919 nsecs_t startTime = now();
920
921 // For security reasons, we defer updating the touch state until we are sure that
922 // event injection will be allowed.
923 //
924 // FIXME In the original code, screenWasOff could never be set to true.
925 // The reason is that the POLICY_FLAG_WOKE_HERE
926 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
927 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
928 // actually enqueued using the policyFlags that appeared in the final EV_SYN
929 // events upon which no preprocessing took place. So policyFlags was always 0.
930 // In the new native input dispatcher we're a bit more careful about event
931 // preprocessing so the touches we receive can actually have non-zero policyFlags.
932 // Unfortunately we obtain undesirable behavior.
933 //
934 // Here's what happens:
935 //
936 // When the device dims in anticipation of going to sleep, touches
937 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
938 // the device to brighten and reset the user activity timer.
939 // Touches on other windows (such as the launcher window)
940 // are dropped. Then after a moment, the device goes to sleep. Oops.
941 //
942 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
943 // instead of POLICY_FLAG_WOKE_HERE...
944 //
945 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
946
947 int32_t action = entry->action;
948
949 // Update the touch state as needed based on the properties of the touch event.
950 int32_t injectionResult;
951 InjectionPermission injectionPermission;
952 if (action == AMOTION_EVENT_ACTION_DOWN) {
953 /* Case 1: ACTION_DOWN */
954
955 InputWindow* newTouchedWindow = NULL;
956 mTempTouchedOutsideTargets.clear();
957
958 int32_t x = int32_t(entry->firstSample.pointerCoords[0].x);
959 int32_t y = int32_t(entry->firstSample.pointerCoords[0].y);
960 InputWindow* topErrorWindow = NULL;
961 bool obscured = false;
962
963 // Traverse windows from front to back to find touched window and outside targets.
964 size_t numWindows = mWindows.size();
965 for (size_t i = 0; i < numWindows; i++) {
966 InputWindow* window = & mWindows.editItemAt(i);
967 int32_t flags = window->layoutParamsFlags;
968
969 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
970 if (! topErrorWindow) {
971 topErrorWindow = window;
972 }
973 }
974
975 if (window->visible) {
976 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
977 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
978 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
979 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
980 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
981 newTouchedWindow = window;
982 obscured = isWindowObscuredLocked(window);
983 }
984 break; // found touched window, exit window loop
985 }
986 }
987
988 if (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH) {
989 OutsideTarget outsideTarget;
990 outsideTarget.window = window;
991 outsideTarget.obscured = isWindowObscuredLocked(window);
992 mTempTouchedOutsideTargets.push(outsideTarget);
993 }
994 }
995 }
996
997 // If there is an error window but it is not taking focus (typically because
998 // it is invisible) then wait for it. Any other focused window may in
999 // fact be in ANR state.
1000 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1001#if DEBUG_FOCUS
1002 LOGD("Waiting because system error window is pending.");
1003#endif
1004 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1005 NULL, NULL, nextWakeupTime);
1006 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1007 goto Unresponsive;
1008 }
1009
1010 // If we did not find a touched window then fail.
1011 if (! newTouchedWindow) {
1012 if (mFocusedApplication) {
1013#if DEBUG_FOCUS
1014 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown53a415e2010-09-15 15:18:56 -07001015 "focused application that may eventually add a new window: %s.",
1016 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Browna665ca82010-09-08 11:49:43 -07001017#endif
1018 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1019 mFocusedApplication, NULL, nextWakeupTime);
1020 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1021 goto Unresponsive;
1022 }
1023
1024 LOGI("Dropping event because there is no touched window or focused application.");
1025 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1026 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1027 goto Failed;
1028 }
1029
1030 // Check permissions.
1031 if (! checkInjectionPermission(newTouchedWindow, entry->injectorPid, entry->injectorUid)) {
1032 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1033 injectionPermission = INJECTION_PERMISSION_DENIED;
1034 goto Failed;
1035 }
1036
1037 // If the touched window is paused then keep waiting.
1038 if (newTouchedWindow->paused) {
1039#if DEBUG_INPUT_DISPATCHER_POLICY
1040 LOGD("Waiting because touched window is paused.");
1041#endif
1042 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1043 NULL, newTouchedWindow, nextWakeupTime);
1044 injectionPermission = INJECTION_PERMISSION_GRANTED;
1045 goto Unresponsive;
1046 }
1047
Jeff Brown53a415e2010-09-15 15:18:56 -07001048 // If the touched window is still working on previous events then keep waiting.
1049 if (! isWindowFinishedWithPreviousInputLocked(newTouchedWindow)) {
1050#if DEBUG_FOCUS
1051 LOGD("Waiting because touched window still processing previous input.");
1052#endif
1053 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1054 NULL, newTouchedWindow, nextWakeupTime);
1055 injectionPermission = INJECTION_PERMISSION_GRANTED;
1056 goto Unresponsive;
1057 }
1058
Jeff Browna665ca82010-09-08 11:49:43 -07001059 // Success! Update the touch dispatch state for real.
1060 releaseTouchedWindowLocked();
1061
1062 mTouchedWindow = newTouchedWindow;
1063 mTouchedWindowIsObscured = obscured;
1064
1065 if (newTouchedWindow->hasWallpaper) {
1066 mTouchedWallpaperWindows.appendVector(mWallpaperWindows);
1067 }
1068 } else {
1069 /* Case 2: Everything but ACTION_DOWN */
1070
1071 // Check permissions.
1072 if (! checkInjectionPermission(mTouchedWindow, entry->injectorPid, entry->injectorUid)) {
1073 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1074 injectionPermission = INJECTION_PERMISSION_DENIED;
1075 goto Failed;
1076 }
1077
1078 // If the pointer is not currently down, then ignore the event.
1079 if (! mTouchDown) {
1080 LOGI("Dropping event because the pointer is not down.");
1081 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1082 injectionPermission = INJECTION_PERMISSION_GRANTED;
1083 goto Failed;
1084 }
1085
1086 // If there is no currently touched window then fail.
1087 if (! mTouchedWindow) {
1088#if DEBUG_INPUT_DISPATCHER_POLICY
1089 LOGD("Dropping event because there is no touched window to receive it.");
1090#endif
1091 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1092 injectionPermission = INJECTION_PERMISSION_GRANTED;
1093 goto Failed;
1094 }
1095
1096 // If the touched window is paused then keep waiting.
1097 if (mTouchedWindow->paused) {
1098#if DEBUG_INPUT_DISPATCHER_POLICY
1099 LOGD("Waiting because touched window is paused.");
1100#endif
1101 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1102 NULL, mTouchedWindow, nextWakeupTime);
1103 injectionPermission = INJECTION_PERMISSION_GRANTED;
1104 goto Unresponsive;
1105 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001106
1107 // If the touched window is still working on previous events then keep waiting.
1108 if (! isWindowFinishedWithPreviousInputLocked(mTouchedWindow)) {
1109#if DEBUG_FOCUS
1110 LOGD("Waiting because touched window still processing previous input.");
1111#endif
1112 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1113 NULL, mTouchedWindow, nextWakeupTime);
1114 injectionPermission = INJECTION_PERMISSION_GRANTED;
1115 goto Unresponsive;
1116 }
Jeff Browna665ca82010-09-08 11:49:43 -07001117 }
1118
1119 // Success! Output targets.
1120 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1121 injectionPermission = INJECTION_PERMISSION_GRANTED;
1122
1123 {
1124 size_t numWallpaperWindows = mTouchedWallpaperWindows.size();
1125 for (size_t i = 0; i < numWallpaperWindows; i++) {
1126 addWindowTargetLocked(mTouchedWallpaperWindows[i],
Jeff Brown53a415e2010-09-15 15:18:56 -07001127 InputTarget::FLAG_WINDOW_IS_OBSCURED);
Jeff Browna665ca82010-09-08 11:49:43 -07001128 }
1129
1130 size_t numOutsideTargets = mTempTouchedOutsideTargets.size();
1131 for (size_t i = 0; i < numOutsideTargets; i++) {
1132 const OutsideTarget& outsideTarget = mTempTouchedOutsideTargets[i];
1133 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1134 if (outsideTarget.obscured) {
1135 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1136 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001137 addWindowTargetLocked(outsideTarget.window, outsideTargetFlags);
Jeff Browna665ca82010-09-08 11:49:43 -07001138 }
1139 mTempTouchedOutsideTargets.clear();
1140
Jeff Brown53a415e2010-09-15 15:18:56 -07001141 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
Jeff Browna665ca82010-09-08 11:49:43 -07001142 if (mTouchedWindowIsObscured) {
1143 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1144 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001145 addWindowTargetLocked(mTouchedWindow, targetFlags);
Jeff Browna665ca82010-09-08 11:49:43 -07001146 *outWindow = mTouchedWindow;
1147 }
1148
1149Failed:
1150 // Check injection permission once and for all.
1151 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
1152 if (checkInjectionPermission(action == AMOTION_EVENT_ACTION_DOWN ? NULL : mTouchedWindow,
1153 entry->injectorPid, entry->injectorUid)) {
1154 injectionPermission = INJECTION_PERMISSION_GRANTED;
1155 } else {
1156 injectionPermission = INJECTION_PERMISSION_DENIED;
1157 }
1158 }
1159
1160 // Update final pieces of touch state if the injector had permission.
1161 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1162 if (action == AMOTION_EVENT_ACTION_DOWN) {
1163 if (mTouchDown) {
1164 // This is weird. We got a down but we thought it was already down!
1165 LOGW("Pointer down received while already down.");
1166 } else {
1167 mTouchDown = true;
1168 }
1169
1170 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
1171 // Since we failed to identify a target for this touch down, we may still
1172 // be holding on to an earlier target from a previous touch down. Release it.
1173 releaseTouchedWindowLocked();
1174 }
1175 } else if (action == AMOTION_EVENT_ACTION_UP) {
1176 mTouchDown = false;
1177 releaseTouchedWindowLocked();
1178 }
1179 } else {
1180 LOGW("Not updating touch focus because injection was denied.");
1181 }
1182
1183Unresponsive:
Jeff Brown53a415e2010-09-15 15:18:56 -07001184 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1185 updateDispatchStatisticsLocked(currentTime, entry,
1186 injectionResult, timeSpentWaitingForApplication);
Jeff Browna665ca82010-09-08 11:49:43 -07001187#if DEBUG_FOCUS
Jeff Brown53a415e2010-09-15 15:18:56 -07001188 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d,"
1189 "timeSpendWaitingForApplication=%0.1fms",
1190 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Browna665ca82010-09-08 11:49:43 -07001191#endif
1192 return injectionResult;
1193}
1194
1195void InputDispatcher::releaseTouchedWindowLocked() {
1196 mTouchedWindow = NULL;
1197 mTouchedWindowIsObscured = false;
1198 mTouchedWallpaperWindows.clear();
1199}
1200
Jeff Brown53a415e2010-09-15 15:18:56 -07001201void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags) {
Jeff Browna665ca82010-09-08 11:49:43 -07001202 mCurrentInputTargets.push();
1203
1204 InputTarget& target = mCurrentInputTargets.editTop();
1205 target.inputChannel = window->inputChannel;
1206 target.flags = targetFlags;
Jeff Browna665ca82010-09-08 11:49:43 -07001207 target.xOffset = - window->frameLeft;
1208 target.yOffset = - window->frameTop;
1209}
1210
1211void InputDispatcher::addMonitoringTargetsLocked() {
1212 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1213 mCurrentInputTargets.push();
1214
1215 InputTarget& target = mCurrentInputTargets.editTop();
1216 target.inputChannel = mMonitoringChannels[i];
1217 target.flags = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07001218 target.xOffset = 0;
1219 target.yOffset = 0;
1220 }
1221}
1222
1223bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
1224 int32_t injectorPid, int32_t injectorUid) {
1225 if (injectorUid > 0 && (window == NULL || window->ownerUid != injectorUid)) {
1226 bool result = mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
1227 if (! result) {
1228 if (window) {
1229 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1230 "with input channel %s owned by uid %d",
1231 injectorPid, injectorUid, window->inputChannel->getName().string(),
1232 window->ownerUid);
1233 } else {
1234 LOGW("Permission denied: injecting event from pid %d uid %d",
1235 injectorPid, injectorUid);
1236 }
1237 return false;
1238 }
1239 }
1240 return true;
1241}
1242
1243bool InputDispatcher::isWindowObscuredLocked(const InputWindow* window) {
1244 size_t numWindows = mWindows.size();
1245 for (size_t i = 0; i < numWindows; i++) {
1246 const InputWindow* other = & mWindows.itemAt(i);
1247 if (other == window) {
1248 break;
1249 }
1250 if (other->visible && window->visibleFrameIntersects(other)) {
1251 return true;
1252 }
1253 }
1254 return false;
1255}
1256
Jeff Brown53a415e2010-09-15 15:18:56 -07001257bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1258 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1259 if (connectionIndex >= 0) {
1260 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1261 return connection->outboundQueue.isEmpty();
1262 } else {
1263 return true;
1264 }
1265}
1266
1267String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1268 const InputWindow* window) {
1269 if (application) {
1270 if (window) {
1271 String8 label(application->name);
1272 label.append(" - ");
1273 label.append(window->name);
1274 return label;
1275 } else {
1276 return application->name;
1277 }
1278 } else if (window) {
1279 return window->name;
1280 } else {
1281 return String8("<unknown application or window>");
1282 }
1283}
1284
Jeff Browna665ca82010-09-08 11:49:43 -07001285void InputDispatcher::pokeUserActivityLocked(nsecs_t eventTime,
1286 int32_t windowType, int32_t eventType) {
1287 CommandEntry* commandEntry = postCommandLocked(
1288 & InputDispatcher::doPokeUserActivityLockedInterruptible);
1289 commandEntry->eventTime = eventTime;
1290 commandEntry->windowType = windowType;
1291 commandEntry->userActivityEventType = eventType;
1292}
1293
Jeff Brown51d45a72010-06-17 20:52:56 -07001294void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1295 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -07001296 bool resumeWithAppendedMotionSample) {
1297#if DEBUG_DISPATCH_CYCLE
Jeff Brown53a415e2010-09-15 15:18:56 -07001298 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Browne839a582010-04-22 18:58:52 -07001299 "xOffset=%f, yOffset=%f, resumeWithAppendedMotionSample=%s",
Jeff Brown53a415e2010-09-15 15:18:56 -07001300 connection->getInputChannelName(), inputTarget->flags,
Jeff Browne839a582010-04-22 18:58:52 -07001301 inputTarget->xOffset, inputTarget->yOffset,
Jeff Browna665ca82010-09-08 11:49:43 -07001302 toString(resumeWithAppendedMotionSample));
Jeff Browne839a582010-04-22 18:58:52 -07001303#endif
1304
1305 // Skip this event if the connection status is not normal.
Jeff Brown53a415e2010-09-15 15:18:56 -07001306 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Browne839a582010-04-22 18:58:52 -07001307 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Browna665ca82010-09-08 11:49:43 -07001308 LOGW("channel '%s' ~ Dropping event because the channel status is %s",
1309 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Browne839a582010-04-22 18:58:52 -07001310 return;
1311 }
1312
1313 // Resume the dispatch cycle with a freshly appended motion sample.
1314 // First we check that the last dispatch entry in the outbound queue is for the same
1315 // motion event to which we appended the motion sample. If we find such a dispatch
1316 // entry, and if it is currently in progress then we try to stream the new sample.
1317 bool wasEmpty = connection->outboundQueue.isEmpty();
1318
1319 if (! wasEmpty && resumeWithAppendedMotionSample) {
1320 DispatchEntry* motionEventDispatchEntry =
1321 connection->findQueuedDispatchEntryForEvent(eventEntry);
1322 if (motionEventDispatchEntry) {
1323 // If the dispatch entry is not in progress, then we must be busy dispatching an
1324 // earlier event. Not a problem, the motion event is on the outbound queue and will
1325 // be dispatched later.
1326 if (! motionEventDispatchEntry->inProgress) {
1327#if DEBUG_BATCHING
1328 LOGD("channel '%s' ~ Not streaming because the motion event has "
1329 "not yet been dispatched. "
1330 "(Waiting for earlier events to be consumed.)",
1331 connection->getInputChannelName());
1332#endif
1333 return;
1334 }
1335
1336 // If the dispatch entry is in progress but it already has a tail of pending
1337 // motion samples, then it must mean that the shared memory buffer filled up.
1338 // Not a problem, when this dispatch cycle is finished, we will eventually start
1339 // a new dispatch cycle to process the tail and that tail includes the newly
1340 // appended motion sample.
1341 if (motionEventDispatchEntry->tailMotionSample) {
1342#if DEBUG_BATCHING
1343 LOGD("channel '%s' ~ Not streaming because no new samples can "
1344 "be appended to the motion event in this dispatch cycle. "
1345 "(Waiting for next dispatch cycle to start.)",
1346 connection->getInputChannelName());
1347#endif
1348 return;
1349 }
1350
1351 // The dispatch entry is in progress and is still potentially open for streaming.
1352 // Try to stream the new motion sample. This might fail if the consumer has already
1353 // consumed the motion event (or if the channel is broken).
1354 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1355 status_t status = connection->inputPublisher.appendMotionSample(
1356 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1357 if (status == OK) {
1358#if DEBUG_BATCHING
1359 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1360 connection->getInputChannelName());
1361#endif
1362 return;
1363 }
1364
1365#if DEBUG_BATCHING
1366 if (status == NO_MEMORY) {
1367 LOGD("channel '%s' ~ Could not append motion sample to currently "
1368 "dispatched move event because the shared memory buffer is full. "
1369 "(Waiting for next dispatch cycle to start.)",
1370 connection->getInputChannelName());
1371 } else if (status == status_t(FAILED_TRANSACTION)) {
1372 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown50de30a2010-06-22 01:27:15 -07001373 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-04-22 18:58:52 -07001374 "(Waiting for next dispatch cycle to start.)",
1375 connection->getInputChannelName());
1376 } else {
1377 LOGD("channel '%s' ~ Could not append motion sample to currently "
1378 "dispatched move event due to an error, status=%d. "
1379 "(Waiting for next dispatch cycle to start.)",
1380 connection->getInputChannelName(), status);
1381 }
1382#endif
1383 // Failed to stream. Start a new tail of pending motion samples to dispatch
1384 // in the next cycle.
1385 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1386 return;
1387 }
1388 }
1389
Jeff Browna665ca82010-09-08 11:49:43 -07001390 // Bring the input state back in line with reality in case it drifted off during an ANR.
1391 if (connection->inputState.isOutOfSync()) {
1392 mTempCancelationEvents.clear();
1393 connection->inputState.synthesizeCancelationEvents(& mAllocator, mTempCancelationEvents);
1394 connection->inputState.resetOutOfSync();
1395
1396 if (! mTempCancelationEvents.isEmpty()) {
1397 LOGI("channel '%s' ~ Generated %d cancelation events to bring channel back in sync "
1398 "with reality.",
1399 connection->getInputChannelName(), mTempCancelationEvents.size());
1400
1401 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1402 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1403 switch (cancelationEventEntry->type) {
1404 case EventEntry::TYPE_KEY:
1405 logOutboundKeyDetailsLocked(" ",
1406 static_cast<KeyEntry*>(cancelationEventEntry));
1407 break;
1408 case EventEntry::TYPE_MOTION:
1409 logOutboundMotionDetailsLocked(" ",
1410 static_cast<MotionEntry*>(cancelationEventEntry));
1411 break;
1412 }
1413
1414 DispatchEntry* cancelationDispatchEntry =
1415 mAllocator.obtainDispatchEntry(cancelationEventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07001416 0, inputTarget->xOffset, inputTarget->yOffset); // increments ref
Jeff Browna665ca82010-09-08 11:49:43 -07001417 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1418
1419 mAllocator.releaseEventEntry(cancelationEventEntry);
1420 }
1421 }
1422 }
1423
Jeff Browne839a582010-04-22 18:58:52 -07001424 // This is a new event.
1425 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Browna665ca82010-09-08 11:49:43 -07001426 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown53a415e2010-09-15 15:18:56 -07001427 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1428 if (dispatchEntry->hasForegroundTarget()) {
1429 eventEntry->pendingForegroundDispatches += 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07001430 }
1431
Jeff Browne839a582010-04-22 18:58:52 -07001432 // Handle the case where we could not stream a new motion sample because the consumer has
1433 // already consumed the motion event (otherwise the corresponding dispatch entry would
1434 // still be in the outbound queue for this connection). We set the head motion sample
1435 // to the list starting with the newly appended motion sample.
1436 if (resumeWithAppendedMotionSample) {
1437#if DEBUG_BATCHING
1438 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1439 "that cannot be streamed because the motion event has already been consumed.",
1440 connection->getInputChannelName());
1441#endif
1442 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1443 dispatchEntry->headMotionSample = appendedMotionSample;
1444 }
1445
1446 // Enqueue the dispatch entry.
1447 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1448
1449 // If the outbound queue was previously empty, start the dispatch cycle going.
1450 if (wasEmpty) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001451 activateConnectionLocked(connection.get());
Jeff Brown53a415e2010-09-15 15:18:56 -07001452 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001453 }
1454}
1455
Jeff Brown51d45a72010-06-17 20:52:56 -07001456void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown53a415e2010-09-15 15:18:56 -07001457 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001458#if DEBUG_DISPATCH_CYCLE
1459 LOGD("channel '%s' ~ startDispatchCycle",
1460 connection->getInputChannelName());
1461#endif
1462
1463 assert(connection->status == Connection::STATUS_NORMAL);
1464 assert(! connection->outboundQueue.isEmpty());
1465
Jeff Browna665ca82010-09-08 11:49:43 -07001466 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001467 assert(! dispatchEntry->inProgress);
1468
Jeff Browna665ca82010-09-08 11:49:43 -07001469 // Mark the dispatch entry as in progress.
1470 dispatchEntry->inProgress = true;
1471
1472 // Update the connection's input state.
1473 InputState::Consistency consistency = connection->inputState.trackEvent(
1474 dispatchEntry->eventEntry);
1475
1476#if FILTER_INPUT_EVENTS
1477 // Filter out inconsistent sequences of input events.
1478 // The input system may drop or inject events in a way that could violate implicit
1479 // invariants on input state and potentially cause an application to crash
1480 // or think that a key or pointer is stuck down. Technically we make no guarantees
1481 // of consistency but it would be nice to improve on this where possible.
1482 // XXX: This code is a proof of concept only. Not ready for prime time.
1483 if (consistency == InputState::TOLERABLE) {
1484#if DEBUG_DISPATCH_CYCLE
1485 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1486 "current input state but that is likely to be tolerated by the application.",
1487 connection->getInputChannelName());
1488#endif
1489 } else if (consistency == InputState::BROKEN) {
1490 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1491 "current input state and that is likely to cause the application to crash.",
1492 connection->getInputChannelName());
1493 startNextDispatchCycleLocked(currentTime, connection);
1494 return;
1495 }
1496#endif
Jeff Browne839a582010-04-22 18:58:52 -07001497
1498 // Publish the event.
1499 status_t status;
1500 switch (dispatchEntry->eventEntry->type) {
1501 case EventEntry::TYPE_KEY: {
1502 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
1503
1504 // Apply target flags.
1505 int32_t action = keyEntry->action;
1506 int32_t flags = keyEntry->flags;
1507 if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001508 flags |= AKEY_EVENT_FLAG_CANCELED;
Jeff Browne839a582010-04-22 18:58:52 -07001509 }
1510
1511 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001512 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-04-22 18:58:52 -07001513 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1514 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1515 keyEntry->eventTime);
1516
1517 if (status) {
1518 LOGE("channel '%s' ~ Could not publish key event, "
1519 "status=%d", connection->getInputChannelName(), status);
1520 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1521 return;
1522 }
1523 break;
1524 }
1525
1526 case EventEntry::TYPE_MOTION: {
1527 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
1528
1529 // Apply target flags.
1530 int32_t action = motionEntry->action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07001531 int32_t flags = motionEntry->flags;
Jeff Browne839a582010-04-22 18:58:52 -07001532 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001533 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -07001534 }
1535 if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001536 action = AMOTION_EVENT_ACTION_CANCEL;
Jeff Browne839a582010-04-22 18:58:52 -07001537 }
Jeff Brownaf30ff62010-09-01 17:01:00 -07001538 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1539 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1540 }
Jeff Browne839a582010-04-22 18:58:52 -07001541
1542 // If headMotionSample is non-NULL, then it points to the first new sample that we
1543 // were unable to dispatch during the previous cycle so we resume dispatching from
1544 // that point in the list of motion samples.
1545 // Otherwise, we just start from the first sample of the motion event.
1546 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1547 if (! firstMotionSample) {
1548 firstMotionSample = & motionEntry->firstSample;
1549 }
1550
Jeff Brownf26db0d2010-07-16 17:21:06 -07001551 // Set the X and Y offset depending on the input source.
1552 float xOffset, yOffset;
1553 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1554 xOffset = dispatchEntry->xOffset;
1555 yOffset = dispatchEntry->yOffset;
1556 } else {
1557 xOffset = 0.0f;
1558 yOffset = 0.0f;
1559 }
1560
Jeff Browne839a582010-04-22 18:58:52 -07001561 // Publish the motion event and the first motion sample.
1562 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001563 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -07001564 xOffset, yOffset,
Jeff Browne839a582010-04-22 18:58:52 -07001565 motionEntry->xPrecision, motionEntry->yPrecision,
1566 motionEntry->downTime, firstMotionSample->eventTime,
1567 motionEntry->pointerCount, motionEntry->pointerIds,
1568 firstMotionSample->pointerCoords);
1569
1570 if (status) {
1571 LOGE("channel '%s' ~ Could not publish motion event, "
1572 "status=%d", connection->getInputChannelName(), status);
1573 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1574 return;
1575 }
1576
1577 // Append additional motion samples.
1578 MotionSample* nextMotionSample = firstMotionSample->next;
1579 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1580 status = connection->inputPublisher.appendMotionSample(
1581 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1582 if (status == NO_MEMORY) {
1583#if DEBUG_DISPATCH_CYCLE
1584 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1585 "be sent in the next dispatch cycle.",
1586 connection->getInputChannelName());
1587#endif
1588 break;
1589 }
1590 if (status != OK) {
1591 LOGE("channel '%s' ~ Could not append motion sample "
1592 "for a reason other than out of memory, status=%d",
1593 connection->getInputChannelName(), status);
1594 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1595 return;
1596 }
1597 }
1598
1599 // Remember the next motion sample that we could not dispatch, in case we ran out
1600 // of space in the shared memory buffer.
1601 dispatchEntry->tailMotionSample = nextMotionSample;
1602 break;
1603 }
1604
1605 default: {
1606 assert(false);
1607 }
1608 }
1609
1610 // Send the dispatch signal.
1611 status = connection->inputPublisher.sendDispatchSignal();
1612 if (status) {
1613 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1614 connection->getInputChannelName(), status);
1615 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1616 return;
1617 }
1618
1619 // Record information about the newly started dispatch cycle.
Jeff Browne839a582010-04-22 18:58:52 -07001620 connection->lastEventTime = dispatchEntry->eventEntry->eventTime;
1621 connection->lastDispatchTime = currentTime;
1622
Jeff Browne839a582010-04-22 18:58:52 -07001623 // Notify other system components.
1624 onDispatchCycleStartedLocked(currentTime, connection);
1625}
1626
Jeff Brown51d45a72010-06-17 20:52:56 -07001627void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1628 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001629#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001630 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -07001631 "%01.1fms since dispatch",
1632 connection->getInputChannelName(),
1633 connection->getEventLatencyMillis(currentTime),
1634 connection->getDispatchLatencyMillis(currentTime));
1635#endif
1636
Jeff Brown54bc2812010-06-15 01:31:58 -07001637 if (connection->status == Connection::STATUS_BROKEN
1638 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -07001639 return;
1640 }
1641
Jeff Brown53a415e2010-09-15 15:18:56 -07001642 // Notify other system components.
1643 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001644
1645 // Reset the publisher since the event has been consumed.
1646 // We do this now so that the publisher can release some of its internal resources
1647 // while waiting for the next dispatch cycle to begin.
1648 status_t status = connection->inputPublisher.reset();
1649 if (status) {
1650 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1651 connection->getInputChannelName(), status);
1652 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1653 return;
1654 }
1655
Jeff Browna665ca82010-09-08 11:49:43 -07001656 startNextDispatchCycleLocked(currentTime, connection);
1657}
1658
1659void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1660 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001661 // Start the next dispatch cycle for this connection.
1662 while (! connection->outboundQueue.isEmpty()) {
Jeff Browna665ca82010-09-08 11:49:43 -07001663 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Browne839a582010-04-22 18:58:52 -07001664 if (dispatchEntry->inProgress) {
1665 // Finish or resume current event in progress.
1666 if (dispatchEntry->tailMotionSample) {
1667 // We have a tail of undispatched motion samples.
1668 // Reuse the same DispatchEntry and start a new cycle.
1669 dispatchEntry->inProgress = false;
1670 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1671 dispatchEntry->tailMotionSample = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07001672 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001673 return;
1674 }
1675 // Finished.
1676 connection->outboundQueue.dequeueAtHead();
Jeff Brown53a415e2010-09-15 15:18:56 -07001677 if (dispatchEntry->hasForegroundTarget()) {
1678 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownf67c53e2010-07-28 15:48:59 -07001679 }
Jeff Browne839a582010-04-22 18:58:52 -07001680 mAllocator.releaseDispatchEntry(dispatchEntry);
1681 } else {
1682 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown53a415e2010-09-15 15:18:56 -07001683 // progress event, which means we actually aborted it.
Jeff Browne839a582010-04-22 18:58:52 -07001684 // So just start the next event for this connection.
Jeff Brown53a415e2010-09-15 15:18:56 -07001685 startDispatchCycleLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -07001686 return;
1687 }
1688 }
1689
1690 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -07001691 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001692}
1693
Jeff Brown51d45a72010-06-17 20:52:56 -07001694void InputDispatcher::abortDispatchCycleLocked(nsecs_t currentTime,
1695 const sp<Connection>& connection, bool broken) {
Jeff Browne839a582010-04-22 18:58:52 -07001696#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -07001697 LOGD("channel '%s' ~ abortDispatchCycle - broken=%s",
Jeff Browna665ca82010-09-08 11:49:43 -07001698 connection->getInputChannelName(), toString(broken));
Jeff Browne839a582010-04-22 18:58:52 -07001699#endif
1700
Jeff Browna665ca82010-09-08 11:49:43 -07001701 // Input state will no longer be realistic.
1702 connection->inputState.setOutOfSync();
Jeff Browne839a582010-04-22 18:58:52 -07001703
Jeff Browna665ca82010-09-08 11:49:43 -07001704 // Clear the outbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001705 drainOutboundQueueLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -07001706
1707 // Handle the case where the connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -07001708 // Ignore already broken or zombie connections.
Jeff Browne839a582010-04-22 18:58:52 -07001709 if (broken) {
Jeff Brown53a415e2010-09-15 15:18:56 -07001710 if (connection->status == Connection::STATUS_NORMAL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001711 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -07001712
Jeff Brown54bc2812010-06-15 01:31:58 -07001713 // Notify other system components.
1714 onDispatchCycleBrokenLocked(currentTime, connection);
1715 }
Jeff Browne839a582010-04-22 18:58:52 -07001716 }
Jeff Browne839a582010-04-22 18:58:52 -07001717}
1718
Jeff Brown53a415e2010-09-15 15:18:56 -07001719void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1720 while (! connection->outboundQueue.isEmpty()) {
1721 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1722 if (dispatchEntry->hasForegroundTarget()) {
1723 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001724 }
1725 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Browna665ca82010-09-08 11:49:43 -07001726 }
1727
Jeff Brown53a415e2010-09-15 15:18:56 -07001728 deactivateConnectionLocked(connection);
Jeff Browna665ca82010-09-08 11:49:43 -07001729}
1730
Jeff Brown59abe7e2010-09-13 23:17:30 -07001731int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Browne839a582010-04-22 18:58:52 -07001732 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1733
1734 { // acquire lock
1735 AutoMutex _l(d->mLock);
1736
1737 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1738 if (connectionIndex < 0) {
1739 LOGE("Received spurious receive callback for unknown input channel. "
1740 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001741 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001742 }
1743
Jeff Brown51d45a72010-06-17 20:52:56 -07001744 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -07001745
1746 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001747 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Browne839a582010-04-22 18:58:52 -07001748 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1749 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown51d45a72010-06-17 20:52:56 -07001750 d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -07001751 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001752 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001753 }
1754
Jeff Brown59abe7e2010-09-13 23:17:30 -07001755 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Browne839a582010-04-22 18:58:52 -07001756 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1757 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown59abe7e2010-09-13 23:17:30 -07001758 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001759 }
1760
1761 status_t status = connection->inputPublisher.receiveFinishedSignal();
1762 if (status) {
1763 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1764 connection->getInputChannelName(), status);
Jeff Brown51d45a72010-06-17 20:52:56 -07001765 d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -07001766 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001767 return 0; // remove the callback
Jeff Browne839a582010-04-22 18:58:52 -07001768 }
1769
Jeff Brown51d45a72010-06-17 20:52:56 -07001770 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001771 d->runCommandsLockedInterruptible();
Jeff Brown59abe7e2010-09-13 23:17:30 -07001772 return 1;
Jeff Browne839a582010-04-22 18:58:52 -07001773 } // release lock
1774}
1775
Jeff Brown54bc2812010-06-15 01:31:58 -07001776void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07001777#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -07001778 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07001779#endif
1780
Jeff Browna665ca82010-09-08 11:49:43 -07001781 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07001782 { // acquire lock
1783 AutoMutex _l(mLock);
1784
Jeff Brown51d45a72010-06-17 20:52:56 -07001785 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browna665ca82010-09-08 11:49:43 -07001786 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001787 } // release lock
1788
Jeff Browna665ca82010-09-08 11:49:43 -07001789 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07001790 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07001791 }
1792}
1793
Jeff Brown5c1ed842010-07-14 18:48:53 -07001794void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -07001795 uint32_t policyFlags, int32_t action, int32_t flags,
1796 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
1797#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07001798 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07001799 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07001800 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -07001801 keyCode, scanCode, metaState, downTime);
1802#endif
1803
Jeff Browna665ca82010-09-08 11:49:43 -07001804 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07001805 { // acquire lock
1806 AutoMutex _l(mLock);
1807
Jeff Brown51d45a72010-06-17 20:52:56 -07001808 int32_t repeatCount = 0;
1809 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07001810 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -07001811 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -07001812
Jeff Browna665ca82010-09-08 11:49:43 -07001813 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001814 } // release lock
1815
Jeff Browna665ca82010-09-08 11:49:43 -07001816 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07001817 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07001818 }
1819}
1820
Jeff Brown5c1ed842010-07-14 18:48:53 -07001821void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001822 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07001823 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
1824 float xPrecision, float yPrecision, nsecs_t downTime) {
1825#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07001826 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07001827 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
1828 "xPrecision=%f, yPrecision=%f, downTime=%lld",
1829 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07001830 xPrecision, yPrecision, downTime);
1831 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown38a7fab2010-08-30 03:02:23 -07001832 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brownaf30ff62010-09-01 17:01:00 -07001833 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown38a7fab2010-08-30 03:02:23 -07001834 "orientation=%f",
Jeff Browne839a582010-04-22 18:58:52 -07001835 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown38a7fab2010-08-30 03:02:23 -07001836 pointerCoords[i].pressure, pointerCoords[i].size,
1837 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
1838 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
1839 pointerCoords[i].orientation);
Jeff Browne839a582010-04-22 18:58:52 -07001840 }
1841#endif
1842
Jeff Browna665ca82010-09-08 11:49:43 -07001843 bool needWake;
Jeff Browne839a582010-04-22 18:58:52 -07001844 { // acquire lock
1845 AutoMutex _l(mLock);
1846
1847 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001848 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07001849 // BATCHING CASE
1850 //
1851 // Try to append a move sample to the tail of the inbound queue for this device.
1852 // Give up if we encounter a non-move motion event for this device since that
1853 // means we cannot append any new samples until a new motion event has started.
Jeff Browna665ca82010-09-08 11:49:43 -07001854 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
1855 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07001856 if (entry->type != EventEntry::TYPE_MOTION) {
1857 // Keep looking for motion events.
1858 continue;
1859 }
1860
1861 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
1862 if (motionEntry->deviceId != deviceId) {
1863 // Keep looking for this device.
1864 continue;
1865 }
1866
Jeff Brown5c1ed842010-07-14 18:48:53 -07001867 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07001868 || motionEntry->pointerCount != pointerCount
1869 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07001870 // Last motion event in the queue for this device is not compatible for
1871 // appending new samples. Stop here.
1872 goto NoBatchingOrStreaming;
1873 }
1874
1875 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07001876 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07001877 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07001878#if DEBUG_BATCHING
1879 LOGD("Appended motion sample onto batch for most recent "
1880 "motion event for this device in the inbound queue.");
1881#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07001882 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07001883 }
1884
1885 // STREAMING CASE
1886 //
1887 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown53a415e2010-09-15 15:18:56 -07001888 // Search the outbound queue for the current foreground targets to find a dispatched
1889 // motion event that is still in progress. If found, then, appen the new sample to
1890 // that event and push it out to all current targets. The logic in
1891 // prepareDispatchCycleLocked takes care of the case where some targets may
1892 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown54bc2812010-06-15 01:31:58 -07001893 if (mCurrentInputTargetsValid) {
Jeff Brown53a415e2010-09-15 15:18:56 -07001894 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
1895 const InputTarget& inputTarget = mCurrentInputTargets[i];
1896 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
1897 // Skip non-foreground targets. We only want to stream if there is at
1898 // least one foreground target whose dispatch is still in progress.
1899 continue;
Jeff Browne839a582010-04-22 18:58:52 -07001900 }
Jeff Brown53a415e2010-09-15 15:18:56 -07001901
1902 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
1903 if (connectionIndex < 0) {
1904 // Connection must no longer be valid.
1905 continue;
1906 }
1907
1908 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1909 if (connection->outboundQueue.isEmpty()) {
1910 // This foreground target has an empty outbound queue.
1911 continue;
1912 }
1913
1914 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
1915 if (! dispatchEntry->inProgress
1916 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION) {
1917 // No motion event is being dispatched.
1918 continue;
1919 }
1920
1921 MotionEntry* motionEntry = static_cast<MotionEntry*>(
1922 dispatchEntry->eventEntry);
1923 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
1924 || motionEntry->deviceId != deviceId
1925 || motionEntry->pointerCount != pointerCount
1926 || motionEntry->isInjected()) {
1927 // The motion event is not compatible with this move.
1928 continue;
1929 }
1930
1931 // Hurray! This foreground target is currently dispatching a move event
1932 // that we can stream onto. Append the motion sample and resume dispatch.
1933 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
1934#if DEBUG_BATCHING
1935 LOGD("Appended motion sample onto batch for most recently dispatched "
1936 "motion event for this device in the outbound queues. "
1937 "Attempting to stream the motion sample.");
1938#endif
1939 nsecs_t currentTime = now();
1940 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
1941 true /*resumeWithAppendedMotionSample*/);
1942
1943 runCommandsLockedInterruptible();
1944 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07001945 }
1946 }
1947
1948NoBatchingOrStreaming:;
1949 }
1950
1951 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07001952 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07001953 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07001954 xPrecision, yPrecision, downTime,
1955 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07001956
Jeff Browna665ca82010-09-08 11:49:43 -07001957 needWake = enqueueInboundEventLocked(newEntry);
Jeff Browne839a582010-04-22 18:58:52 -07001958 } // release lock
1959
Jeff Browna665ca82010-09-08 11:49:43 -07001960 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07001961 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07001962 }
1963}
1964
Jeff Brown51d45a72010-06-17 20:52:56 -07001965int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brownf67c53e2010-07-28 15:48:59 -07001966 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001967#if DEBUG_INBOUND_EVENT_DETAILS
1968 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brownf67c53e2010-07-28 15:48:59 -07001969 "syncMode=%d, timeoutMillis=%d",
1970 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown51d45a72010-06-17 20:52:56 -07001971#endif
1972
1973 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
1974
1975 EventEntry* injectedEntry;
Jeff Browna665ca82010-09-08 11:49:43 -07001976 bool needWake;
Jeff Brown51d45a72010-06-17 20:52:56 -07001977 { // acquire lock
1978 AutoMutex _l(mLock);
1979
Jeff Browna665ca82010-09-08 11:49:43 -07001980 injectedEntry = createEntryFromInjectedInputEventLocked(event);
1981 if (! injectedEntry) {
1982 return INPUT_EVENT_INJECTION_FAILED;
1983 }
1984
Jeff Brown51d45a72010-06-17 20:52:56 -07001985 injectedEntry->refCount += 1;
1986 injectedEntry->injectorPid = injectorPid;
1987 injectedEntry->injectorUid = injectorUid;
1988
Jeff Brownf67c53e2010-07-28 15:48:59 -07001989 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
1990 injectedEntry->injectionIsAsync = true;
1991 }
1992
Jeff Browna665ca82010-09-08 11:49:43 -07001993 needWake = enqueueInboundEventLocked(injectedEntry);
Jeff Brown51d45a72010-06-17 20:52:56 -07001994 } // release lock
1995
Jeff Browna665ca82010-09-08 11:49:43 -07001996 if (needWake) {
Jeff Brown59abe7e2010-09-13 23:17:30 -07001997 mLooper->wake();
Jeff Brown51d45a72010-06-17 20:52:56 -07001998 }
1999
2000 int32_t injectionResult;
2001 { // acquire lock
2002 AutoMutex _l(mLock);
2003
Jeff Brownf67c53e2010-07-28 15:48:59 -07002004 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2005 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2006 } else {
2007 for (;;) {
2008 injectionResult = injectedEntry->injectionResult;
2009 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2010 break;
2011 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002012
Jeff Brown51d45a72010-06-17 20:52:56 -07002013 nsecs_t remainingTimeout = endTime - now();
2014 if (remainingTimeout <= 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002015#if DEBUG_INJECTION
2016 LOGD("injectInputEvent - Timed out waiting for injection result "
2017 "to become available.");
2018#endif
Jeff Brown51d45a72010-06-17 20:52:56 -07002019 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2020 break;
2021 }
2022
Jeff Brownf67c53e2010-07-28 15:48:59 -07002023 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2024 }
2025
2026 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2027 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002028 while (injectedEntry->pendingForegroundDispatches != 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002029#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002030 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
2031 injectedEntry->pendingForegroundDispatches);
Jeff Brownf67c53e2010-07-28 15:48:59 -07002032#endif
2033 nsecs_t remainingTimeout = endTime - now();
2034 if (remainingTimeout <= 0) {
2035#if DEBUG_INJECTION
Jeff Brown53a415e2010-09-15 15:18:56 -07002036 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brownf67c53e2010-07-28 15:48:59 -07002037 "dispatches to finish.");
2038#endif
2039 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2040 break;
2041 }
2042
2043 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2044 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002045 }
2046 }
2047
2048 mAllocator.releaseEventEntry(injectedEntry);
2049 } // release lock
2050
Jeff Brownf67c53e2010-07-28 15:48:59 -07002051#if DEBUG_INJECTION
2052 LOGD("injectInputEvent - Finished with result %d. "
2053 "injectorPid=%d, injectorUid=%d",
2054 injectionResult, injectorPid, injectorUid);
2055#endif
2056
Jeff Brown51d45a72010-06-17 20:52:56 -07002057 return injectionResult;
2058}
2059
2060void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
2061 if (entry->isInjected()) {
2062#if DEBUG_INJECTION
2063 LOGD("Setting input event injection result to %d. "
2064 "injectorPid=%d, injectorUid=%d",
2065 injectionResult, entry->injectorPid, entry->injectorUid);
2066#endif
2067
Jeff Brownf67c53e2010-07-28 15:48:59 -07002068 if (entry->injectionIsAsync) {
2069 // Log the outcome since the injector did not wait for the injection result.
2070 switch (injectionResult) {
2071 case INPUT_EVENT_INJECTION_SUCCEEDED:
2072 LOGV("Asynchronous input event injection succeeded.");
2073 break;
2074 case INPUT_EVENT_INJECTION_FAILED:
2075 LOGW("Asynchronous input event injection failed.");
2076 break;
2077 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2078 LOGW("Asynchronous input event injection permission denied.");
2079 break;
2080 case INPUT_EVENT_INJECTION_TIMED_OUT:
2081 LOGW("Asynchronous input event injection timed out.");
2082 break;
2083 }
2084 }
2085
Jeff Brown51d45a72010-06-17 20:52:56 -07002086 entry->injectionResult = injectionResult;
2087 mInjectionResultAvailableCondition.broadcast();
2088 }
2089}
2090
Jeff Brown53a415e2010-09-15 15:18:56 -07002091void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2092 entry->pendingForegroundDispatches -= 1;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002093
Jeff Brown53a415e2010-09-15 15:18:56 -07002094 if (entry->isInjected() && entry->pendingForegroundDispatches == 0) {
Jeff Brownf67c53e2010-07-28 15:48:59 -07002095 mInjectionSyncFinishedCondition.broadcast();
2096 }
Jeff Brown51d45a72010-06-17 20:52:56 -07002097}
2098
Jeff Browna665ca82010-09-08 11:49:43 -07002099static bool isValidKeyAction(int32_t action) {
2100 switch (action) {
2101 case AKEY_EVENT_ACTION_DOWN:
2102 case AKEY_EVENT_ACTION_UP:
2103 return true;
2104 default:
2105 return false;
2106 }
2107}
2108
2109static bool isValidMotionAction(int32_t action) {
2110 switch (action & AMOTION_EVENT_ACTION_MASK) {
2111 case AMOTION_EVENT_ACTION_DOWN:
2112 case AMOTION_EVENT_ACTION_UP:
2113 case AMOTION_EVENT_ACTION_CANCEL:
2114 case AMOTION_EVENT_ACTION_MOVE:
2115 case AMOTION_EVENT_ACTION_POINTER_DOWN:
2116 case AMOTION_EVENT_ACTION_POINTER_UP:
2117 case AMOTION_EVENT_ACTION_OUTSIDE:
2118 return true;
2119 default:
2120 return false;
2121 }
2122}
2123
2124InputDispatcher::EventEntry* InputDispatcher::createEntryFromInjectedInputEventLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002125 const InputEvent* event) {
2126 switch (event->getType()) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07002127 case AINPUT_EVENT_TYPE_KEY: {
Jeff Brown51d45a72010-06-17 20:52:56 -07002128 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
Jeff Browna665ca82010-09-08 11:49:43 -07002129 if (! isValidKeyAction(keyEvent->getAction())) {
2130 LOGE("Dropping injected key event since it has invalid action code 0x%x",
2131 keyEvent->getAction());
2132 return NULL;
2133 }
2134
Jeff Brownaf30ff62010-09-01 17:01:00 -07002135 uint32_t policyFlags = POLICY_FLAG_INJECTED;
Jeff Brown51d45a72010-06-17 20:52:56 -07002136
2137 KeyEntry* keyEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
Jeff Brown5c1ed842010-07-14 18:48:53 -07002138 keyEvent->getDeviceId(), keyEvent->getSource(), policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002139 keyEvent->getAction(), keyEvent->getFlags(),
2140 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
2141 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2142 return keyEntry;
2143 }
2144
Jeff Brown5c1ed842010-07-14 18:48:53 -07002145 case AINPUT_EVENT_TYPE_MOTION: {
Jeff Brown51d45a72010-06-17 20:52:56 -07002146 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
Jeff Browna665ca82010-09-08 11:49:43 -07002147 if (! isValidMotionAction(motionEvent->getAction())) {
2148 LOGE("Dropping injected motion event since it has invalid action code 0x%x.",
2149 motionEvent->getAction());
2150 return NULL;
2151 }
2152 if (motionEvent->getPointerCount() == 0
2153 || motionEvent->getPointerCount() > MAX_POINTERS) {
2154 LOGE("Dropping injected motion event since it has an invalid pointer count %d.",
2155 motionEvent->getPointerCount());
2156 }
2157
Jeff Brownaf30ff62010-09-01 17:01:00 -07002158 uint32_t policyFlags = POLICY_FLAG_INJECTED;
Jeff Brown51d45a72010-06-17 20:52:56 -07002159
2160 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2161 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2162 size_t pointerCount = motionEvent->getPointerCount();
2163
2164 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002165 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002166 motionEvent->getAction(), motionEvent->getFlags(),
2167 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
Jeff Brown51d45a72010-06-17 20:52:56 -07002168 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2169 motionEvent->getDownTime(), uint32_t(pointerCount),
2170 motionEvent->getPointerIds(), samplePointerCoords);
2171 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2172 sampleEventTimes += 1;
2173 samplePointerCoords += pointerCount;
2174 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2175 }
2176 return motionEntry;
2177 }
2178
2179 default:
2180 assert(false);
2181 return NULL;
2182 }
2183}
2184
Jeff Browna665ca82010-09-08 11:49:43 -07002185void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2186#if DEBUG_FOCUS
2187 LOGD("setInputWindows");
2188#endif
2189 { // acquire lock
2190 AutoMutex _l(mLock);
2191
Jeff Brown405a1d32010-09-16 12:31:46 -07002192 // Clear old window pointers but remember their associated channels.
2193 mFocusedWindow = NULL;
Jeff Brown53a415e2010-09-15 15:18:56 -07002194
Jeff Browna665ca82010-09-08 11:49:43 -07002195 sp<InputChannel> touchedWindowChannel;
2196 if (mTouchedWindow) {
2197 touchedWindowChannel = mTouchedWindow->inputChannel;
2198 mTouchedWindow = NULL;
2199 }
2200 size_t numTouchedWallpapers = mTouchedWallpaperWindows.size();
2201 if (numTouchedWallpapers != 0) {
2202 for (size_t i = 0; i < numTouchedWallpapers; i++) {
2203 mTempTouchedWallpaperChannels.push(mTouchedWallpaperWindows[i]->inputChannel);
2204 }
2205 mTouchedWallpaperWindows.clear();
2206 }
Jeff Browna665ca82010-09-08 11:49:43 -07002207 mWallpaperWindows.clear();
Jeff Browna665ca82010-09-08 11:49:43 -07002208 mWindows.clear();
Jeff Brown405a1d32010-09-16 12:31:46 -07002209
2210 // Loop over new windows and rebuild the necessary window pointers for
2211 // tracking focus and touch.
Jeff Browna665ca82010-09-08 11:49:43 -07002212 mWindows.appendVector(inputWindows);
2213
2214 size_t numWindows = mWindows.size();
2215 for (size_t i = 0; i < numWindows; i++) {
2216 InputWindow* window = & mWindows.editItemAt(i);
2217 if (window->hasFocus) {
2218 mFocusedWindow = window;
2219 }
2220
2221 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
2222 mWallpaperWindows.push(window);
2223
2224 for (size_t j = 0; j < numTouchedWallpapers; j++) {
2225 if (window->inputChannel == mTempTouchedWallpaperChannels[i]) {
2226 mTouchedWallpaperWindows.push(window);
2227 }
2228 }
2229 }
2230
2231 if (window->inputChannel == touchedWindowChannel) {
2232 mTouchedWindow = window;
2233 }
2234 }
Jeff Browna665ca82010-09-08 11:49:43 -07002235 mTempTouchedWallpaperChannels.clear();
2236
Jeff Browna665ca82010-09-08 11:49:43 -07002237#if DEBUG_FOCUS
2238 logDispatchStateLocked();
2239#endif
2240 } // release lock
2241
2242 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002243 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002244}
2245
2246void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2247#if DEBUG_FOCUS
2248 LOGD("setFocusedApplication");
2249#endif
2250 { // acquire lock
2251 AutoMutex _l(mLock);
2252
2253 releaseFocusedApplicationLocked();
2254
2255 if (inputApplication) {
2256 mFocusedApplicationStorage = *inputApplication;
2257 mFocusedApplication = & mFocusedApplicationStorage;
2258 }
2259
2260#if DEBUG_FOCUS
2261 logDispatchStateLocked();
2262#endif
2263 } // release lock
2264
2265 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002266 mLooper->wake();
Jeff Browna665ca82010-09-08 11:49:43 -07002267}
2268
2269void InputDispatcher::releaseFocusedApplicationLocked() {
2270 if (mFocusedApplication) {
2271 mFocusedApplication = NULL;
2272 mFocusedApplicationStorage.handle.clear();
2273 }
2274}
2275
2276void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2277#if DEBUG_FOCUS
2278 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2279#endif
2280
2281 bool changed;
2282 { // acquire lock
2283 AutoMutex _l(mLock);
2284
2285 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2286 if (mDispatchFrozen && ! frozen) {
2287 resetANRTimeoutsLocked();
2288 }
2289
2290 mDispatchEnabled = enabled;
2291 mDispatchFrozen = frozen;
2292 changed = true;
2293 } else {
2294 changed = false;
2295 }
2296
2297#if DEBUG_FOCUS
2298 logDispatchStateLocked();
2299#endif
2300 } // release lock
2301
2302 if (changed) {
2303 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002304 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002305 }
2306}
2307
Jeff Browna665ca82010-09-08 11:49:43 -07002308void InputDispatcher::logDispatchStateLocked() {
2309 String8 dump;
2310 dumpDispatchStateLocked(dump);
Jeff Brown405a1d32010-09-16 12:31:46 -07002311
2312 char* text = dump.lockBuffer(dump.size());
2313 char* start = text;
2314 while (*start != '\0') {
2315 char* end = strchr(start, '\n');
2316 if (*end == '\n') {
2317 *(end++) = '\0';
2318 }
2319 LOGD("%s", start);
2320 start = end;
2321 }
Jeff Browna665ca82010-09-08 11:49:43 -07002322}
2323
2324void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
2325 dump.appendFormat(" dispatchEnabled: %d\n", mDispatchEnabled);
2326 dump.appendFormat(" dispatchFrozen: %d\n", mDispatchFrozen);
2327
2328 if (mFocusedApplication) {
2329 dump.appendFormat(" focusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
2330 mFocusedApplication->name.string(),
2331 mFocusedApplication->dispatchingTimeout / 1000000.0);
2332 } else {
2333 dump.append(" focusedApplication: <null>\n");
2334 }
Jeff Brown405a1d32010-09-16 12:31:46 -07002335 dump.appendFormat(" focusedWindow: name='%s'\n",
2336 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
2337 dump.appendFormat(" touchedWindow: name='%s', touchDown=%d\n",
2338 mTouchedWindow != NULL ? mTouchedWindow->name.string() : "<null>",
Jeff Browna665ca82010-09-08 11:49:43 -07002339 mTouchDown);
2340 for (size_t i = 0; i < mTouchedWallpaperWindows.size(); i++) {
Jeff Brown405a1d32010-09-16 12:31:46 -07002341 dump.appendFormat(" touchedWallpaperWindows[%d]: name='%s'\n",
2342 i, mTouchedWallpaperWindows[i]->name.string());
Jeff Browna665ca82010-09-08 11:49:43 -07002343 }
2344 for (size_t i = 0; i < mWindows.size(); i++) {
Jeff Brown405a1d32010-09-16 12:31:46 -07002345 dump.appendFormat(" windows[%d]: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2346 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
Jeff Browna665ca82010-09-08 11:49:43 -07002347 "frame=[%d,%d][%d,%d], "
2348 "visibleFrame=[%d,%d][%d,%d], "
2349 "touchableArea=[%d,%d][%d,%d], "
2350 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Jeff Brown405a1d32010-09-16 12:31:46 -07002351 i, mWindows[i].name.string(),
Jeff Browna665ca82010-09-08 11:49:43 -07002352 toString(mWindows[i].paused),
2353 toString(mWindows[i].hasFocus),
2354 toString(mWindows[i].hasWallpaper),
2355 toString(mWindows[i].visible),
Jeff Brown405a1d32010-09-16 12:31:46 -07002356 toString(mWindows[i].canReceiveKeys),
Jeff Browna665ca82010-09-08 11:49:43 -07002357 mWindows[i].layoutParamsFlags, mWindows[i].layoutParamsType,
Jeff Brown405a1d32010-09-16 12:31:46 -07002358 mWindows[i].layer,
Jeff Browna665ca82010-09-08 11:49:43 -07002359 mWindows[i].frameLeft, mWindows[i].frameTop,
2360 mWindows[i].frameRight, mWindows[i].frameBottom,
2361 mWindows[i].visibleFrameLeft, mWindows[i].visibleFrameTop,
2362 mWindows[i].visibleFrameRight, mWindows[i].visibleFrameBottom,
2363 mWindows[i].touchableAreaLeft, mWindows[i].touchableAreaTop,
2364 mWindows[i].touchableAreaRight, mWindows[i].touchableAreaBottom,
2365 mWindows[i].ownerPid, mWindows[i].ownerUid,
2366 mWindows[i].dispatchingTimeout / 1000000.0);
2367 }
2368
2369 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2370 const sp<InputChannel>& channel = mMonitoringChannels[i];
2371 dump.appendFormat(" monitoringChannel[%d]: '%s'\n",
2372 i, channel->getName().string());
2373 }
2374
Jeff Brown53a415e2010-09-15 15:18:56 -07002375 dump.appendFormat(" inboundQueue: length=%u", mInboundQueue.count());
2376
Jeff Browna665ca82010-09-08 11:49:43 -07002377 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2378 const Connection* connection = mActiveConnections[i];
Jeff Brown53a415e2010-09-15 15:18:56 -07002379 dump.appendFormat(" activeConnection[%d]: '%s', status=%s, outboundQueueLength=%u"
Jeff Browna665ca82010-09-08 11:49:43 -07002380 "inputState.isNeutral=%s, inputState.isOutOfSync=%s\n",
2381 i, connection->getInputChannelName(), connection->getStatusLabel(),
Jeff Brown53a415e2010-09-15 15:18:56 -07002382 connection->outboundQueue.count(),
Jeff Browna665ca82010-09-08 11:49:43 -07002383 toString(connection->inputState.isNeutral()),
2384 toString(connection->inputState.isOutOfSync()));
2385 }
2386
2387 if (isAppSwitchPendingLocked()) {
2388 dump.appendFormat(" appSwitch: pending, due in %01.1fms\n",
2389 (mAppSwitchDueTime - now()) / 1000000.0);
2390 } else {
2391 dump.append(" appSwitch: not pending\n");
2392 }
2393}
2394
2395status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002396#if DEBUG_REGISTRATION
Jeff Browna665ca82010-09-08 11:49:43 -07002397 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2398 toString(monitor));
Jeff Brown54bc2812010-06-15 01:31:58 -07002399#endif
2400
Jeff Browne839a582010-04-22 18:58:52 -07002401 { // acquire lock
2402 AutoMutex _l(mLock);
2403
Jeff Brown53a415e2010-09-15 15:18:56 -07002404 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Browne839a582010-04-22 18:58:52 -07002405 LOGW("Attempted to register already registered input channel '%s'",
2406 inputChannel->getName().string());
2407 return BAD_VALUE;
2408 }
2409
2410 sp<Connection> connection = new Connection(inputChannel);
2411 status_t status = connection->initialize();
2412 if (status) {
2413 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2414 inputChannel->getName().string(), status);
2415 return status;
2416 }
2417
Jeff Brown0cacb872010-08-17 15:59:26 -07002418 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Browne839a582010-04-22 18:58:52 -07002419 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07002420
Jeff Browna665ca82010-09-08 11:49:43 -07002421 if (monitor) {
2422 mMonitoringChannels.push(inputChannel);
2423 }
2424
Jeff Brown59abe7e2010-09-13 23:17:30 -07002425 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown0cacb872010-08-17 15:59:26 -07002426
Jeff Brown54bc2812010-06-15 01:31:58 -07002427 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002428 } // release lock
Jeff Browne839a582010-04-22 18:58:52 -07002429 return OK;
2430}
2431
2432status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002433#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07002434 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07002435#endif
2436
Jeff Browne839a582010-04-22 18:58:52 -07002437 { // acquire lock
2438 AutoMutex _l(mLock);
2439
Jeff Brown53a415e2010-09-15 15:18:56 -07002440 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Browne839a582010-04-22 18:58:52 -07002441 if (connectionIndex < 0) {
2442 LOGW("Attempted to unregister already unregistered input channel '%s'",
2443 inputChannel->getName().string());
2444 return BAD_VALUE;
2445 }
2446
2447 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2448 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2449
2450 connection->status = Connection::STATUS_ZOMBIE;
2451
Jeff Browna665ca82010-09-08 11:49:43 -07002452 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2453 if (mMonitoringChannels[i] == inputChannel) {
2454 mMonitoringChannels.removeAt(i);
2455 break;
2456 }
2457 }
2458
Jeff Brown59abe7e2010-09-13 23:17:30 -07002459 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown0cacb872010-08-17 15:59:26 -07002460
Jeff Brown51d45a72010-06-17 20:52:56 -07002461 nsecs_t currentTime = now();
2462 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -07002463
2464 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07002465 } // release lock
2466
Jeff Browne839a582010-04-22 18:58:52 -07002467 // Wake the poll loop because removing the connection may have changed the current
2468 // synchronization state.
Jeff Brown59abe7e2010-09-13 23:17:30 -07002469 mLooper->wake();
Jeff Browne839a582010-04-22 18:58:52 -07002470 return OK;
2471}
2472
Jeff Brown53a415e2010-09-15 15:18:56 -07002473ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown0cacb872010-08-17 15:59:26 -07002474 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2475 if (connectionIndex >= 0) {
2476 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2477 if (connection->inputChannel.get() == inputChannel.get()) {
2478 return connectionIndex;
2479 }
2480 }
2481
2482 return -1;
2483}
2484
Jeff Browne839a582010-04-22 18:58:52 -07002485void InputDispatcher::activateConnectionLocked(Connection* connection) {
2486 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2487 if (mActiveConnections.itemAt(i) == connection) {
2488 return;
2489 }
2490 }
2491 mActiveConnections.add(connection);
2492}
2493
2494void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2495 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2496 if (mActiveConnections.itemAt(i) == connection) {
2497 mActiveConnections.removeAt(i);
2498 return;
2499 }
2500 }
2501}
2502
Jeff Brown54bc2812010-06-15 01:31:58 -07002503void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002504 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002505}
2506
Jeff Brown54bc2812010-06-15 01:31:58 -07002507void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002508 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002509}
2510
Jeff Brown54bc2812010-06-15 01:31:58 -07002511void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07002512 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07002513 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2514 connection->getInputChannelName());
2515
Jeff Brown54bc2812010-06-15 01:31:58 -07002516 CommandEntry* commandEntry = postCommandLocked(
2517 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07002518 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07002519}
2520
Jeff Brown53a415e2010-09-15 15:18:56 -07002521void InputDispatcher::onANRLocked(
2522 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2523 nsecs_t eventTime, nsecs_t waitStartTime) {
2524 LOGI("Application is not responding: %s. "
2525 "%01.1fms since event, %01.1fms since wait started",
2526 getApplicationWindowLabelLocked(application, window).string(),
2527 (currentTime - eventTime) / 1000000.0,
2528 (currentTime - waitStartTime) / 1000000.0);
2529
2530 CommandEntry* commandEntry = postCommandLocked(
2531 & InputDispatcher::doNotifyANRLockedInterruptible);
2532 if (application) {
2533 commandEntry->inputApplicationHandle = application->handle;
2534 }
2535 if (window) {
2536 commandEntry->inputChannel = window->inputChannel;
2537 }
2538}
2539
Jeff Browna665ca82010-09-08 11:49:43 -07002540void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2541 CommandEntry* commandEntry) {
2542 mLock.unlock();
2543
2544 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2545
2546 mLock.lock();
2547}
2548
Jeff Brown54bc2812010-06-15 01:31:58 -07002549void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2550 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07002551 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07002552
Jeff Brown51d45a72010-06-17 20:52:56 -07002553 if (connection->status != Connection::STATUS_ZOMBIE) {
2554 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002555
Jeff Brown51d45a72010-06-17 20:52:56 -07002556 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2557
2558 mLock.lock();
2559 }
Jeff Brown54bc2812010-06-15 01:31:58 -07002560}
2561
Jeff Brown53a415e2010-09-15 15:18:56 -07002562void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown54bc2812010-06-15 01:31:58 -07002563 CommandEntry* commandEntry) {
Jeff Brown53a415e2010-09-15 15:18:56 -07002564 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07002565
Jeff Brown53a415e2010-09-15 15:18:56 -07002566 nsecs_t newTimeout = mPolicy->notifyANR(
2567 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002568
Jeff Brown53a415e2010-09-15 15:18:56 -07002569 mLock.lock();
Jeff Brown51d45a72010-06-17 20:52:56 -07002570
Jeff Brown53a415e2010-09-15 15:18:56 -07002571 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown54bc2812010-06-15 01:31:58 -07002572}
2573
Jeff Browna665ca82010-09-08 11:49:43 -07002574void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2575 CommandEntry* commandEntry) {
2576 KeyEntry* entry = commandEntry->keyEntry;
2577 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2578 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2579 entry->downTime, entry->eventTime);
2580
2581 mLock.unlock();
2582
2583 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2584 & mReusableKeyEvent, entry->policyFlags);
2585
2586 mLock.lock();
2587
2588 entry->interceptKeyResult = consumed
2589 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2590 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2591 mAllocator.releaseKeyEntry(entry);
2592}
2593
2594void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2595 mLock.unlock();
2596
2597 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->windowType,
2598 commandEntry->userActivityEventType);
2599
2600 mLock.lock();
2601}
2602
Jeff Brown53a415e2010-09-15 15:18:56 -07002603void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
2604 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
2605 // TODO Write some statistics about how long we spend waiting.
Jeff Browna665ca82010-09-08 11:49:43 -07002606}
2607
2608void InputDispatcher::dump(String8& dump) {
2609 dumpDispatchStateLocked(dump);
2610}
2611
Jeff Brown54bc2812010-06-15 01:31:58 -07002612
Jeff Brown53a415e2010-09-15 15:18:56 -07002613// --- InputDispatcher::Queue ---
2614
2615template <typename T>
2616uint32_t InputDispatcher::Queue<T>::count() const {
2617 uint32_t result = 0;
2618 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
2619 result += 1;
2620 }
2621 return result;
2622}
2623
2624
Jeff Browne839a582010-04-22 18:58:52 -07002625// --- InputDispatcher::Allocator ---
2626
2627InputDispatcher::Allocator::Allocator() {
2628}
2629
Jeff Brown51d45a72010-06-17 20:52:56 -07002630void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
2631 nsecs_t eventTime) {
2632 entry->type = type;
2633 entry->refCount = 1;
2634 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07002635 entry->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07002636 entry->injectionResult = INPUT_EVENT_INJECTION_PENDING;
Jeff Brownf67c53e2010-07-28 15:48:59 -07002637 entry->injectionIsAsync = false;
Jeff Brown51d45a72010-06-17 20:52:56 -07002638 entry->injectorPid = -1;
2639 entry->injectorUid = -1;
Jeff Brown53a415e2010-09-15 15:18:56 -07002640 entry->pendingForegroundDispatches = 0;
Jeff Brown51d45a72010-06-17 20:52:56 -07002641}
2642
Jeff Browne839a582010-04-22 18:58:52 -07002643InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07002644InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002645 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown51d45a72010-06-17 20:52:56 -07002646 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07002647 return entry;
2648}
2649
Jeff Brown51d45a72010-06-17 20:52:56 -07002650InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07002651 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07002652 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
2653 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07002654 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown51d45a72010-06-17 20:52:56 -07002655 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime);
2656
2657 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07002658 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07002659 entry->policyFlags = policyFlags;
2660 entry->action = action;
2661 entry->flags = flags;
2662 entry->keyCode = keyCode;
2663 entry->scanCode = scanCode;
2664 entry->metaState = metaState;
2665 entry->repeatCount = repeatCount;
2666 entry->downTime = downTime;
Jeff Browna665ca82010-09-08 11:49:43 -07002667 entry->syntheticRepeat = false;
2668 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Browne839a582010-04-22 18:58:52 -07002669 return entry;
2670}
2671
Jeff Brown51d45a72010-06-17 20:52:56 -07002672InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brownaf30ff62010-09-01 17:01:00 -07002673 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown51d45a72010-06-17 20:52:56 -07002674 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
2675 nsecs_t downTime, uint32_t pointerCount,
2676 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07002677 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown51d45a72010-06-17 20:52:56 -07002678 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime);
2679
2680 entry->eventTime = eventTime;
2681 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07002682 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07002683 entry->policyFlags = policyFlags;
2684 entry->action = action;
Jeff Brownaf30ff62010-09-01 17:01:00 -07002685 entry->flags = flags;
Jeff Brown51d45a72010-06-17 20:52:56 -07002686 entry->metaState = metaState;
2687 entry->edgeFlags = edgeFlags;
2688 entry->xPrecision = xPrecision;
2689 entry->yPrecision = yPrecision;
2690 entry->downTime = downTime;
2691 entry->pointerCount = pointerCount;
2692 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07002693 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07002694 entry->lastSample = & entry->firstSample;
2695 for (uint32_t i = 0; i < pointerCount; i++) {
2696 entry->pointerIds[i] = pointerIds[i];
2697 entry->firstSample.pointerCoords[i] = pointerCoords[i];
2698 }
Jeff Browne839a582010-04-22 18:58:52 -07002699 return entry;
2700}
2701
2702InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Browna665ca82010-09-08 11:49:43 -07002703 EventEntry* eventEntry,
Jeff Brown53a415e2010-09-15 15:18:56 -07002704 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Browne839a582010-04-22 18:58:52 -07002705 DispatchEntry* entry = mDispatchEntryPool.alloc();
2706 entry->eventEntry = eventEntry;
2707 eventEntry->refCount += 1;
Jeff Browna665ca82010-09-08 11:49:43 -07002708 entry->targetFlags = targetFlags;
2709 entry->xOffset = xOffset;
2710 entry->yOffset = yOffset;
Jeff Browna665ca82010-09-08 11:49:43 -07002711 entry->inProgress = false;
2712 entry->headMotionSample = NULL;
2713 entry->tailMotionSample = NULL;
Jeff Browne839a582010-04-22 18:58:52 -07002714 return entry;
2715}
2716
Jeff Brown54bc2812010-06-15 01:31:58 -07002717InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
2718 CommandEntry* entry = mCommandEntryPool.alloc();
2719 entry->command = command;
2720 return entry;
2721}
2722
Jeff Browne839a582010-04-22 18:58:52 -07002723void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
2724 switch (entry->type) {
2725 case EventEntry::TYPE_CONFIGURATION_CHANGED:
2726 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
2727 break;
2728 case EventEntry::TYPE_KEY:
2729 releaseKeyEntry(static_cast<KeyEntry*>(entry));
2730 break;
2731 case EventEntry::TYPE_MOTION:
2732 releaseMotionEntry(static_cast<MotionEntry*>(entry));
2733 break;
2734 default:
2735 assert(false);
2736 break;
2737 }
2738}
2739
2740void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
2741 ConfigurationChangedEntry* entry) {
2742 entry->refCount -= 1;
2743 if (entry->refCount == 0) {
2744 mConfigurationChangeEntryPool.free(entry);
2745 } else {
2746 assert(entry->refCount > 0);
2747 }
2748}
2749
2750void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
2751 entry->refCount -= 1;
2752 if (entry->refCount == 0) {
2753 mKeyEntryPool.free(entry);
2754 } else {
2755 assert(entry->refCount > 0);
2756 }
2757}
2758
2759void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
2760 entry->refCount -= 1;
2761 if (entry->refCount == 0) {
Jeff Brown54bc2812010-06-15 01:31:58 -07002762 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
2763 MotionSample* next = sample->next;
2764 mMotionSamplePool.free(sample);
2765 sample = next;
2766 }
Jeff Browne839a582010-04-22 18:58:52 -07002767 mMotionEntryPool.free(entry);
2768 } else {
2769 assert(entry->refCount > 0);
2770 }
2771}
2772
2773void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
2774 releaseEventEntry(entry->eventEntry);
2775 mDispatchEntryPool.free(entry);
2776}
2777
Jeff Brown54bc2812010-06-15 01:31:58 -07002778void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
2779 mCommandEntryPool.free(entry);
2780}
2781
Jeff Browne839a582010-04-22 18:58:52 -07002782void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07002783 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07002784 MotionSample* sample = mMotionSamplePool.alloc();
2785 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07002786 uint32_t pointerCount = motionEntry->pointerCount;
2787 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07002788 sample->pointerCoords[i] = pointerCoords[i];
2789 }
2790
2791 sample->next = NULL;
2792 motionEntry->lastSample->next = sample;
2793 motionEntry->lastSample = sample;
2794}
2795
Jeff Browna665ca82010-09-08 11:49:43 -07002796
2797// --- InputDispatcher::EventEntry ---
2798
2799void InputDispatcher::EventEntry::recycle() {
2800 injectionResult = INPUT_EVENT_INJECTION_PENDING;
2801 dispatchInProgress = false;
Jeff Brown53a415e2010-09-15 15:18:56 -07002802 pendingForegroundDispatches = 0;
Jeff Browna665ca82010-09-08 11:49:43 -07002803}
2804
2805
2806// --- InputDispatcher::KeyEntry ---
2807
2808void InputDispatcher::KeyEntry::recycle() {
2809 EventEntry::recycle();
2810 syntheticRepeat = false;
2811 interceptKeyResult = INTERCEPT_KEY_RESULT_UNKNOWN;
2812}
2813
2814
Jeff Brown542412c2010-08-18 15:51:08 -07002815// --- InputDispatcher::MotionEntry ---
2816
2817uint32_t InputDispatcher::MotionEntry::countSamples() const {
2818 uint32_t count = 1;
2819 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
2820 count += 1;
2821 }
2822 return count;
2823}
2824
Jeff Browna665ca82010-09-08 11:49:43 -07002825
2826// --- InputDispatcher::InputState ---
2827
2828InputDispatcher::InputState::InputState() :
2829 mIsOutOfSync(false) {
2830}
2831
2832InputDispatcher::InputState::~InputState() {
2833}
2834
2835bool InputDispatcher::InputState::isNeutral() const {
2836 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
2837}
2838
2839bool InputDispatcher::InputState::isOutOfSync() const {
2840 return mIsOutOfSync;
2841}
2842
2843void InputDispatcher::InputState::setOutOfSync() {
2844 if (! isNeutral()) {
2845 mIsOutOfSync = true;
2846 }
2847}
2848
2849void InputDispatcher::InputState::resetOutOfSync() {
2850 mIsOutOfSync = false;
2851}
2852
2853InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
2854 const EventEntry* entry) {
2855 switch (entry->type) {
2856 case EventEntry::TYPE_KEY:
2857 return trackKey(static_cast<const KeyEntry*>(entry));
2858
2859 case EventEntry::TYPE_MOTION:
2860 return trackMotion(static_cast<const MotionEntry*>(entry));
2861
2862 default:
2863 return CONSISTENT;
2864 }
2865}
2866
2867InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
2868 const KeyEntry* entry) {
2869 int32_t action = entry->action;
2870 for (size_t i = 0; i < mKeyMementos.size(); i++) {
2871 KeyMemento& memento = mKeyMementos.editItemAt(i);
2872 if (memento.deviceId == entry->deviceId
2873 && memento.source == entry->source
2874 && memento.keyCode == entry->keyCode
2875 && memento.scanCode == entry->scanCode) {
2876 switch (action) {
2877 case AKEY_EVENT_ACTION_UP:
2878 mKeyMementos.removeAt(i);
2879 if (isNeutral()) {
2880 mIsOutOfSync = false;
2881 }
2882 return CONSISTENT;
2883
2884 case AKEY_EVENT_ACTION_DOWN:
2885 return TOLERABLE;
2886
2887 default:
2888 return BROKEN;
2889 }
2890 }
2891 }
2892
2893 switch (action) {
2894 case AKEY_EVENT_ACTION_DOWN: {
2895 mKeyMementos.push();
2896 KeyMemento& memento = mKeyMementos.editTop();
2897 memento.deviceId = entry->deviceId;
2898 memento.source = entry->source;
2899 memento.keyCode = entry->keyCode;
2900 memento.scanCode = entry->scanCode;
2901 memento.downTime = entry->downTime;
2902 return CONSISTENT;
2903 }
2904
2905 default:
2906 return BROKEN;
2907 }
2908}
2909
2910InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
2911 const MotionEntry* entry) {
2912 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
2913 for (size_t i = 0; i < mMotionMementos.size(); i++) {
2914 MotionMemento& memento = mMotionMementos.editItemAt(i);
2915 if (memento.deviceId == entry->deviceId
2916 && memento.source == entry->source) {
2917 switch (action) {
2918 case AMOTION_EVENT_ACTION_UP:
2919 case AMOTION_EVENT_ACTION_CANCEL:
2920 mMotionMementos.removeAt(i);
2921 if (isNeutral()) {
2922 mIsOutOfSync = false;
2923 }
2924 return CONSISTENT;
2925
2926 case AMOTION_EVENT_ACTION_DOWN:
2927 return TOLERABLE;
2928
2929 case AMOTION_EVENT_ACTION_POINTER_DOWN:
2930 if (entry->pointerCount == memento.pointerCount + 1) {
2931 memento.setPointers(entry);
2932 return CONSISTENT;
2933 }
2934 return BROKEN;
2935
2936 case AMOTION_EVENT_ACTION_POINTER_UP:
2937 if (entry->pointerCount == memento.pointerCount - 1) {
2938 memento.setPointers(entry);
2939 return CONSISTENT;
2940 }
2941 return BROKEN;
2942
2943 case AMOTION_EVENT_ACTION_MOVE:
2944 if (entry->pointerCount == memento.pointerCount) {
2945 return CONSISTENT;
2946 }
2947 return BROKEN;
2948
2949 default:
2950 return BROKEN;
2951 }
2952 }
2953 }
2954
2955 switch (action) {
2956 case AMOTION_EVENT_ACTION_DOWN: {
2957 mMotionMementos.push();
2958 MotionMemento& memento = mMotionMementos.editTop();
2959 memento.deviceId = entry->deviceId;
2960 memento.source = entry->source;
2961 memento.xPrecision = entry->xPrecision;
2962 memento.yPrecision = entry->yPrecision;
2963 memento.downTime = entry->downTime;
2964 memento.setPointers(entry);
2965 return CONSISTENT;
2966 }
2967
2968 default:
2969 return BROKEN;
2970 }
2971}
2972
2973void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
2974 pointerCount = entry->pointerCount;
2975 for (uint32_t i = 0; i < entry->pointerCount; i++) {
2976 pointerIds[i] = entry->pointerIds[i];
2977 pointerCoords[i] = entry->lastSample->pointerCoords[i];
2978 }
2979}
2980
2981void InputDispatcher::InputState::synthesizeCancelationEvents(
2982 Allocator* allocator, Vector<EventEntry*>& outEvents) const {
2983 for (size_t i = 0; i < mKeyMementos.size(); i++) {
2984 const KeyMemento& memento = mKeyMementos.itemAt(i);
2985 outEvents.push(allocator->obtainKeyEntry(now(),
2986 memento.deviceId, memento.source, 0,
2987 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
2988 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
2989 }
2990
2991 for (size_t i = 0; i < mMotionMementos.size(); i++) {
2992 const MotionMemento& memento = mMotionMementos.itemAt(i);
2993 outEvents.push(allocator->obtainMotionEntry(now(),
2994 memento.deviceId, memento.source, 0,
2995 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
2996 memento.xPrecision, memento.yPrecision, memento.downTime,
2997 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
2998 }
2999}
3000
3001void InputDispatcher::InputState::clear() {
3002 mKeyMementos.clear();
3003 mMotionMementos.clear();
3004 mIsOutOfSync = false;
3005}
3006
3007
Jeff Browne839a582010-04-22 18:58:52 -07003008// --- InputDispatcher::Connection ---
3009
3010InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3011 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown53a415e2010-09-15 15:18:56 -07003012 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Browne839a582010-04-22 18:58:52 -07003013}
3014
3015InputDispatcher::Connection::~Connection() {
3016}
3017
3018status_t InputDispatcher::Connection::initialize() {
3019 return inputPublisher.initialize();
3020}
3021
Jeff Brown54bc2812010-06-15 01:31:58 -07003022const char* InputDispatcher::Connection::getStatusLabel() const {
3023 switch (status) {
3024 case STATUS_NORMAL:
3025 return "NORMAL";
3026
3027 case STATUS_BROKEN:
3028 return "BROKEN";
3029
Jeff Brown54bc2812010-06-15 01:31:58 -07003030 case STATUS_ZOMBIE:
3031 return "ZOMBIE";
3032
3033 default:
3034 return "UNKNOWN";
3035 }
3036}
3037
Jeff Browne839a582010-04-22 18:58:52 -07003038InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3039 const EventEntry* eventEntry) const {
Jeff Browna665ca82010-09-08 11:49:43 -07003040 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3041 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Browne839a582010-04-22 18:58:52 -07003042 if (dispatchEntry->eventEntry == eventEntry) {
3043 return dispatchEntry;
3044 }
3045 }
3046 return NULL;
3047}
3048
Jeff Browna665ca82010-09-08 11:49:43 -07003049
Jeff Brown54bc2812010-06-15 01:31:58 -07003050// --- InputDispatcher::CommandEntry ---
3051
Jeff Browna665ca82010-09-08 11:49:43 -07003052InputDispatcher::CommandEntry::CommandEntry() :
3053 keyEntry(NULL) {
Jeff Brown54bc2812010-06-15 01:31:58 -07003054}
3055
3056InputDispatcher::CommandEntry::~CommandEntry() {
3057}
3058
Jeff Browne839a582010-04-22 18:58:52 -07003059
3060// --- InputDispatcherThread ---
3061
3062InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3063 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3064}
3065
3066InputDispatcherThread::~InputDispatcherThread() {
3067}
3068
3069bool InputDispatcherThread::threadLoop() {
3070 mDispatcher->dispatchOnce();
3071 return true;
3072}
3073
3074} // namespace android