blob: cbfdd755df09e488325a76b6e216f145eb176e86 [file] [log] [blame]
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070017#define LOG_TAG "InputDispatcher"
18
19//#define LOG_NDEBUG 0
20
21// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070022#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070023
24// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070025#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070026
27// Log debug messages about batching.
Jeff Brown349703e2010-06-22 01:27:15 -070028#define DEBUG_BATCHING 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070029
30// Log debug messages about the dispatch cycle.
Jeff Brown349703e2010-06-22 01:27:15 -070031#define DEBUG_DISPATCH_CYCLE 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070032
Jeff Brown9c3cda02010-06-15 01:31:58 -070033// Log debug messages about registrations.
Jeff Brown349703e2010-06-22 01:27:15 -070034#define DEBUG_REGISTRATION 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070035
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070036// Log debug messages about performance statistics.
Jeff Brown349703e2010-06-22 01:27:15 -070037#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070038
Jeff Brown7fbdc842010-06-17 20:52:56 -070039// Log debug messages about input event injection.
Jeff Brown349703e2010-06-22 01:27:15 -070040#define DEBUG_INJECTION 0
Jeff Brown7fbdc842010-06-17 20:52:56 -070041
Jeff Brownae9fc032010-08-18 15:51:08 -070042// Log debug messages about input event throttling.
43#define DEBUG_THROTTLING 0
44
Jeff Brownb88102f2010-09-08 11:49:43 -070045// Log debug messages about input focus tracking.
46#define DEBUG_FOCUS 0
47
48// Log debug messages about the app switch latency optimization.
49#define DEBUG_APP_SWITCH 0
50
Jeff Brownb4ff35d2011-01-02 16:37:43 -080051#include "InputDispatcher.h"
52
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070053#include <cutils/log.h>
Jeff Brownb88102f2010-09-08 11:49:43 -070054#include <ui/PowerManager.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070055
56#include <stddef.h>
57#include <unistd.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070058#include <errno.h>
59#include <limits.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070060
Jeff Brownf2f487182010-10-01 17:46:21 -070061#define INDENT " "
62#define INDENT2 " "
63
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070064namespace android {
65
Jeff Brownb88102f2010-09-08 11:49:43 -070066// Default input dispatching timeout if there is no focused application or paused window
67// from which to determine an appropriate dispatching timeout.
68const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
69
70// Amount of time to allow for all pending events to be processed when an app switch
71// key is on the way. This is used to preempt input dispatch and drop input events
72// when an application takes too long to respond and the user has pressed an app switch key.
73const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
74
Jeff Brown928e0542011-01-10 11:17:36 -080075// Amount of time to allow for an event to be dispatched (measured since its eventTime)
76// before considering it stale and dropping it.
77const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
78
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070079
Jeff Brown7fbdc842010-06-17 20:52:56 -070080static inline nsecs_t now() {
81 return systemTime(SYSTEM_TIME_MONOTONIC);
82}
83
Jeff Brownb88102f2010-09-08 11:49:43 -070084static inline const char* toString(bool value) {
85 return value ? "true" : "false";
86}
87
Jeff Brown01ce2e92010-09-26 22:20:12 -070088static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
89 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
90 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
91}
92
93static bool isValidKeyAction(int32_t action) {
94 switch (action) {
95 case AKEY_EVENT_ACTION_DOWN:
96 case AKEY_EVENT_ACTION_UP:
97 return true;
98 default:
99 return false;
100 }
101}
102
103static bool validateKeyEvent(int32_t action) {
104 if (! isValidKeyAction(action)) {
105 LOGE("Key event has invalid action code 0x%x", action);
106 return false;
107 }
108 return true;
109}
110
Jeff Brownb6997262010-10-08 22:31:17 -0700111static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700112 switch (action & AMOTION_EVENT_ACTION_MASK) {
113 case AMOTION_EVENT_ACTION_DOWN:
114 case AMOTION_EVENT_ACTION_UP:
115 case AMOTION_EVENT_ACTION_CANCEL:
116 case AMOTION_EVENT_ACTION_MOVE:
Jeff Brown01ce2e92010-09-26 22:20:12 -0700117 case AMOTION_EVENT_ACTION_OUTSIDE:
118 return true;
Jeff Brownb6997262010-10-08 22:31:17 -0700119 case AMOTION_EVENT_ACTION_POINTER_DOWN:
120 case AMOTION_EVENT_ACTION_POINTER_UP: {
121 int32_t index = getMotionEventActionPointerIndex(action);
122 return index >= 0 && size_t(index) < pointerCount;
123 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700124 default:
125 return false;
126 }
127}
128
129static bool validateMotionEvent(int32_t action, size_t pointerCount,
130 const int32_t* pointerIds) {
Jeff Brownb6997262010-10-08 22:31:17 -0700131 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700132 LOGE("Motion event has invalid action code 0x%x", action);
133 return false;
134 }
135 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
136 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
137 pointerCount, MAX_POINTERS);
138 return false;
139 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700140 BitSet32 pointerIdBits;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700141 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownc3db8582010-10-20 15:33:38 -0700142 int32_t id = pointerIds[i];
143 if (id < 0 || id > MAX_POINTER_ID) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700144 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
Jeff Brownc3db8582010-10-20 15:33:38 -0700145 id, MAX_POINTER_ID);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700146 return false;
147 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700148 if (pointerIdBits.hasBit(id)) {
149 LOGE("Motion event has duplicate pointer id %d", id);
150 return false;
151 }
152 pointerIdBits.markBit(id);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700153 }
154 return true;
155}
156
Jeff Brownfbf09772011-01-16 14:06:57 -0800157static void dumpRegion(String8& dump, const SkRegion& region) {
158 if (region.isEmpty()) {
159 dump.append("<empty>");
160 return;
161 }
162
163 bool first = true;
164 for (SkRegion::Iterator it(region); !it.done(); it.next()) {
165 if (first) {
166 first = false;
167 } else {
168 dump.append("|");
169 }
170 const SkIRect& rect = it.rect();
171 dump.appendFormat("[%d,%d][%d,%d]", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
172 }
173}
174
Jeff Brownb88102f2010-09-08 11:49:43 -0700175
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700176// --- InputDispatcher ---
177
Jeff Brown9c3cda02010-06-15 01:31:58 -0700178InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Brownb88102f2010-09-08 11:49:43 -0700179 mPolicy(policy),
Jeff Brown928e0542011-01-10 11:17:36 -0800180 mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
181 mNextUnblockedEvent(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700182 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brown01ce2e92010-09-26 22:20:12 -0700183 mFocusedWindow(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700184 mFocusedApplication(NULL),
185 mCurrentInputTargetsValid(false),
186 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700187 mLooper = new Looper(false);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700188
Jeff Brownb88102f2010-09-08 11:49:43 -0700189 mInboundQueue.headSentinel.refCount = -1;
190 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
191 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700192
Jeff Brownb88102f2010-09-08 11:49:43 -0700193 mInboundQueue.tailSentinel.refCount = -1;
194 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
195 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700196
197 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700198
Jeff Brownae9fc032010-08-18 15:51:08 -0700199 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
200 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
201 mThrottleState.lastDeviceId = -1;
202
203#if DEBUG_THROTTLING
204 mThrottleState.originalSampleCount = 0;
205 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
206#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700207}
208
209InputDispatcher::~InputDispatcher() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700210 { // acquire lock
211 AutoMutex _l(mLock);
212
213 resetKeyRepeatLocked();
Jeff Brown54a18252010-09-16 14:07:33 -0700214 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700215 drainInboundQueueLocked();
216 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700217
218 while (mConnectionsByReceiveFd.size() != 0) {
219 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
220 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700221}
222
223void InputDispatcher::dispatchOnce() {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700224 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700225 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700226
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700227 nsecs_t nextWakeupTime = LONG_LONG_MAX;
228 { // acquire lock
229 AutoMutex _l(mLock);
Jeff Brownb88102f2010-09-08 11:49:43 -0700230 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700231
Jeff Brownb88102f2010-09-08 11:49:43 -0700232 if (runCommandsLockedInterruptible()) {
233 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700234 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700235 } // release lock
236
Jeff Brownb88102f2010-09-08 11:49:43 -0700237 // Wait for callback or timeout or wake. (make sure we round up, not down)
238 nsecs_t currentTime = now();
239 int32_t timeoutMillis;
240 if (nextWakeupTime > currentTime) {
241 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
242 timeout = (timeout + 999999LL) / 1000000LL;
243 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
244 } else {
245 timeoutMillis = 0;
246 }
247
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700248 mLooper->pollOnce(timeoutMillis);
Jeff Brownb88102f2010-09-08 11:49:43 -0700249}
250
251void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
252 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
253 nsecs_t currentTime = now();
254
255 // Reset the key repeat timer whenever we disallow key events, even if the next event
256 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
257 // out of sleep.
258 if (keyRepeatTimeout < 0) {
259 resetKeyRepeatLocked();
260 }
261
Jeff Brownb88102f2010-09-08 11:49:43 -0700262 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
263 if (mDispatchFrozen) {
264#if DEBUG_FOCUS
265 LOGD("Dispatch frozen. Waiting some more.");
266#endif
267 return;
268 }
269
270 // Optimize latency of app switches.
271 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
272 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
273 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
274 if (mAppSwitchDueTime < *nextWakeupTime) {
275 *nextWakeupTime = mAppSwitchDueTime;
276 }
277
Jeff Brownb88102f2010-09-08 11:49:43 -0700278 // Ready to start a new event.
279 // If we don't already have a pending event, go grab one.
280 if (! mPendingEvent) {
281 if (mInboundQueue.isEmpty()) {
282 if (isAppSwitchDue) {
283 // The inbound queue is empty so the app switch key we were waiting
284 // for will never arrive. Stop waiting for it.
285 resetPendingAppSwitchLocked(false);
286 isAppSwitchDue = false;
287 }
288
289 // Synthesize a key repeat if appropriate.
290 if (mKeyRepeatState.lastKeyEntry) {
291 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
292 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
293 } else {
294 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
295 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
296 }
297 }
298 }
299 if (! mPendingEvent) {
300 return;
301 }
302 } else {
303 // Inbound queue has at least one entry.
304 EventEntry* entry = mInboundQueue.headSentinel.next;
305
306 // Throttle the entry if it is a move event and there are no
307 // other events behind it in the queue. Due to movement batching, additional
308 // samples may be appended to this event by the time the throttling timeout
309 // expires.
310 // TODO Make this smarter and consider throttling per device independently.
Jeff Brownb6997262010-10-08 22:31:17 -0700311 if (entry->type == EventEntry::TYPE_MOTION
312 && !isAppSwitchDue
313 && mDispatchEnabled
314 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
315 && !entry->isInjected()) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700316 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
317 int32_t deviceId = motionEntry->deviceId;
318 uint32_t source = motionEntry->source;
319 if (! isAppSwitchDue
320 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
321 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
322 && deviceId == mThrottleState.lastDeviceId
323 && source == mThrottleState.lastSource) {
324 nsecs_t nextTime = mThrottleState.lastEventTime
325 + mThrottleState.minTimeBetweenEvents;
326 if (currentTime < nextTime) {
327 // Throttle it!
328#if DEBUG_THROTTLING
329 LOGD("Throttling - Delaying motion event for "
Jeff Brown90655042010-12-02 13:50:46 -0800330 "device %d, source 0x%08x by up to %0.3fms.",
Jeff Brownb88102f2010-09-08 11:49:43 -0700331 deviceId, source, (nextTime - currentTime) * 0.000001);
332#endif
333 if (nextTime < *nextWakeupTime) {
334 *nextWakeupTime = nextTime;
335 }
336 if (mThrottleState.originalSampleCount == 0) {
337 mThrottleState.originalSampleCount =
338 motionEntry->countSamples();
339 }
340 return;
341 }
342 }
343
344#if DEBUG_THROTTLING
345 if (mThrottleState.originalSampleCount != 0) {
346 uint32_t count = motionEntry->countSamples();
347 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
348 count - mThrottleState.originalSampleCount,
349 mThrottleState.originalSampleCount, count);
350 mThrottleState.originalSampleCount = 0;
351 }
352#endif
353
354 mThrottleState.lastEventTime = entry->eventTime < currentTime
355 ? entry->eventTime : currentTime;
356 mThrottleState.lastDeviceId = deviceId;
357 mThrottleState.lastSource = source;
358 }
359
360 mInboundQueue.dequeue(entry);
361 mPendingEvent = entry;
362 }
Jeff Browne2fe69e2010-10-18 13:21:23 -0700363
364 // Poke user activity for this event.
365 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
366 pokeUserActivityLocked(mPendingEvent);
367 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700368 }
369
370 // Now we have an event to dispatch.
Jeff Brown928e0542011-01-10 11:17:36 -0800371 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Jeff Brownb88102f2010-09-08 11:49:43 -0700372 assert(mPendingEvent != NULL);
Jeff Brown54a18252010-09-16 14:07:33 -0700373 bool done = false;
Jeff Brownb6997262010-10-08 22:31:17 -0700374 DropReason dropReason = DROP_REASON_NOT_DROPPED;
375 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
376 dropReason = DROP_REASON_POLICY;
377 } else if (!mDispatchEnabled) {
378 dropReason = DROP_REASON_DISABLED;
379 }
Jeff Brown928e0542011-01-10 11:17:36 -0800380
381 if (mNextUnblockedEvent == mPendingEvent) {
382 mNextUnblockedEvent = NULL;
383 }
384
Jeff Brownb88102f2010-09-08 11:49:43 -0700385 switch (mPendingEvent->type) {
386 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
387 ConfigurationChangedEntry* typedEntry =
388 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700389 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brownb6997262010-10-08 22:31:17 -0700390 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Brownb88102f2010-09-08 11:49:43 -0700391 break;
392 }
393
394 case EventEntry::TYPE_KEY: {
395 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700396 if (isAppSwitchDue) {
397 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700398 resetPendingAppSwitchLocked(true);
Jeff Brownb6997262010-10-08 22:31:17 -0700399 isAppSwitchDue = false;
400 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
401 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700402 }
403 }
Jeff Brown928e0542011-01-10 11:17:36 -0800404 if (dropReason == DROP_REASON_NOT_DROPPED
405 && isStaleEventLocked(currentTime, typedEntry)) {
406 dropReason = DROP_REASON_STALE;
407 }
408 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
409 dropReason = DROP_REASON_BLOCKED;
410 }
Jeff Brownb6997262010-10-08 22:31:17 -0700411 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Browne20c9e02010-10-11 14:20:19 -0700412 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700413 break;
414 }
415
416 case EventEntry::TYPE_MOTION: {
417 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700418 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
419 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700420 }
Jeff Brown928e0542011-01-10 11:17:36 -0800421 if (dropReason == DROP_REASON_NOT_DROPPED
422 && isStaleEventLocked(currentTime, typedEntry)) {
423 dropReason = DROP_REASON_STALE;
424 }
425 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
426 dropReason = DROP_REASON_BLOCKED;
427 }
Jeff Brownb6997262010-10-08 22:31:17 -0700428 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Browne20c9e02010-10-11 14:20:19 -0700429 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700430 break;
431 }
432
433 default:
434 assert(false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700435 break;
436 }
437
Jeff Brown54a18252010-09-16 14:07:33 -0700438 if (done) {
Jeff Brownb6997262010-10-08 22:31:17 -0700439 if (dropReason != DROP_REASON_NOT_DROPPED) {
440 dropInboundEventLocked(mPendingEvent, dropReason);
441 }
442
Jeff Brown54a18252010-09-16 14:07:33 -0700443 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700444 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
445 }
446}
447
448bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
449 bool needWake = mInboundQueue.isEmpty();
450 mInboundQueue.enqueueAtTail(entry);
451
452 switch (entry->type) {
Jeff Brownb6997262010-10-08 22:31:17 -0700453 case EventEntry::TYPE_KEY: {
Jeff Brown928e0542011-01-10 11:17:36 -0800454 // Optimize app switch latency.
455 // If the application takes too long to catch up then we drop all events preceding
456 // the app switch key.
Jeff Brownb6997262010-10-08 22:31:17 -0700457 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
458 if (isAppSwitchKeyEventLocked(keyEntry)) {
459 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
460 mAppSwitchSawKeyDown = true;
461 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
462 if (mAppSwitchSawKeyDown) {
463#if DEBUG_APP_SWITCH
464 LOGD("App switch is pending!");
465#endif
466 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
467 mAppSwitchSawKeyDown = false;
468 needWake = true;
469 }
470 }
471 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700472 break;
473 }
Jeff Brown928e0542011-01-10 11:17:36 -0800474
475 case EventEntry::TYPE_MOTION: {
476 // Optimize case where the current application is unresponsive and the user
477 // decides to touch a window in a different application.
478 // If the application takes too long to catch up then we drop all events preceding
479 // the touch into the other window.
480 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
481 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
482 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
483 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
484 && mInputTargetWaitApplication != NULL) {
485 int32_t x = int32_t(motionEntry->firstSample.pointerCoords[0].x);
486 int32_t y = int32_t(motionEntry->firstSample.pointerCoords[0].y);
487 const InputWindow* touchedWindow = findTouchedWindowAtLocked(x, y);
488 if (touchedWindow
489 && touchedWindow->inputWindowHandle != NULL
490 && touchedWindow->inputWindowHandle->getInputApplicationHandle()
491 != mInputTargetWaitApplication) {
492 // User touched a different application than the one we are waiting on.
493 // Flag the event, and start pruning the input queue.
494 mNextUnblockedEvent = motionEntry;
495 needWake = true;
496 }
497 }
498 break;
499 }
Jeff Brownb6997262010-10-08 22:31:17 -0700500 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700501
502 return needWake;
503}
504
Jeff Brown928e0542011-01-10 11:17:36 -0800505const InputWindow* InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
506 // Traverse windows from front to back to find touched window.
507 size_t numWindows = mWindows.size();
508 for (size_t i = 0; i < numWindows; i++) {
509 const InputWindow* window = & mWindows.editItemAt(i);
510 int32_t flags = window->layoutParamsFlags;
511
512 if (window->visible) {
513 if (!(flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
514 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
515 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
Jeff Brownfbf09772011-01-16 14:06:57 -0800516 if (isTouchModal || window->touchableRegionContainsPoint(x, y)) {
Jeff Brown928e0542011-01-10 11:17:36 -0800517 // Found window.
518 return window;
519 }
520 }
521 }
522
523 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
524 // Error window is on top but not visible, so touch is dropped.
525 return NULL;
526 }
527 }
528 return NULL;
529}
530
Jeff Brownb6997262010-10-08 22:31:17 -0700531void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
532 const char* reason;
533 switch (dropReason) {
534 case DROP_REASON_POLICY:
Jeff Browne20c9e02010-10-11 14:20:19 -0700535#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown3122e442010-10-11 23:32:49 -0700536 LOGD("Dropped event because policy consumed it.");
Jeff Browne20c9e02010-10-11 14:20:19 -0700537#endif
Jeff Brown3122e442010-10-11 23:32:49 -0700538 reason = "inbound event was dropped because the policy consumed it";
Jeff Brownb6997262010-10-08 22:31:17 -0700539 break;
540 case DROP_REASON_DISABLED:
541 LOGI("Dropped event because input dispatch is disabled.");
542 reason = "inbound event was dropped because input dispatch is disabled";
543 break;
544 case DROP_REASON_APP_SWITCH:
545 LOGI("Dropped event because of pending overdue app switch.");
546 reason = "inbound event was dropped because of pending overdue app switch";
547 break;
Jeff Brown928e0542011-01-10 11:17:36 -0800548 case DROP_REASON_BLOCKED:
549 LOGI("Dropped event because the current application is not responding and the user "
550 "has started interating with a different application.");
551 reason = "inbound event was dropped because the current application is not responding "
552 "and the user has started interating with a different application";
553 break;
554 case DROP_REASON_STALE:
555 LOGI("Dropped event because it is stale.");
556 reason = "inbound event was dropped because it is stale";
557 break;
Jeff Brownb6997262010-10-08 22:31:17 -0700558 default:
559 assert(false);
560 return;
561 }
562
563 switch (entry->type) {
564 case EventEntry::TYPE_KEY:
565 synthesizeCancelationEventsForAllConnectionsLocked(
566 InputState::CANCEL_NON_POINTER_EVENTS, reason);
567 break;
568 case EventEntry::TYPE_MOTION: {
569 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
570 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
571 synthesizeCancelationEventsForAllConnectionsLocked(
572 InputState::CANCEL_POINTER_EVENTS, reason);
573 } else {
574 synthesizeCancelationEventsForAllConnectionsLocked(
575 InputState::CANCEL_NON_POINTER_EVENTS, reason);
576 }
577 break;
578 }
579 }
580}
581
582bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700583 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
584}
585
Jeff Brownb6997262010-10-08 22:31:17 -0700586bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
587 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
588 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Browne20c9e02010-10-11 14:20:19 -0700589 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brownb6997262010-10-08 22:31:17 -0700590 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
591}
592
Jeff Brownb88102f2010-09-08 11:49:43 -0700593bool InputDispatcher::isAppSwitchPendingLocked() {
594 return mAppSwitchDueTime != LONG_LONG_MAX;
595}
596
Jeff Brownb88102f2010-09-08 11:49:43 -0700597void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
598 mAppSwitchDueTime = LONG_LONG_MAX;
599
600#if DEBUG_APP_SWITCH
601 if (handled) {
602 LOGD("App switch has arrived.");
603 } else {
604 LOGD("App switch was abandoned.");
605 }
606#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700607}
608
Jeff Brown928e0542011-01-10 11:17:36 -0800609bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
610 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
611}
612
Jeff Brown9c3cda02010-06-15 01:31:58 -0700613bool InputDispatcher::runCommandsLockedInterruptible() {
614 if (mCommandQueue.isEmpty()) {
615 return false;
616 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700617
Jeff Brown9c3cda02010-06-15 01:31:58 -0700618 do {
619 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
620
621 Command command = commandEntry->command;
622 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
623
Jeff Brown7fbdc842010-06-17 20:52:56 -0700624 commandEntry->connection.clear();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700625 mAllocator.releaseCommandEntry(commandEntry);
626 } while (! mCommandQueue.isEmpty());
627 return true;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700628}
629
Jeff Brown9c3cda02010-06-15 01:31:58 -0700630InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
631 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
632 mCommandQueue.enqueueAtTail(commandEntry);
633 return commandEntry;
634}
635
Jeff Brownb88102f2010-09-08 11:49:43 -0700636void InputDispatcher::drainInboundQueueLocked() {
637 while (! mInboundQueue.isEmpty()) {
638 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700639 releaseInboundEventLocked(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700640 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700641}
642
Jeff Brown54a18252010-09-16 14:07:33 -0700643void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700644 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700645 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700646 mPendingEvent = NULL;
647 }
648}
649
Jeff Brown54a18252010-09-16 14:07:33 -0700650void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700651 InjectionState* injectionState = entry->injectionState;
652 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700653#if DEBUG_DISPATCH_CYCLE
Jeff Brown01ce2e92010-09-26 22:20:12 -0700654 LOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700655#endif
656 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
657 }
658 mAllocator.releaseEventEntry(entry);
659}
660
Jeff Brownb88102f2010-09-08 11:49:43 -0700661void InputDispatcher::resetKeyRepeatLocked() {
662 if (mKeyRepeatState.lastKeyEntry) {
663 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
664 mKeyRepeatState.lastKeyEntry = NULL;
665 }
666}
667
668InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brownb21fb102010-09-07 10:44:57 -0700669 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown349703e2010-06-22 01:27:15 -0700670 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
671
Jeff Brown349703e2010-06-22 01:27:15 -0700672 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Browne20c9e02010-10-11 14:20:19 -0700673 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
674 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700675 if (entry->refCount == 1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700676 mAllocator.recycleKeyEntry(entry);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700677 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700678 entry->policyFlags = policyFlags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700679 entry->repeatCount += 1;
680 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700681 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700682 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700683 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700684 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700685
686 mKeyRepeatState.lastKeyEntry = newEntry;
687 mAllocator.releaseKeyEntry(entry);
688
689 entry = newEntry;
690 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700691 entry->syntheticRepeat = true;
692
693 // Increment reference count since we keep a reference to the event in
694 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
695 entry->refCount += 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700696
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700697 if (entry->repeatCount == 1) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700698 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700699 }
700
Jeff Brownb21fb102010-09-07 10:44:57 -0700701 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700702 return entry;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700703}
704
Jeff Brownb88102f2010-09-08 11:49:43 -0700705bool InputDispatcher::dispatchConfigurationChangedLocked(
706 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700707#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownb88102f2010-09-08 11:49:43 -0700708 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
709#endif
710
711 // Reset key repeating in case a keyboard device was added or removed or something.
712 resetKeyRepeatLocked();
713
714 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
715 CommandEntry* commandEntry = postCommandLocked(
716 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
717 commandEntry->eventTime = entry->eventTime;
718 return true;
719}
720
721bool InputDispatcher::dispatchKeyLocked(
722 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Browne20c9e02010-10-11 14:20:19 -0700723 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700724 // Preprocessing.
725 if (! entry->dispatchInProgress) {
726 if (entry->repeatCount == 0
727 && entry->action == AKEY_EVENT_ACTION_DOWN
728 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
729 && !entry->isInjected()) {
730 if (mKeyRepeatState.lastKeyEntry
731 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
732 // We have seen two identical key downs in a row which indicates that the device
733 // driver is automatically generating key repeats itself. We take note of the
734 // repeat here, but we disable our own next key repeat timer since it is clear that
735 // we will not need to synthesize key repeats ourselves.
736 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
737 resetKeyRepeatLocked();
738 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
739 } else {
740 // Not a repeat. Save key down state in case we do see a repeat later.
741 resetKeyRepeatLocked();
742 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
743 }
744 mKeyRepeatState.lastKeyEntry = entry;
745 entry->refCount += 1;
746 } else if (! entry->syntheticRepeat) {
747 resetKeyRepeatLocked();
748 }
749
750 entry->dispatchInProgress = true;
751 resetTargetsLocked();
752
753 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
754 }
755
Jeff Brown54a18252010-09-16 14:07:33 -0700756 // Give the policy a chance to intercept the key.
757 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700758 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brown54a18252010-09-16 14:07:33 -0700759 CommandEntry* commandEntry = postCommandLocked(
760 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Browne20c9e02010-10-11 14:20:19 -0700761 if (mFocusedWindow) {
Jeff Brown928e0542011-01-10 11:17:36 -0800762 commandEntry->inputWindowHandle = mFocusedWindow->inputWindowHandle;
Jeff Brown54a18252010-09-16 14:07:33 -0700763 }
764 commandEntry->keyEntry = entry;
765 entry->refCount += 1;
766 return false; // wait for the command to run
767 } else {
768 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
769 }
770 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700771 if (*dropReason == DROP_REASON_NOT_DROPPED) {
772 *dropReason = DROP_REASON_POLICY;
773 }
Jeff Brown54a18252010-09-16 14:07:33 -0700774 }
775
776 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700777 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700778 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700779 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
780 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700781 return true;
782 }
783
Jeff Brownb88102f2010-09-08 11:49:43 -0700784 // Identify targets.
785 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700786 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
787 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700788 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
789 return false;
790 }
791
792 setInjectionResultLocked(entry, injectionResult);
793 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
794 return true;
795 }
796
797 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700798 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700799 }
800
801 // Dispatch the key.
802 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700803 return true;
804}
805
806void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
807#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800808 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brownb88102f2010-09-08 11:49:43 -0700809 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
Jeff Browne46a0a42010-11-02 17:58:22 -0700810 "repeatCount=%d, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700811 prefix,
812 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
813 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Jeff Browne46a0a42010-11-02 17:58:22 -0700814 entry->repeatCount, entry->downTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700815#endif
816}
817
818bool InputDispatcher::dispatchMotionLocked(
Jeff Browne20c9e02010-10-11 14:20:19 -0700819 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700820 // Preprocessing.
821 if (! entry->dispatchInProgress) {
822 entry->dispatchInProgress = true;
823 resetTargetsLocked();
824
825 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
826 }
827
Jeff Brown54a18252010-09-16 14:07:33 -0700828 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700829 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700830 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700831 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
832 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700833 return true;
834 }
835
Jeff Brownb88102f2010-09-08 11:49:43 -0700836 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
837
838 // Identify targets.
839 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700840 int32_t injectionResult;
841 if (isPointerEvent) {
842 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700843 injectionResult = findTouchedWindowTargetsLocked(currentTime,
844 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700845 } else {
846 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700847 injectionResult = findFocusedWindowTargetsLocked(currentTime,
848 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700849 }
850 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
851 return false;
852 }
853
854 setInjectionResultLocked(entry, injectionResult);
855 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
856 return true;
857 }
858
859 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700860 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700861 }
862
863 // Dispatch the motion.
864 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700865 return true;
866}
867
868
869void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
870#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800871 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700872 "action=0x%x, flags=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700873 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700874 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700875 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
876 entry->action, entry->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700877 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
878 entry->downTime);
879
880 // Print the most recent sample that we have available, this may change due to batching.
881 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700882 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700883 for (; sample->next != NULL; sample = sample->next) {
884 sampleCount += 1;
885 }
886 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -0700887 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700888 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700889 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700890 i, entry->pointerIds[i],
Jeff Brown8d608662010-08-30 03:02:23 -0700891 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
892 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
893 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
894 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
895 sample->pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700896 }
897
898 // Keep in mind that due to batching, it is possible for the number of samples actually
899 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700900 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700901 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
902 }
903#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700904}
905
906void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
907 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
908#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -0700909 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700910 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700911 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700912#endif
913
Jeff Brown9c3cda02010-06-15 01:31:58 -0700914 assert(eventEntry->dispatchInProgress); // should already have been set to true
915
Jeff Browne2fe69e2010-10-18 13:21:23 -0700916 pokeUserActivityLocked(eventEntry);
917
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700918 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
919 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
920
Jeff Brown519e0242010-09-15 15:18:56 -0700921 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700922 if (connectionIndex >= 0) {
923 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700924 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700925 resumeWithAppendedMotionSample);
926 } else {
Jeff Brownb6997262010-10-08 22:31:17 -0700927#if DEBUG_FOCUS
928 LOGD("Dropping event delivery to target with channel '%s' because it "
929 "is no longer registered with the input dispatcher.",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700930 inputTarget.inputChannel->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -0700931#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700932 }
933 }
934}
935
Jeff Brown54a18252010-09-16 14:07:33 -0700936void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700937 mCurrentInputTargetsValid = false;
938 mCurrentInputTargets.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700939 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Jeff Brown928e0542011-01-10 11:17:36 -0800940 mInputTargetWaitApplication.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700941}
942
Jeff Brown01ce2e92010-09-26 22:20:12 -0700943void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700944 mCurrentInputTargetsValid = true;
945}
946
947int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
948 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
949 nsecs_t* nextWakeupTime) {
950 if (application == NULL && window == NULL) {
951 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
952#if DEBUG_FOCUS
953 LOGD("Waiting for system to become ready for input.");
954#endif
955 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
956 mInputTargetWaitStartTime = currentTime;
957 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
958 mInputTargetWaitTimeoutExpired = false;
Jeff Brown928e0542011-01-10 11:17:36 -0800959 mInputTargetWaitApplication.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700960 }
961 } else {
962 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
963#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700964 LOGD("Waiting for application to become ready for input: %s",
965 getApplicationWindowLabelLocked(application, window).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700966#endif
967 nsecs_t timeout = window ? window->dispatchingTimeout :
968 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
969
970 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
971 mInputTargetWaitStartTime = currentTime;
972 mInputTargetWaitTimeoutTime = currentTime + timeout;
973 mInputTargetWaitTimeoutExpired = false;
Jeff Brown928e0542011-01-10 11:17:36 -0800974 mInputTargetWaitApplication.clear();
975
976 if (window && window->inputWindowHandle != NULL) {
977 mInputTargetWaitApplication =
978 window->inputWindowHandle->getInputApplicationHandle();
979 }
980 if (mInputTargetWaitApplication == NULL && application) {
981 mInputTargetWaitApplication = application->inputApplicationHandle;
982 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700983 }
984 }
985
986 if (mInputTargetWaitTimeoutExpired) {
987 return INPUT_EVENT_INJECTION_TIMED_OUT;
988 }
989
990 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown519e0242010-09-15 15:18:56 -0700991 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700992
993 // Force poll loop to wake up immediately on next iteration once we get the
994 // ANR response back from the policy.
995 *nextWakeupTime = LONG_LONG_MIN;
996 return INPUT_EVENT_INJECTION_PENDING;
997 } else {
998 // Force poll loop to wake up when timeout is due.
999 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1000 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1001 }
1002 return INPUT_EVENT_INJECTION_PENDING;
1003 }
1004}
1005
Jeff Brown519e0242010-09-15 15:18:56 -07001006void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1007 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001008 if (newTimeout > 0) {
1009 // Extend the timeout.
1010 mInputTargetWaitTimeoutTime = now() + newTimeout;
1011 } else {
1012 // Give up.
1013 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -07001014
Jeff Brown01ce2e92010-09-26 22:20:12 -07001015 // Release the touch targets.
1016 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07001017
Jeff Brown519e0242010-09-15 15:18:56 -07001018 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -07001019 if (inputChannel.get()) {
1020 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1021 if (connectionIndex >= 0) {
1022 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown00045a72010-12-09 18:10:30 -08001023 if (connection->status == Connection::STATUS_NORMAL) {
1024 synthesizeCancelationEventsForConnectionLocked(
1025 connection, InputState::CANCEL_ALL_EVENTS,
1026 "application not responding");
1027 }
Jeff Browndc3e0052010-09-16 11:02:16 -07001028 }
Jeff Brown519e0242010-09-15 15:18:56 -07001029 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001030 }
1031}
1032
Jeff Brown519e0242010-09-15 15:18:56 -07001033nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -07001034 nsecs_t currentTime) {
1035 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1036 return currentTime - mInputTargetWaitStartTime;
1037 }
1038 return 0;
1039}
1040
1041void InputDispatcher::resetANRTimeoutsLocked() {
1042#if DEBUG_FOCUS
1043 LOGD("Resetting ANR timeouts.");
1044#endif
1045
Jeff Brownb88102f2010-09-08 11:49:43 -07001046 // Reset input target wait timeout.
1047 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
1048}
1049
Jeff Brown01ce2e92010-09-26 22:20:12 -07001050int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
1051 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001052 mCurrentInputTargets.clear();
1053
1054 int32_t injectionResult;
1055
1056 // If there is no currently focused window and no focused application
1057 // then drop the event.
1058 if (! mFocusedWindow) {
1059 if (mFocusedApplication) {
1060#if DEBUG_FOCUS
1061 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001062 "focused application that may eventually add a window: %s.",
1063 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001064#endif
1065 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1066 mFocusedApplication, NULL, nextWakeupTime);
1067 goto Unresponsive;
1068 }
1069
1070 LOGI("Dropping event because there is no focused window or focused application.");
1071 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1072 goto Failed;
1073 }
1074
1075 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001076 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001077 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1078 goto Failed;
1079 }
1080
1081 // If the currently focused window is paused then keep waiting.
1082 if (mFocusedWindow->paused) {
1083#if DEBUG_FOCUS
1084 LOGD("Waiting because focused window is paused.");
1085#endif
1086 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1087 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1088 goto Unresponsive;
1089 }
1090
Jeff Brown519e0242010-09-15 15:18:56 -07001091 // If the currently focused window is still working on previous events then keep waiting.
1092 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
1093#if DEBUG_FOCUS
1094 LOGD("Waiting because focused window still processing previous input.");
1095#endif
1096 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1097 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1098 goto Unresponsive;
1099 }
1100
Jeff Brownb88102f2010-09-08 11:49:43 -07001101 // Success! Output targets.
1102 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001103 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001104
1105 // Done.
1106Failed:
1107Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001108 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1109 updateDispatchStatisticsLocked(currentTime, entry,
1110 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001111#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -07001112 LOGD("findFocusedWindow finished: injectionResult=%d, "
1113 "timeSpendWaitingForApplication=%0.1fms",
1114 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001115#endif
1116 return injectionResult;
1117}
1118
Jeff Brown01ce2e92010-09-26 22:20:12 -07001119int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1120 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001121 enum InjectionPermission {
1122 INJECTION_PERMISSION_UNKNOWN,
1123 INJECTION_PERMISSION_GRANTED,
1124 INJECTION_PERMISSION_DENIED
1125 };
1126
Jeff Brownb88102f2010-09-08 11:49:43 -07001127 mCurrentInputTargets.clear();
1128
1129 nsecs_t startTime = now();
1130
1131 // For security reasons, we defer updating the touch state until we are sure that
1132 // event injection will be allowed.
1133 //
1134 // FIXME In the original code, screenWasOff could never be set to true.
1135 // The reason is that the POLICY_FLAG_WOKE_HERE
1136 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1137 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1138 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1139 // events upon which no preprocessing took place. So policyFlags was always 0.
1140 // In the new native input dispatcher we're a bit more careful about event
1141 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1142 // Unfortunately we obtain undesirable behavior.
1143 //
1144 // Here's what happens:
1145 //
1146 // When the device dims in anticipation of going to sleep, touches
1147 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1148 // the device to brighten and reset the user activity timer.
1149 // Touches on other windows (such as the launcher window)
1150 // are dropped. Then after a moment, the device goes to sleep. Oops.
1151 //
1152 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1153 // instead of POLICY_FLAG_WOKE_HERE...
1154 //
1155 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1156
1157 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001158 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001159
1160 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001161 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1162 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Jeff Brown95712852011-01-04 19:41:59 -08001163 bool isSplit, wrongDevice;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001164 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1165 mTempTouchState.reset();
1166 mTempTouchState.down = true;
Jeff Brown95712852011-01-04 19:41:59 -08001167 mTempTouchState.deviceId = entry->deviceId;
Jeff Brown58a2da82011-01-25 16:02:22 -08001168 mTempTouchState.source = entry->source;
Jeff Brown95712852011-01-04 19:41:59 -08001169 isSplit = false;
1170 wrongDevice = false;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001171 } else {
1172 mTempTouchState.copyFrom(mTouchState);
Jeff Brown95712852011-01-04 19:41:59 -08001173 isSplit = mTempTouchState.split;
Jeff Brown58a2da82011-01-25 16:02:22 -08001174 wrongDevice = mTempTouchState.down
1175 && (mTempTouchState.deviceId != entry->deviceId
1176 || mTempTouchState.source != entry->source);
Jeff Brown95712852011-01-04 19:41:59 -08001177 if (wrongDevice) {
1178#if DEBUG_INPUT_DISPATCHER_POLICY
1179 LOGD("Dropping event because a pointer for a different device is already down.");
1180#endif
1181 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1182 goto Failed;
1183 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001184 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001185
Jeff Brown01ce2e92010-09-26 22:20:12 -07001186 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1187 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1188 /* Case 1: New splittable pointer going down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001189
Jeff Brown01ce2e92010-09-26 22:20:12 -07001190 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1191 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1192 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1193 const InputWindow* newTouchedWindow = NULL;
1194 const InputWindow* topErrorWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07001195
1196 // Traverse windows from front to back to find touched window and outside targets.
1197 size_t numWindows = mWindows.size();
1198 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001199 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001200 int32_t flags = window->layoutParamsFlags;
1201
1202 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1203 if (! topErrorWindow) {
1204 topErrorWindow = window;
1205 }
1206 }
1207
1208 if (window->visible) {
1209 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1210 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1211 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
Jeff Brownfbf09772011-01-16 14:06:57 -08001212 if (isTouchModal || window->touchableRegionContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001213 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1214 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001215 }
1216 break; // found touched window, exit window loop
1217 }
1218 }
1219
Jeff Brown01ce2e92010-09-26 22:20:12 -07001220 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1221 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001222 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1223 if (isWindowObscuredAtPointLocked(window, x, y)) {
1224 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1225 }
1226
1227 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001228 }
1229 }
1230 }
1231
1232 // If there is an error window but it is not taking focus (typically because
1233 // it is invisible) then wait for it. Any other focused window may in
1234 // fact be in ANR state.
1235 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1236#if DEBUG_FOCUS
1237 LOGD("Waiting because system error window is pending.");
1238#endif
1239 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1240 NULL, NULL, nextWakeupTime);
1241 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1242 goto Unresponsive;
1243 }
1244
Jeff Brown01ce2e92010-09-26 22:20:12 -07001245 // Figure out whether splitting will be allowed for this window.
Jeff Brown46e75292010-11-10 16:53:45 -08001246 if (newTouchedWindow && newTouchedWindow->supportsSplitTouch()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001247 // New window supports splitting.
1248 isSplit = true;
1249 } else if (isSplit) {
1250 // New window does not support splitting but we have already split events.
1251 // Assign the pointer to the first foreground window we find.
1252 // (May be NULL which is why we put this code block before the next check.)
1253 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1254 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001255
Jeff Brownb88102f2010-09-08 11:49:43 -07001256 // If we did not find a touched window then fail.
1257 if (! newTouchedWindow) {
1258 if (mFocusedApplication) {
1259#if DEBUG_FOCUS
1260 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001261 "focused application that may eventually add a new window: %s.",
1262 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001263#endif
1264 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1265 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001266 goto Unresponsive;
1267 }
1268
1269 LOGI("Dropping event because there is no touched window or focused application.");
1270 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001271 goto Failed;
1272 }
1273
Jeff Brown19dfc832010-10-05 12:26:23 -07001274 // Set target flags.
1275 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1276 if (isSplit) {
1277 targetFlags |= InputTarget::FLAG_SPLIT;
1278 }
1279 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1280 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1281 }
1282
Jeff Brown01ce2e92010-09-26 22:20:12 -07001283 // Update the temporary touch state.
1284 BitSet32 pointerIds;
1285 if (isSplit) {
1286 uint32_t pointerId = entry->pointerIds[pointerIndex];
1287 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001288 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001289 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001290 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001291 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001292
1293 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001294 if (! mTempTouchState.down) {
Jeff Brown76860e32010-10-25 17:37:46 -07001295#if DEBUG_INPUT_DISPATCHER_POLICY
1296 LOGD("Dropping event because the pointer is not down or we previously "
1297 "dropped the pointer down event.");
1298#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001299 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001300 goto Failed;
1301 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001302 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001303
Jeff Brown01ce2e92010-09-26 22:20:12 -07001304 // Check permission to inject into all touched foreground windows and ensure there
1305 // is at least one touched foreground window.
1306 {
1307 bool haveForegroundWindow = false;
1308 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1309 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1310 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1311 haveForegroundWindow = true;
1312 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1313 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1314 injectionPermission = INJECTION_PERMISSION_DENIED;
1315 goto Failed;
1316 }
1317 }
1318 }
1319 if (! haveForegroundWindow) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001320#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown01ce2e92010-09-26 22:20:12 -07001321 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001322#endif
1323 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001324 goto Failed;
1325 }
1326
Jeff Brown01ce2e92010-09-26 22:20:12 -07001327 // Permission granted to injection into all touched foreground windows.
1328 injectionPermission = INJECTION_PERMISSION_GRANTED;
1329 }
Jeff Brown519e0242010-09-15 15:18:56 -07001330
Jeff Brown01ce2e92010-09-26 22:20:12 -07001331 // Ensure all touched foreground windows are ready for new input.
1332 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1333 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1334 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1335 // If the touched window is paused then keep waiting.
1336 if (touchedWindow.window->paused) {
1337#if DEBUG_INPUT_DISPATCHER_POLICY
1338 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001339#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001340 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1341 NULL, touchedWindow.window, nextWakeupTime);
1342 goto Unresponsive;
1343 }
1344
1345 // If the touched window is still working on previous events then keep waiting.
1346 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1347#if DEBUG_FOCUS
1348 LOGD("Waiting because touched window still processing previous input.");
1349#endif
1350 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1351 NULL, touchedWindow.window, nextWakeupTime);
1352 goto Unresponsive;
1353 }
1354 }
1355 }
1356
1357 // If this is the first pointer going down and the touched window has a wallpaper
1358 // then also add the touched wallpaper windows so they are locked in for the duration
1359 // of the touch gesture.
1360 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1361 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1362 if (foregroundWindow->hasWallpaper) {
1363 for (size_t i = 0; i < mWindows.size(); i++) {
1364 const InputWindow* window = & mWindows[i];
1365 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001366 mTempTouchState.addOrUpdateWindow(window,
1367 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001368 }
1369 }
1370 }
1371 }
1372
Jeff Brownb88102f2010-09-08 11:49:43 -07001373 // Success! Output targets.
1374 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001375
Jeff Brown01ce2e92010-09-26 22:20:12 -07001376 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1377 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1378 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1379 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001380 }
1381
Jeff Brown01ce2e92010-09-26 22:20:12 -07001382 // Drop the outside touch window since we will not care about them in the next iteration.
1383 mTempTouchState.removeOutsideTouchWindows();
1384
Jeff Brownb88102f2010-09-08 11:49:43 -07001385Failed:
1386 // Check injection permission once and for all.
1387 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001388 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001389 injectionPermission = INJECTION_PERMISSION_GRANTED;
1390 } else {
1391 injectionPermission = INJECTION_PERMISSION_DENIED;
1392 }
1393 }
1394
1395 // Update final pieces of touch state if the injector had permission.
1396 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown95712852011-01-04 19:41:59 -08001397 if (!wrongDevice) {
1398 if (maskedAction == AMOTION_EVENT_ACTION_UP
1399 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1400 // All pointers up or canceled.
1401 mTempTouchState.reset();
1402 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1403 // First pointer went down.
1404 if (mTouchState.down) {
Jeff Brownb6997262010-10-08 22:31:17 -07001405#if DEBUG_FOCUS
Jeff Brown95712852011-01-04 19:41:59 -08001406 LOGD("Pointer down received while already down.");
Jeff Brownb6997262010-10-08 22:31:17 -07001407#endif
Jeff Brown95712852011-01-04 19:41:59 -08001408 }
1409 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1410 // One pointer went up.
1411 if (isSplit) {
1412 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1413 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001414
Jeff Brown95712852011-01-04 19:41:59 -08001415 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1416 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1417 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1418 touchedWindow.pointerIds.clearBit(pointerId);
1419 if (touchedWindow.pointerIds.isEmpty()) {
1420 mTempTouchState.windows.removeAt(i);
1421 continue;
1422 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001423 }
Jeff Brown95712852011-01-04 19:41:59 -08001424 i += 1;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001425 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001426 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001427 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001428
Jeff Brown95712852011-01-04 19:41:59 -08001429 // Save changes to touch state.
1430 mTouchState.copyFrom(mTempTouchState);
1431 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001432 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001433#if DEBUG_FOCUS
1434 LOGD("Not updating touch focus because injection was denied.");
1435#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001436 }
1437
1438Unresponsive:
Jeff Brown120a4592010-10-27 18:43:51 -07001439 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1440 mTempTouchState.reset();
1441
Jeff Brown519e0242010-09-15 15:18:56 -07001442 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1443 updateDispatchStatisticsLocked(currentTime, entry,
1444 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001445#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001446 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1447 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001448 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001449#endif
1450 return injectionResult;
1451}
1452
Jeff Brown01ce2e92010-09-26 22:20:12 -07001453void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1454 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001455 mCurrentInputTargets.push();
1456
1457 InputTarget& target = mCurrentInputTargets.editTop();
1458 target.inputChannel = window->inputChannel;
1459 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001460 target.xOffset = - window->frameLeft;
1461 target.yOffset = - window->frameTop;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001462 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001463}
1464
1465void InputDispatcher::addMonitoringTargetsLocked() {
1466 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1467 mCurrentInputTargets.push();
1468
1469 InputTarget& target = mCurrentInputTargets.editTop();
1470 target.inputChannel = mMonitoringChannels[i];
1471 target.flags = 0;
Jeff Brownb88102f2010-09-08 11:49:43 -07001472 target.xOffset = 0;
1473 target.yOffset = 0;
1474 }
1475}
1476
1477bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001478 const InjectionState* injectionState) {
1479 if (injectionState
Jeff Brownb6997262010-10-08 22:31:17 -07001480 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1481 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1482 if (window) {
1483 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1484 "with input channel %s owned by uid %d",
1485 injectionState->injectorPid, injectionState->injectorUid,
1486 window->inputChannel->getName().string(),
1487 window->ownerUid);
1488 } else {
1489 LOGW("Permission denied: injecting event from pid %d uid %d",
1490 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001491 }
Jeff Brownb6997262010-10-08 22:31:17 -07001492 return false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001493 }
1494 return true;
1495}
1496
Jeff Brown19dfc832010-10-05 12:26:23 -07001497bool InputDispatcher::isWindowObscuredAtPointLocked(
1498 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07001499 size_t numWindows = mWindows.size();
1500 for (size_t i = 0; i < numWindows; i++) {
1501 const InputWindow* other = & mWindows.itemAt(i);
1502 if (other == window) {
1503 break;
1504 }
Jeff Brown19dfc832010-10-05 12:26:23 -07001505 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001506 return true;
1507 }
1508 }
1509 return false;
1510}
1511
Jeff Brown519e0242010-09-15 15:18:56 -07001512bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1513 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1514 if (connectionIndex >= 0) {
1515 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1516 return connection->outboundQueue.isEmpty();
1517 } else {
1518 return true;
1519 }
1520}
1521
1522String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1523 const InputWindow* window) {
1524 if (application) {
1525 if (window) {
1526 String8 label(application->name);
1527 label.append(" - ");
1528 label.append(window->name);
1529 return label;
1530 } else {
1531 return application->name;
1532 }
1533 } else if (window) {
1534 return window->name;
1535 } else {
1536 return String8("<unknown application or window>");
1537 }
1538}
1539
Jeff Browne2fe69e2010-10-18 13:21:23 -07001540void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1541 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brown4d396052010-10-29 21:50:21 -07001542 switch (eventEntry->type) {
1543 case EventEntry::TYPE_MOTION: {
Jeff Browne2fe69e2010-10-18 13:21:23 -07001544 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Brown4d396052010-10-29 21:50:21 -07001545 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1546 return;
1547 }
1548
Jeff Browne2fe69e2010-10-18 13:21:23 -07001549 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
Joe Onorato1a542c72010-11-08 09:48:20 -08001550 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001551 }
Jeff Brown4d396052010-10-29 21:50:21 -07001552 break;
1553 }
1554 case EventEntry::TYPE_KEY: {
1555 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1556 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1557 return;
1558 }
1559 break;
1560 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001561 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001562
Jeff Brownb88102f2010-09-08 11:49:43 -07001563 CommandEntry* commandEntry = postCommandLocked(
1564 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Browne2fe69e2010-10-18 13:21:23 -07001565 commandEntry->eventTime = eventEntry->eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001566 commandEntry->userActivityEventType = eventType;
1567}
1568
Jeff Brown7fbdc842010-06-17 20:52:56 -07001569void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1570 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001571 bool resumeWithAppendedMotionSample) {
1572#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001573 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001574 "xOffset=%f, yOffset=%f, "
Jeff Brown83c09682010-12-23 17:50:18 -08001575 "pointerIds=0x%x, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001576 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001577 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001578 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brown83c09682010-12-23 17:50:18 -08001579 inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001580 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001581#endif
1582
Jeff Brown01ce2e92010-09-26 22:20:12 -07001583 // Make sure we are never called for streaming when splitting across multiple windows.
1584 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1585 assert(! (resumeWithAppendedMotionSample && isSplit));
1586
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001587 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001588 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001589 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb6997262010-10-08 22:31:17 -07001590#if DEBUG_DISPATCH_CYCLE
1591 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001592 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brownb6997262010-10-08 22:31:17 -07001593#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001594 return;
1595 }
1596
Jeff Brown01ce2e92010-09-26 22:20:12 -07001597 // Split a motion event if needed.
1598 if (isSplit) {
1599 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1600
1601 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1602 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1603 MotionEntry* splitMotionEntry = splitMotionEvent(
1604 originalMotionEntry, inputTarget->pointerIds);
Jeff Brown58a2da82011-01-25 16:02:22 -08001605 if (!splitMotionEntry) {
1606 return; // split event was dropped
1607 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001608#if DEBUG_FOCUS
1609 LOGD("channel '%s' ~ Split motion event.",
1610 connection->getInputChannelName());
1611 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1612#endif
1613 eventEntry = splitMotionEntry;
1614 }
1615 }
1616
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001617 // Resume the dispatch cycle with a freshly appended motion sample.
1618 // First we check that the last dispatch entry in the outbound queue is for the same
1619 // motion event to which we appended the motion sample. If we find such a dispatch
1620 // entry, and if it is currently in progress then we try to stream the new sample.
1621 bool wasEmpty = connection->outboundQueue.isEmpty();
1622
1623 if (! wasEmpty && resumeWithAppendedMotionSample) {
1624 DispatchEntry* motionEventDispatchEntry =
1625 connection->findQueuedDispatchEntryForEvent(eventEntry);
1626 if (motionEventDispatchEntry) {
1627 // If the dispatch entry is not in progress, then we must be busy dispatching an
1628 // earlier event. Not a problem, the motion event is on the outbound queue and will
1629 // be dispatched later.
1630 if (! motionEventDispatchEntry->inProgress) {
1631#if DEBUG_BATCHING
1632 LOGD("channel '%s' ~ Not streaming because the motion event has "
1633 "not yet been dispatched. "
1634 "(Waiting for earlier events to be consumed.)",
1635 connection->getInputChannelName());
1636#endif
1637 return;
1638 }
1639
1640 // If the dispatch entry is in progress but it already has a tail of pending
1641 // motion samples, then it must mean that the shared memory buffer filled up.
1642 // Not a problem, when this dispatch cycle is finished, we will eventually start
1643 // a new dispatch cycle to process the tail and that tail includes the newly
1644 // appended motion sample.
1645 if (motionEventDispatchEntry->tailMotionSample) {
1646#if DEBUG_BATCHING
1647 LOGD("channel '%s' ~ Not streaming because no new samples can "
1648 "be appended to the motion event in this dispatch cycle. "
1649 "(Waiting for next dispatch cycle to start.)",
1650 connection->getInputChannelName());
1651#endif
1652 return;
1653 }
1654
1655 // The dispatch entry is in progress and is still potentially open for streaming.
1656 // Try to stream the new motion sample. This might fail if the consumer has already
1657 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001658 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1659 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001660 status_t status = connection->inputPublisher.appendMotionSample(
1661 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1662 if (status == OK) {
1663#if DEBUG_BATCHING
1664 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1665 connection->getInputChannelName());
1666#endif
1667 return;
1668 }
1669
1670#if DEBUG_BATCHING
1671 if (status == NO_MEMORY) {
1672 LOGD("channel '%s' ~ Could not append motion sample to currently "
1673 "dispatched move event because the shared memory buffer is full. "
1674 "(Waiting for next dispatch cycle to start.)",
1675 connection->getInputChannelName());
1676 } else if (status == status_t(FAILED_TRANSACTION)) {
1677 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001678 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001679 "(Waiting for next dispatch cycle to start.)",
1680 connection->getInputChannelName());
1681 } else {
1682 LOGD("channel '%s' ~ Could not append motion sample to currently "
1683 "dispatched move event due to an error, status=%d. "
1684 "(Waiting for next dispatch cycle to start.)",
1685 connection->getInputChannelName(), status);
1686 }
1687#endif
1688 // Failed to stream. Start a new tail of pending motion samples to dispatch
1689 // in the next cycle.
1690 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1691 return;
1692 }
1693 }
1694
1695 // This is a new event.
1696 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001697 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown519e0242010-09-15 15:18:56 -07001698 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1699 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001700 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001701 }
1702
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001703 // Handle the case where we could not stream a new motion sample because the consumer has
1704 // already consumed the motion event (otherwise the corresponding dispatch entry would
1705 // still be in the outbound queue for this connection). We set the head motion sample
1706 // to the list starting with the newly appended motion sample.
1707 if (resumeWithAppendedMotionSample) {
1708#if DEBUG_BATCHING
1709 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1710 "that cannot be streamed because the motion event has already been consumed.",
1711 connection->getInputChannelName());
1712#endif
1713 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1714 dispatchEntry->headMotionSample = appendedMotionSample;
1715 }
1716
1717 // Enqueue the dispatch entry.
1718 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1719
1720 // If the outbound queue was previously empty, start the dispatch cycle going.
1721 if (wasEmpty) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001722 activateConnectionLocked(connection.get());
Jeff Brown519e0242010-09-15 15:18:56 -07001723 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001724 }
1725}
1726
Jeff Brown7fbdc842010-06-17 20:52:56 -07001727void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001728 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001729#if DEBUG_DISPATCH_CYCLE
1730 LOGD("channel '%s' ~ startDispatchCycle",
1731 connection->getInputChannelName());
1732#endif
1733
1734 assert(connection->status == Connection::STATUS_NORMAL);
1735 assert(! connection->outboundQueue.isEmpty());
1736
Jeff Brownb88102f2010-09-08 11:49:43 -07001737 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001738 assert(! dispatchEntry->inProgress);
1739
Jeff Brownb88102f2010-09-08 11:49:43 -07001740 // Mark the dispatch entry as in progress.
1741 dispatchEntry->inProgress = true;
1742
1743 // Update the connection's input state.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001744 EventEntry* eventEntry = dispatchEntry->eventEntry;
1745 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001746
1747#if FILTER_INPUT_EVENTS
1748 // Filter out inconsistent sequences of input events.
1749 // The input system may drop or inject events in a way that could violate implicit
1750 // invariants on input state and potentially cause an application to crash
1751 // or think that a key or pointer is stuck down. Technically we make no guarantees
1752 // of consistency but it would be nice to improve on this where possible.
1753 // XXX: This code is a proof of concept only. Not ready for prime time.
1754 if (consistency == InputState::TOLERABLE) {
1755#if DEBUG_DISPATCH_CYCLE
1756 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1757 "current input state but that is likely to be tolerated by the application.",
1758 connection->getInputChannelName());
1759#endif
1760 } else if (consistency == InputState::BROKEN) {
1761 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1762 "current input state and that is likely to cause the application to crash.",
1763 connection->getInputChannelName());
1764 startNextDispatchCycleLocked(currentTime, connection);
1765 return;
1766 }
1767#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001768
1769 // Publish the event.
1770 status_t status;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001771 switch (eventEntry->type) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001772 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001773 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001774
1775 // Apply target flags.
1776 int32_t action = keyEntry->action;
1777 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001778
1779 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001780 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001781 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1782 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1783 keyEntry->eventTime);
1784
1785 if (status) {
1786 LOGE("channel '%s' ~ Could not publish key event, "
1787 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001788 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001789 return;
1790 }
1791 break;
1792 }
1793
1794 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001795 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001796
1797 // Apply target flags.
1798 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001799 int32_t flags = motionEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001800 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001801 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001802 }
Jeff Brown85a31762010-09-01 17:01:00 -07001803 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1804 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1805 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001806
1807 // If headMotionSample is non-NULL, then it points to the first new sample that we
1808 // were unable to dispatch during the previous cycle so we resume dispatching from
1809 // that point in the list of motion samples.
1810 // Otherwise, we just start from the first sample of the motion event.
1811 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1812 if (! firstMotionSample) {
1813 firstMotionSample = & motionEntry->firstSample;
1814 }
1815
Jeff Brownd3616592010-07-16 17:21:06 -07001816 // Set the X and Y offset depending on the input source.
1817 float xOffset, yOffset;
1818 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1819 xOffset = dispatchEntry->xOffset;
1820 yOffset = dispatchEntry->yOffset;
1821 } else {
1822 xOffset = 0.0f;
1823 yOffset = 0.0f;
1824 }
1825
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001826 // Publish the motion event and the first motion sample.
1827 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07001828 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownd3616592010-07-16 17:21:06 -07001829 xOffset, yOffset,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001830 motionEntry->xPrecision, motionEntry->yPrecision,
1831 motionEntry->downTime, firstMotionSample->eventTime,
1832 motionEntry->pointerCount, motionEntry->pointerIds,
1833 firstMotionSample->pointerCoords);
1834
1835 if (status) {
1836 LOGE("channel '%s' ~ Could not publish motion event, "
1837 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001838 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001839 return;
1840 }
1841
1842 // Append additional motion samples.
1843 MotionSample* nextMotionSample = firstMotionSample->next;
1844 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1845 status = connection->inputPublisher.appendMotionSample(
1846 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1847 if (status == NO_MEMORY) {
1848#if DEBUG_DISPATCH_CYCLE
1849 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1850 "be sent in the next dispatch cycle.",
1851 connection->getInputChannelName());
1852#endif
1853 break;
1854 }
1855 if (status != OK) {
1856 LOGE("channel '%s' ~ Could not append motion sample "
1857 "for a reason other than out of memory, status=%d",
1858 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001859 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001860 return;
1861 }
1862 }
1863
1864 // Remember the next motion sample that we could not dispatch, in case we ran out
1865 // of space in the shared memory buffer.
1866 dispatchEntry->tailMotionSample = nextMotionSample;
1867 break;
1868 }
1869
1870 default: {
1871 assert(false);
1872 }
1873 }
1874
1875 // Send the dispatch signal.
1876 status = connection->inputPublisher.sendDispatchSignal();
1877 if (status) {
1878 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1879 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001880 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001881 return;
1882 }
1883
1884 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001885 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001886 connection->lastDispatchTime = currentTime;
1887
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001888 // Notify other system components.
1889 onDispatchCycleStartedLocked(currentTime, connection);
1890}
1891
Jeff Brown7fbdc842010-06-17 20:52:56 -07001892void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown3915bb82010-11-05 15:02:16 -07001893 const sp<Connection>& connection, bool handled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001894#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001895 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown3915bb82010-11-05 15:02:16 -07001896 "%01.1fms since dispatch, handled=%s",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001897 connection->getInputChannelName(),
1898 connection->getEventLatencyMillis(currentTime),
Jeff Brown3915bb82010-11-05 15:02:16 -07001899 connection->getDispatchLatencyMillis(currentTime),
1900 toString(handled));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001901#endif
1902
Jeff Brown9c3cda02010-06-15 01:31:58 -07001903 if (connection->status == Connection::STATUS_BROKEN
1904 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001905 return;
1906 }
1907
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001908 // Reset the publisher since the event has been consumed.
1909 // We do this now so that the publisher can release some of its internal resources
1910 // while waiting for the next dispatch cycle to begin.
1911 status_t status = connection->inputPublisher.reset();
1912 if (status) {
1913 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1914 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001915 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001916 return;
1917 }
1918
Jeff Brown3915bb82010-11-05 15:02:16 -07001919 // Notify other system components and prepare to start the next dispatch cycle.
1920 onDispatchCycleFinishedLocked(currentTime, connection, handled);
Jeff Brownb88102f2010-09-08 11:49:43 -07001921}
1922
1923void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1924 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001925 // Start the next dispatch cycle for this connection.
1926 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001927 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001928 if (dispatchEntry->inProgress) {
1929 // Finish or resume current event in progress.
1930 if (dispatchEntry->tailMotionSample) {
1931 // We have a tail of undispatched motion samples.
1932 // Reuse the same DispatchEntry and start a new cycle.
1933 dispatchEntry->inProgress = false;
1934 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1935 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07001936 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001937 return;
1938 }
1939 // Finished.
1940 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07001941 if (dispatchEntry->hasForegroundTarget()) {
1942 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001943 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001944 mAllocator.releaseDispatchEntry(dispatchEntry);
1945 } else {
1946 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07001947 // progress event, which means we actually aborted it.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001948 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07001949 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001950 return;
1951 }
1952 }
1953
1954 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07001955 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001956}
1957
Jeff Brownb6997262010-10-08 22:31:17 -07001958void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1959 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001960#if DEBUG_DISPATCH_CYCLE
Jeff Brown83c09682010-12-23 17:50:18 -08001961 LOGD("channel '%s' ~ abortBrokenDispatchCycle",
1962 connection->getInputChannelName());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001963#endif
1964
Jeff Brownb88102f2010-09-08 11:49:43 -07001965 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07001966 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001967
Jeff Brownb6997262010-10-08 22:31:17 -07001968 // The connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07001969 // Ignore already broken or zombie connections.
Jeff Brownb6997262010-10-08 22:31:17 -07001970 if (connection->status == Connection::STATUS_NORMAL) {
1971 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001972
Jeff Brownb6997262010-10-08 22:31:17 -07001973 // Notify other system components.
1974 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001975 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001976}
1977
Jeff Brown519e0242010-09-15 15:18:56 -07001978void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1979 while (! connection->outboundQueue.isEmpty()) {
1980 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1981 if (dispatchEntry->hasForegroundTarget()) {
1982 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001983 }
1984 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001985 }
1986
Jeff Brown519e0242010-09-15 15:18:56 -07001987 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07001988}
1989
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001990int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001991 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1992
1993 { // acquire lock
1994 AutoMutex _l(d->mLock);
1995
1996 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1997 if (connectionIndex < 0) {
1998 LOGE("Received spurious receive callback for unknown input channel. "
1999 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002000 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002001 }
2002
Jeff Brown7fbdc842010-06-17 20:52:56 -07002003 nsecs_t currentTime = now();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002004
2005 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002006 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002007 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
2008 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brownb6997262010-10-08 22:31:17 -07002009 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002010 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002011 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002012 }
2013
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002014 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002015 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
2016 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002017 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002018 }
2019
Jeff Brown3915bb82010-11-05 15:02:16 -07002020 bool handled = false;
Jeff Brown49ed71d2010-12-06 17:13:33 -08002021 status_t status = connection->inputPublisher.receiveFinishedSignal(&handled);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002022 if (status) {
2023 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
2024 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07002025 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002026 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002027 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002028 }
2029
Jeff Brown3915bb82010-11-05 15:02:16 -07002030 d->finishDispatchCycleLocked(currentTime, connection, handled);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002031 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002032 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002033 } // release lock
2034}
2035
Jeff Brownb6997262010-10-08 22:31:17 -07002036void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
2037 InputState::CancelationOptions options, const char* reason) {
2038 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
2039 synthesizeCancelationEventsForConnectionLocked(
2040 mConnectionsByReceiveFd.valueAt(i), options, reason);
2041 }
2042}
2043
2044void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2045 const sp<InputChannel>& channel, InputState::CancelationOptions options,
2046 const char* reason) {
2047 ssize_t index = getConnectionIndexLocked(channel);
2048 if (index >= 0) {
2049 synthesizeCancelationEventsForConnectionLocked(
2050 mConnectionsByReceiveFd.valueAt(index), options, reason);
2051 }
2052}
2053
2054void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2055 const sp<Connection>& connection, InputState::CancelationOptions options,
2056 const char* reason) {
2057 nsecs_t currentTime = now();
2058
2059 mTempCancelationEvents.clear();
2060 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
2061 mTempCancelationEvents, options);
2062
2063 if (! mTempCancelationEvents.isEmpty()
2064 && connection->status != Connection::STATUS_BROKEN) {
2065#if DEBUG_OUTBOUND_EVENT_DETAILS
2066 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
2067 "with reality: %s, options=%d.",
2068 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
2069#endif
2070 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
2071 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
2072 switch (cancelationEventEntry->type) {
2073 case EventEntry::TYPE_KEY:
2074 logOutboundKeyDetailsLocked("cancel - ",
2075 static_cast<KeyEntry*>(cancelationEventEntry));
2076 break;
2077 case EventEntry::TYPE_MOTION:
2078 logOutboundMotionDetailsLocked("cancel - ",
2079 static_cast<MotionEntry*>(cancelationEventEntry));
2080 break;
2081 }
2082
2083 int32_t xOffset, yOffset;
2084 const InputWindow* window = getWindowLocked(connection->inputChannel);
2085 if (window) {
2086 xOffset = -window->frameLeft;
2087 yOffset = -window->frameTop;
2088 } else {
2089 xOffset = 0;
2090 yOffset = 0;
2091 }
2092
2093 DispatchEntry* cancelationDispatchEntry =
2094 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
2095 0, xOffset, yOffset);
2096 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
2097
2098 mAllocator.releaseEventEntry(cancelationEventEntry);
2099 }
2100
2101 if (!connection->outboundQueue.headSentinel.next->inProgress) {
2102 startDispatchCycleLocked(currentTime, connection);
2103 }
2104 }
2105}
2106
Jeff Brown01ce2e92010-09-26 22:20:12 -07002107InputDispatcher::MotionEntry*
2108InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2109 assert(pointerIds.value != 0);
2110
2111 uint32_t splitPointerIndexMap[MAX_POINTERS];
2112 int32_t splitPointerIds[MAX_POINTERS];
2113 PointerCoords splitPointerCoords[MAX_POINTERS];
2114
2115 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2116 uint32_t splitPointerCount = 0;
2117
2118 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2119 originalPointerIndex++) {
2120 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
2121 if (pointerIds.hasBit(pointerId)) {
2122 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2123 splitPointerIds[splitPointerCount] = pointerId;
2124 splitPointerCoords[splitPointerCount] =
2125 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
2126 splitPointerCount += 1;
2127 }
2128 }
Jeff Brown58a2da82011-01-25 16:02:22 -08002129
2130 if (splitPointerCount != pointerIds.count()) {
2131 // This is bad. We are missing some of the pointers that we expected to deliver.
2132 // Most likely this indicates that we received an ACTION_MOVE events that has
2133 // different pointer ids than we expected based on the previous ACTION_DOWN
2134 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2135 // in this way.
2136 LOGW("Dropping split motion event because the pointer count is %d but "
2137 "we expected there to be %d pointers. This probably means we received "
2138 "a broken sequence of pointer ids from the input device.",
2139 splitPointerCount, pointerIds.count());
2140 return NULL;
2141 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002142
2143 int32_t action = originalMotionEntry->action;
2144 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2145 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2146 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2147 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2148 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2149 if (pointerIds.hasBit(pointerId)) {
2150 if (pointerIds.count() == 1) {
2151 // The first/last pointer went down/up.
2152 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2153 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07002154 } else {
2155 // A secondary pointer went down/up.
2156 uint32_t splitPointerIndex = 0;
2157 while (pointerId != splitPointerIds[splitPointerIndex]) {
2158 splitPointerIndex += 1;
2159 }
2160 action = maskedAction | (splitPointerIndex
2161 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002162 }
2163 } else {
2164 // An unrelated pointer changed.
2165 action = AMOTION_EVENT_ACTION_MOVE;
2166 }
2167 }
2168
2169 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2170 originalMotionEntry->eventTime,
2171 originalMotionEntry->deviceId,
2172 originalMotionEntry->source,
2173 originalMotionEntry->policyFlags,
2174 action,
2175 originalMotionEntry->flags,
2176 originalMotionEntry->metaState,
2177 originalMotionEntry->edgeFlags,
2178 originalMotionEntry->xPrecision,
2179 originalMotionEntry->yPrecision,
2180 originalMotionEntry->downTime,
2181 splitPointerCount, splitPointerIds, splitPointerCoords);
2182
2183 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2184 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2185 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2186 splitPointerIndex++) {
2187 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2188 splitPointerCoords[splitPointerIndex] =
2189 originalMotionSample->pointerCoords[originalPointerIndex];
2190 }
2191
2192 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2193 splitPointerCoords);
2194 }
2195
2196 return splitMotionEntry;
2197}
2198
Jeff Brown9c3cda02010-06-15 01:31:58 -07002199void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002200#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07002201 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002202#endif
2203
Jeff Brownb88102f2010-09-08 11:49:43 -07002204 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002205 { // acquire lock
2206 AutoMutex _l(mLock);
2207
Jeff Brown7fbdc842010-06-17 20:52:56 -07002208 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07002209 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002210 } // release lock
2211
Jeff Brownb88102f2010-09-08 11:49:43 -07002212 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002213 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002214 }
2215}
2216
Jeff Brown58a2da82011-01-25 16:02:22 -08002217void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002218 uint32_t policyFlags, int32_t action, int32_t flags,
2219 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2220#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002221 LOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002222 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07002223 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002224 keyCode, scanCode, metaState, downTime);
2225#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002226 if (! validateKeyEvent(action)) {
2227 return;
2228 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002229
Jeff Brown1f245102010-11-18 20:53:46 -08002230 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2231 policyFlags |= POLICY_FLAG_VIRTUAL;
2232 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2233 }
2234
Jeff Browne20c9e02010-10-11 14:20:19 -07002235 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown1f245102010-11-18 20:53:46 -08002236
2237 KeyEvent event;
2238 event.initialize(deviceId, source, action, flags, keyCode, scanCode,
2239 metaState, 0, downTime, eventTime);
2240
2241 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
2242
2243 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2244 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2245 }
Jeff Brownb6997262010-10-08 22:31:17 -07002246
Jeff Brownb88102f2010-09-08 11:49:43 -07002247 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002248 { // acquire lock
2249 AutoMutex _l(mLock);
2250
Jeff Brown7fbdc842010-06-17 20:52:56 -07002251 int32_t repeatCount = 0;
2252 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002253 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002254 metaState, repeatCount, downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002255
Jeff Brownb88102f2010-09-08 11:49:43 -07002256 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002257 } // release lock
2258
Jeff Brownb88102f2010-09-08 11:49:43 -07002259 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002260 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002261 }
2262}
2263
Jeff Brown58a2da82011-01-25 16:02:22 -08002264void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002265 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002266 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2267 float xPrecision, float yPrecision, nsecs_t downTime) {
2268#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002269 LOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002270 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2271 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2272 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002273 xPrecision, yPrecision, downTime);
2274 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002275 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002276 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002277 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002278 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown8d608662010-08-30 03:02:23 -07002279 pointerCoords[i].pressure, pointerCoords[i].size,
2280 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2281 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2282 pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002283 }
2284#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002285 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2286 return;
2287 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002288
Jeff Browne20c9e02010-10-11 14:20:19 -07002289 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002290 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2291
Jeff Brownb88102f2010-09-08 11:49:43 -07002292 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002293 { // acquire lock
2294 AutoMutex _l(mLock);
2295
2296 // Attempt batching and streaming of move events.
Jeff Brownc5ed5912010-07-14 18:48:53 -07002297 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002298 // BATCHING CASE
2299 //
2300 // Try to append a move sample to the tail of the inbound queue for this device.
2301 // Give up if we encounter a non-move motion event for this device since that
2302 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002303 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2304 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002305 if (entry->type != EventEntry::TYPE_MOTION) {
2306 // Keep looking for motion events.
2307 continue;
2308 }
2309
2310 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2311 if (motionEntry->deviceId != deviceId) {
2312 // Keep looking for this device.
2313 continue;
2314 }
2315
Jeff Brownc5ed5912010-07-14 18:48:53 -07002316 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown58a2da82011-01-25 16:02:22 -08002317 || motionEntry->source != source
Jeff Brown7fbdc842010-06-17 20:52:56 -07002318 || motionEntry->pointerCount != pointerCount
2319 || motionEntry->isInjected()) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002320 // Last motion event in the queue for this device is not compatible for
2321 // appending new samples. Stop here.
2322 goto NoBatchingOrStreaming;
2323 }
2324
2325 // The last motion event is a move and is compatible for appending.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002326 // Do the batching magic.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002327 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002328#if DEBUG_BATCHING
2329 LOGD("Appended motion sample onto batch for most recent "
2330 "motion event for this device in the inbound queue.");
2331#endif
Jeff Brown9c3cda02010-06-15 01:31:58 -07002332 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002333 }
2334
2335 // STREAMING CASE
2336 //
2337 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002338 // Search the outbound queue for the current foreground targets to find a dispatched
2339 // motion event that is still in progress. If found, then, appen the new sample to
2340 // that event and push it out to all current targets. The logic in
2341 // prepareDispatchCycleLocked takes care of the case where some targets may
2342 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002343 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002344 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2345 const InputTarget& inputTarget = mCurrentInputTargets[i];
2346 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2347 // Skip non-foreground targets. We only want to stream if there is at
2348 // least one foreground target whose dispatch is still in progress.
2349 continue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002350 }
Jeff Brown519e0242010-09-15 15:18:56 -07002351
2352 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2353 if (connectionIndex < 0) {
2354 // Connection must no longer be valid.
2355 continue;
2356 }
2357
2358 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2359 if (connection->outboundQueue.isEmpty()) {
2360 // This foreground target has an empty outbound queue.
2361 continue;
2362 }
2363
2364 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2365 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002366 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2367 || dispatchEntry->isSplit()) {
2368 // No motion event is being dispatched, or it is being split across
2369 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002370 continue;
2371 }
2372
2373 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2374 dispatchEntry->eventEntry);
2375 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2376 || motionEntry->deviceId != deviceId
Jeff Brown58a2da82011-01-25 16:02:22 -08002377 || motionEntry->source != source
Jeff Brown519e0242010-09-15 15:18:56 -07002378 || motionEntry->pointerCount != pointerCount
2379 || motionEntry->isInjected()) {
2380 // The motion event is not compatible with this move.
2381 continue;
2382 }
2383
2384 // Hurray! This foreground target is currently dispatching a move event
2385 // that we can stream onto. Append the motion sample and resume dispatch.
2386 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2387#if DEBUG_BATCHING
2388 LOGD("Appended motion sample onto batch for most recently dispatched "
2389 "motion event for this device in the outbound queues. "
2390 "Attempting to stream the motion sample.");
2391#endif
2392 nsecs_t currentTime = now();
2393 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2394 true /*resumeWithAppendedMotionSample*/);
2395
2396 runCommandsLockedInterruptible();
2397 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002398 }
2399 }
2400
2401NoBatchingOrStreaming:;
2402 }
2403
2404 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002405 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002406 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002407 xPrecision, yPrecision, downTime,
2408 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002409
Jeff Brownb88102f2010-09-08 11:49:43 -07002410 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002411 } // release lock
2412
Jeff Brownb88102f2010-09-08 11:49:43 -07002413 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002414 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002415 }
2416}
2417
Jeff Brownb6997262010-10-08 22:31:17 -07002418void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2419 uint32_t policyFlags) {
2420#if DEBUG_INBOUND_EVENT_DETAILS
2421 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2422 switchCode, switchValue, policyFlags);
2423#endif
2424
Jeff Browne20c9e02010-10-11 14:20:19 -07002425 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002426 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2427}
2428
Jeff Brown7fbdc842010-06-17 20:52:56 -07002429int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002430 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002431#if DEBUG_INBOUND_EVENT_DETAILS
2432 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002433 "syncMode=%d, timeoutMillis=%d",
2434 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002435#endif
2436
2437 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Browne20c9e02010-10-11 14:20:19 -07002438
2439 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2440 if (hasInjectionPermission(injectorPid, injectorUid)) {
2441 policyFlags |= POLICY_FLAG_TRUSTED;
2442 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002443
Jeff Brownb6997262010-10-08 22:31:17 -07002444 EventEntry* injectedEntry;
2445 switch (event->getType()) {
2446 case AINPUT_EVENT_TYPE_KEY: {
2447 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2448 int32_t action = keyEvent->getAction();
2449 if (! validateKeyEvent(action)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002450 return INPUT_EVENT_INJECTION_FAILED;
2451 }
2452
Jeff Brownb6997262010-10-08 22:31:17 -07002453 int32_t flags = keyEvent->getFlags();
Jeff Brown1f245102010-11-18 20:53:46 -08002454 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2455 policyFlags |= POLICY_FLAG_VIRTUAL;
2456 }
2457
2458 mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
2459
2460 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2461 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2462 }
Jeff Brown6ec402b2010-07-28 15:48:59 -07002463
Jeff Brownb6997262010-10-08 22:31:17 -07002464 mLock.lock();
Jeff Brown1f245102010-11-18 20:53:46 -08002465 injectedEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
2466 keyEvent->getDeviceId(), keyEvent->getSource(),
2467 policyFlags, action, flags,
2468 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
Jeff Brownb6997262010-10-08 22:31:17 -07002469 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2470 break;
2471 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002472
Jeff Brownb6997262010-10-08 22:31:17 -07002473 case AINPUT_EVENT_TYPE_MOTION: {
2474 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2475 int32_t action = motionEvent->getAction();
2476 size_t pointerCount = motionEvent->getPointerCount();
2477 const int32_t* pointerIds = motionEvent->getPointerIds();
2478 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2479 return INPUT_EVENT_INJECTION_FAILED;
2480 }
2481
2482 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Browne20c9e02010-10-11 14:20:19 -07002483 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002484
2485 mLock.lock();
2486 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2487 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2488 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2489 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2490 action, motionEvent->getFlags(),
2491 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2492 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2493 motionEvent->getDownTime(), uint32_t(pointerCount),
2494 pointerIds, samplePointerCoords);
2495 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2496 sampleEventTimes += 1;
2497 samplePointerCoords += pointerCount;
2498 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2499 }
2500 injectedEntry = motionEntry;
2501 break;
2502 }
2503
2504 default:
2505 LOGW("Cannot inject event of type %d", event->getType());
2506 return INPUT_EVENT_INJECTION_FAILED;
2507 }
2508
2509 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2510 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2511 injectionState->injectionIsAsync = true;
2512 }
2513
2514 injectionState->refCount += 1;
2515 injectedEntry->injectionState = injectionState;
2516
2517 bool needWake = enqueueInboundEventLocked(injectedEntry);
2518 mLock.unlock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002519
Jeff Brownb88102f2010-09-08 11:49:43 -07002520 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002521 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002522 }
2523
2524 int32_t injectionResult;
2525 { // acquire lock
2526 AutoMutex _l(mLock);
2527
Jeff Brown6ec402b2010-07-28 15:48:59 -07002528 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2529 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2530 } else {
2531 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002532 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002533 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2534 break;
2535 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002536
Jeff Brown7fbdc842010-06-17 20:52:56 -07002537 nsecs_t remainingTimeout = endTime - now();
2538 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002539#if DEBUG_INJECTION
2540 LOGD("injectInputEvent - Timed out waiting for injection result "
2541 "to become available.");
2542#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002543 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2544 break;
2545 }
2546
Jeff Brown6ec402b2010-07-28 15:48:59 -07002547 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2548 }
2549
2550 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2551 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002552 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002553#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002554 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002555 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002556#endif
2557 nsecs_t remainingTimeout = endTime - now();
2558 if (remainingTimeout <= 0) {
2559#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002560 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002561 "dispatches to finish.");
2562#endif
2563 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2564 break;
2565 }
2566
2567 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2568 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002569 }
2570 }
2571
Jeff Brown01ce2e92010-09-26 22:20:12 -07002572 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002573 } // release lock
2574
Jeff Brown6ec402b2010-07-28 15:48:59 -07002575#if DEBUG_INJECTION
2576 LOGD("injectInputEvent - Finished with result %d. "
2577 "injectorPid=%d, injectorUid=%d",
2578 injectionResult, injectorPid, injectorUid);
2579#endif
2580
Jeff Brown7fbdc842010-06-17 20:52:56 -07002581 return injectionResult;
2582}
2583
Jeff Brownb6997262010-10-08 22:31:17 -07002584bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2585 return injectorUid == 0
2586 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2587}
2588
Jeff Brown7fbdc842010-06-17 20:52:56 -07002589void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002590 InjectionState* injectionState = entry->injectionState;
2591 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002592#if DEBUG_INJECTION
2593 LOGD("Setting input event injection result to %d. "
2594 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002595 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002596#endif
2597
Jeff Brown01ce2e92010-09-26 22:20:12 -07002598 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002599 // Log the outcome since the injector did not wait for the injection result.
2600 switch (injectionResult) {
2601 case INPUT_EVENT_INJECTION_SUCCEEDED:
2602 LOGV("Asynchronous input event injection succeeded.");
2603 break;
2604 case INPUT_EVENT_INJECTION_FAILED:
2605 LOGW("Asynchronous input event injection failed.");
2606 break;
2607 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2608 LOGW("Asynchronous input event injection permission denied.");
2609 break;
2610 case INPUT_EVENT_INJECTION_TIMED_OUT:
2611 LOGW("Asynchronous input event injection timed out.");
2612 break;
2613 }
2614 }
2615
Jeff Brown01ce2e92010-09-26 22:20:12 -07002616 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002617 mInjectionResultAvailableCondition.broadcast();
2618 }
2619}
2620
Jeff Brown01ce2e92010-09-26 22:20:12 -07002621void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2622 InjectionState* injectionState = entry->injectionState;
2623 if (injectionState) {
2624 injectionState->pendingForegroundDispatches += 1;
2625 }
2626}
2627
Jeff Brown519e0242010-09-15 15:18:56 -07002628void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002629 InjectionState* injectionState = entry->injectionState;
2630 if (injectionState) {
2631 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002632
Jeff Brown01ce2e92010-09-26 22:20:12 -07002633 if (injectionState->pendingForegroundDispatches == 0) {
2634 mInjectionSyncFinishedCondition.broadcast();
2635 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002636 }
2637}
2638
Jeff Brown01ce2e92010-09-26 22:20:12 -07002639const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2640 for (size_t i = 0; i < mWindows.size(); i++) {
2641 const InputWindow* window = & mWindows[i];
2642 if (window->inputChannel == inputChannel) {
2643 return window;
2644 }
2645 }
2646 return NULL;
2647}
2648
Jeff Brownb88102f2010-09-08 11:49:43 -07002649void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2650#if DEBUG_FOCUS
2651 LOGD("setInputWindows");
2652#endif
2653 { // acquire lock
2654 AutoMutex _l(mLock);
2655
Jeff Brown01ce2e92010-09-26 22:20:12 -07002656 // Clear old window pointers.
Jeff Brownb6997262010-10-08 22:31:17 -07002657 sp<InputChannel> oldFocusedWindowChannel;
2658 if (mFocusedWindow) {
2659 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2660 mFocusedWindow = NULL;
2661 }
2662
Jeff Brownb88102f2010-09-08 11:49:43 -07002663 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002664
2665 // Loop over new windows and rebuild the necessary window pointers for
2666 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002667 mWindows.appendVector(inputWindows);
2668
2669 size_t numWindows = mWindows.size();
2670 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002671 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002672 if (window->hasFocus) {
2673 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002674 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002675 }
2676 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002677
Jeff Brownb6997262010-10-08 22:31:17 -07002678 if (oldFocusedWindowChannel != NULL) {
2679 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2680#if DEBUG_FOCUS
2681 LOGD("Focus left window: %s",
2682 oldFocusedWindowChannel->getName().string());
2683#endif
2684 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2685 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2686 oldFocusedWindowChannel.clear();
2687 }
2688 }
2689 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2690#if DEBUG_FOCUS
2691 LOGD("Focus entered window: %s",
2692 mFocusedWindow->inputChannel->getName().string());
2693#endif
2694 }
2695
Jeff Brown01ce2e92010-09-26 22:20:12 -07002696 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2697 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2698 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2699 if (window) {
2700 touchedWindow.window = window;
2701 i += 1;
2702 } else {
Jeff Brownb6997262010-10-08 22:31:17 -07002703#if DEBUG_FOCUS
2704 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2705#endif
Jeff Brownb6997262010-10-08 22:31:17 -07002706 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2707 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownaf48cae2010-10-15 16:20:51 -07002708 mTouchState.windows.removeAt(i);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002709 }
2710 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002711
Jeff Brownb88102f2010-09-08 11:49:43 -07002712#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002713 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002714#endif
2715 } // release lock
2716
2717 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002718 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002719}
2720
2721void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2722#if DEBUG_FOCUS
2723 LOGD("setFocusedApplication");
2724#endif
2725 { // acquire lock
2726 AutoMutex _l(mLock);
2727
2728 releaseFocusedApplicationLocked();
2729
2730 if (inputApplication) {
2731 mFocusedApplicationStorage = *inputApplication;
2732 mFocusedApplication = & mFocusedApplicationStorage;
2733 }
2734
2735#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002736 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002737#endif
2738 } // release lock
2739
2740 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002741 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002742}
2743
2744void InputDispatcher::releaseFocusedApplicationLocked() {
2745 if (mFocusedApplication) {
2746 mFocusedApplication = NULL;
Jeff Brown928e0542011-01-10 11:17:36 -08002747 mFocusedApplicationStorage.inputApplicationHandle.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -07002748 }
2749}
2750
2751void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2752#if DEBUG_FOCUS
2753 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2754#endif
2755
2756 bool changed;
2757 { // acquire lock
2758 AutoMutex _l(mLock);
2759
2760 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brown120a4592010-10-27 18:43:51 -07002761 if (mDispatchFrozen && !frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002762 resetANRTimeoutsLocked();
2763 }
2764
Jeff Brown120a4592010-10-27 18:43:51 -07002765 if (mDispatchEnabled && !enabled) {
2766 resetAndDropEverythingLocked("dispatcher is being disabled");
2767 }
2768
Jeff Brownb88102f2010-09-08 11:49:43 -07002769 mDispatchEnabled = enabled;
2770 mDispatchFrozen = frozen;
2771 changed = true;
2772 } else {
2773 changed = false;
2774 }
2775
2776#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002777 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002778#endif
2779 } // release lock
2780
2781 if (changed) {
2782 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002783 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002784 }
2785}
2786
Jeff Browne6504122010-09-27 14:52:15 -07002787bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2788 const sp<InputChannel>& toChannel) {
2789#if DEBUG_FOCUS
2790 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2791 fromChannel->getName().string(), toChannel->getName().string());
2792#endif
2793 { // acquire lock
2794 AutoMutex _l(mLock);
2795
2796 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2797 const InputWindow* toWindow = getWindowLocked(toChannel);
2798 if (! fromWindow || ! toWindow) {
2799#if DEBUG_FOCUS
2800 LOGD("Cannot transfer focus because from or to window not found.");
2801#endif
2802 return false;
2803 }
2804 if (fromWindow == toWindow) {
2805#if DEBUG_FOCUS
2806 LOGD("Trivial transfer to same window.");
2807#endif
2808 return true;
2809 }
2810
2811 bool found = false;
2812 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2813 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2814 if (touchedWindow.window == fromWindow) {
2815 int32_t oldTargetFlags = touchedWindow.targetFlags;
2816 BitSet32 pointerIds = touchedWindow.pointerIds;
2817
2818 mTouchState.windows.removeAt(i);
2819
Jeff Brown46e75292010-11-10 16:53:45 -08002820 int32_t newTargetFlags = oldTargetFlags
2821 & (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT);
Jeff Browne6504122010-09-27 14:52:15 -07002822 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2823
2824 found = true;
2825 break;
2826 }
2827 }
2828
2829 if (! found) {
2830#if DEBUG_FOCUS
2831 LOGD("Focus transfer failed because from window did not have focus.");
2832#endif
2833 return false;
2834 }
2835
Jeff Brown9c9f1a32010-10-11 18:32:20 -07002836 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2837 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2838 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2839 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2840 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2841
2842 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2843 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2844 InputState::CANCEL_POINTER_EVENTS,
2845 "transferring touch focus from this window to another window");
2846 }
2847
Jeff Browne6504122010-09-27 14:52:15 -07002848#if DEBUG_FOCUS
2849 logDispatchStateLocked();
2850#endif
2851 } // release lock
2852
2853 // Wake up poll loop since it may need to make new input dispatching choices.
2854 mLooper->wake();
2855 return true;
2856}
2857
Jeff Brown120a4592010-10-27 18:43:51 -07002858void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2859#if DEBUG_FOCUS
2860 LOGD("Resetting and dropping all events (%s).", reason);
2861#endif
2862
2863 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2864
2865 resetKeyRepeatLocked();
2866 releasePendingEventLocked();
2867 drainInboundQueueLocked();
2868 resetTargetsLocked();
2869
2870 mTouchState.reset();
2871}
2872
Jeff Brownb88102f2010-09-08 11:49:43 -07002873void InputDispatcher::logDispatchStateLocked() {
2874 String8 dump;
2875 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002876
2877 char* text = dump.lockBuffer(dump.size());
2878 char* start = text;
2879 while (*start != '\0') {
2880 char* end = strchr(start, '\n');
2881 if (*end == '\n') {
2882 *(end++) = '\0';
2883 }
2884 LOGD("%s", start);
2885 start = end;
2886 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002887}
2888
2889void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002890 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2891 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07002892
2893 if (mFocusedApplication) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002894 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002895 mFocusedApplication->name.string(),
2896 mFocusedApplication->dispatchingTimeout / 1000000.0);
2897 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002898 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002899 }
Jeff Brownf2f487182010-10-01 17:46:21 -07002900 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002901 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f487182010-10-01 17:46:21 -07002902
2903 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2904 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
Jeff Brown95712852011-01-04 19:41:59 -08002905 dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
Jeff Brown58a2da82011-01-25 16:02:22 -08002906 dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
Jeff Brownf2f487182010-10-01 17:46:21 -07002907 if (!mTouchState.windows.isEmpty()) {
2908 dump.append(INDENT "TouchedWindows:\n");
2909 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2910 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2911 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2912 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2913 touchedWindow.targetFlags);
2914 }
2915 } else {
2916 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002917 }
2918
Jeff Brownf2f487182010-10-01 17:46:21 -07002919 if (!mWindows.isEmpty()) {
2920 dump.append(INDENT "Windows:\n");
2921 for (size_t i = 0; i < mWindows.size(); i++) {
2922 const InputWindow& window = mWindows[i];
2923 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2924 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2925 "frame=[%d,%d][%d,%d], "
Jeff Brownfbf09772011-01-16 14:06:57 -08002926 "touchableRegion=",
Jeff Brownf2f487182010-10-01 17:46:21 -07002927 i, window.name.string(),
2928 toString(window.paused),
2929 toString(window.hasFocus),
2930 toString(window.hasWallpaper),
2931 toString(window.visible),
2932 toString(window.canReceiveKeys),
2933 window.layoutParamsFlags, window.layoutParamsType,
2934 window.layer,
2935 window.frameLeft, window.frameTop,
Jeff Brownfbf09772011-01-16 14:06:57 -08002936 window.frameRight, window.frameBottom);
2937 dumpRegion(dump, window.touchableRegion);
2938 dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07002939 window.ownerPid, window.ownerUid,
2940 window.dispatchingTimeout / 1000000.0);
2941 }
2942 } else {
2943 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002944 }
2945
Jeff Brownf2f487182010-10-01 17:46:21 -07002946 if (!mMonitoringChannels.isEmpty()) {
2947 dump.append(INDENT "MonitoringChannels:\n");
2948 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2949 const sp<InputChannel>& channel = mMonitoringChannels[i];
2950 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2951 }
2952 } else {
2953 dump.append(INDENT "MonitoringChannels: <none>\n");
2954 }
Jeff Brown519e0242010-09-15 15:18:56 -07002955
Jeff Brownf2f487182010-10-01 17:46:21 -07002956 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2957
2958 if (!mActiveConnections.isEmpty()) {
2959 dump.append(INDENT "ActiveConnections:\n");
2960 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2961 const Connection* connection = mActiveConnections[i];
Jeff Brown76860e32010-10-25 17:37:46 -07002962 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brownb6997262010-10-08 22:31:17 -07002963 "inputState.isNeutral=%s\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07002964 i, connection->getInputChannelName(), connection->getStatusLabel(),
2965 connection->outboundQueue.count(),
Jeff Brownb6997262010-10-08 22:31:17 -07002966 toString(connection->inputState.isNeutral()));
Jeff Brownf2f487182010-10-01 17:46:21 -07002967 }
2968 } else {
2969 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002970 }
2971
2972 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002973 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002974 (mAppSwitchDueTime - now()) / 1000000.0);
2975 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002976 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002977 }
2978}
2979
Jeff Brown928e0542011-01-10 11:17:36 -08002980status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
2981 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002982#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07002983 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2984 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07002985#endif
2986
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002987 { // acquire lock
2988 AutoMutex _l(mLock);
2989
Jeff Brown519e0242010-09-15 15:18:56 -07002990 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002991 LOGW("Attempted to register already registered input channel '%s'",
2992 inputChannel->getName().string());
2993 return BAD_VALUE;
2994 }
2995
Jeff Brown928e0542011-01-10 11:17:36 -08002996 sp<Connection> connection = new Connection(inputChannel, inputWindowHandle);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002997 status_t status = connection->initialize();
2998 if (status) {
2999 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
3000 inputChannel->getName().string(), status);
3001 return status;
3002 }
3003
Jeff Brown2cbecea2010-08-17 15:59:26 -07003004 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003005 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003006
Jeff Brownb88102f2010-09-08 11:49:43 -07003007 if (monitor) {
3008 mMonitoringChannels.push(inputChannel);
3009 }
3010
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003011 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07003012
Jeff Brown9c3cda02010-06-15 01:31:58 -07003013 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003014 } // release lock
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003015 return OK;
3016}
3017
3018status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003019#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07003020 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07003021#endif
3022
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003023 { // acquire lock
3024 AutoMutex _l(mLock);
3025
Jeff Brown519e0242010-09-15 15:18:56 -07003026 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003027 if (connectionIndex < 0) {
3028 LOGW("Attempted to unregister already unregistered input channel '%s'",
3029 inputChannel->getName().string());
3030 return BAD_VALUE;
3031 }
3032
3033 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3034 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
3035
3036 connection->status = Connection::STATUS_ZOMBIE;
3037
Jeff Brownb88102f2010-09-08 11:49:43 -07003038 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3039 if (mMonitoringChannels[i] == inputChannel) {
3040 mMonitoringChannels.removeAt(i);
3041 break;
3042 }
3043 }
3044
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003045 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07003046
Jeff Brown7fbdc842010-06-17 20:52:56 -07003047 nsecs_t currentTime = now();
Jeff Brownb6997262010-10-08 22:31:17 -07003048 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003049
3050 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003051 } // release lock
3052
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003053 // Wake the poll loop because removing the connection may have changed the current
3054 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003055 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003056 return OK;
3057}
3058
Jeff Brown519e0242010-09-15 15:18:56 -07003059ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07003060 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
3061 if (connectionIndex >= 0) {
3062 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3063 if (connection->inputChannel.get() == inputChannel.get()) {
3064 return connectionIndex;
3065 }
3066 }
3067
3068 return -1;
3069}
3070
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003071void InputDispatcher::activateConnectionLocked(Connection* connection) {
3072 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3073 if (mActiveConnections.itemAt(i) == connection) {
3074 return;
3075 }
3076 }
3077 mActiveConnections.add(connection);
3078}
3079
3080void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
3081 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3082 if (mActiveConnections.itemAt(i) == connection) {
3083 mActiveConnections.removeAt(i);
3084 return;
3085 }
3086 }
3087}
3088
Jeff Brown9c3cda02010-06-15 01:31:58 -07003089void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003090 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003091}
3092
Jeff Brown9c3cda02010-06-15 01:31:58 -07003093void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown3915bb82010-11-05 15:02:16 -07003094 nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
3095 CommandEntry* commandEntry = postCommandLocked(
3096 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
3097 commandEntry->connection = connection;
3098 commandEntry->handled = handled;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003099}
3100
Jeff Brown9c3cda02010-06-15 01:31:58 -07003101void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003102 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003103 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3104 connection->getInputChannelName());
3105
Jeff Brown9c3cda02010-06-15 01:31:58 -07003106 CommandEntry* commandEntry = postCommandLocked(
3107 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003108 commandEntry->connection = connection;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003109}
3110
Jeff Brown519e0242010-09-15 15:18:56 -07003111void InputDispatcher::onANRLocked(
3112 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
3113 nsecs_t eventTime, nsecs_t waitStartTime) {
3114 LOGI("Application is not responding: %s. "
3115 "%01.1fms since event, %01.1fms since wait started",
3116 getApplicationWindowLabelLocked(application, window).string(),
3117 (currentTime - eventTime) / 1000000.0,
3118 (currentTime - waitStartTime) / 1000000.0);
3119
3120 CommandEntry* commandEntry = postCommandLocked(
3121 & InputDispatcher::doNotifyANRLockedInterruptible);
3122 if (application) {
Jeff Brown928e0542011-01-10 11:17:36 -08003123 commandEntry->inputApplicationHandle = application->inputApplicationHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003124 }
3125 if (window) {
Jeff Brown928e0542011-01-10 11:17:36 -08003126 commandEntry->inputWindowHandle = window->inputWindowHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003127 commandEntry->inputChannel = window->inputChannel;
3128 }
3129}
3130
Jeff Brownb88102f2010-09-08 11:49:43 -07003131void InputDispatcher::doNotifyConfigurationChangedInterruptible(
3132 CommandEntry* commandEntry) {
3133 mLock.unlock();
3134
3135 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
3136
3137 mLock.lock();
3138}
3139
Jeff Brown9c3cda02010-06-15 01:31:58 -07003140void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
3141 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003142 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07003143
Jeff Brown7fbdc842010-06-17 20:52:56 -07003144 if (connection->status != Connection::STATUS_ZOMBIE) {
3145 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003146
Jeff Brown928e0542011-01-10 11:17:36 -08003147 mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003148
3149 mLock.lock();
3150 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07003151}
3152
Jeff Brown519e0242010-09-15 15:18:56 -07003153void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07003154 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07003155 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003156
Jeff Brown519e0242010-09-15 15:18:56 -07003157 nsecs_t newTimeout = mPolicy->notifyANR(
Jeff Brown928e0542011-01-10 11:17:36 -08003158 commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003159
Jeff Brown519e0242010-09-15 15:18:56 -07003160 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07003161
Jeff Brown519e0242010-09-15 15:18:56 -07003162 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003163}
3164
Jeff Brownb88102f2010-09-08 11:49:43 -07003165void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3166 CommandEntry* commandEntry) {
3167 KeyEntry* entry = commandEntry->keyEntry;
Jeff Brown1f245102010-11-18 20:53:46 -08003168
3169 KeyEvent event;
3170 initializeKeyEvent(&event, entry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003171
3172 mLock.unlock();
3173
Jeff Brown928e0542011-01-10 11:17:36 -08003174 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
Jeff Brown1f245102010-11-18 20:53:46 -08003175 &event, entry->policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -07003176
3177 mLock.lock();
3178
3179 entry->interceptKeyResult = consumed
3180 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
3181 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3182 mAllocator.releaseKeyEntry(entry);
3183}
3184
Jeff Brown3915bb82010-11-05 15:02:16 -07003185void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3186 CommandEntry* commandEntry) {
3187 sp<Connection> connection = commandEntry->connection;
3188 bool handled = commandEntry->handled;
3189
Jeff Brown49ed71d2010-12-06 17:13:33 -08003190 if (!connection->outboundQueue.isEmpty()) {
Jeff Brown3915bb82010-11-05 15:02:16 -07003191 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
3192 if (dispatchEntry->inProgress
3193 && dispatchEntry->hasForegroundTarget()
3194 && dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3195 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003196 if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
3197 if (handled) {
3198 // If the application handled a non-fallback key, then immediately
3199 // cancel all fallback keys previously dispatched to the application.
3200 // This behavior will prevent chording with fallback keys (so they cannot
3201 // be used as modifiers) but it will ensure that fallback keys do not
3202 // get stuck. This takes care of the case where the application does not handle
3203 // the original DOWN so we generate a fallback DOWN but it does handle
3204 // the original UP in which case we would not generate the fallback UP.
3205 synthesizeCancelationEventsForConnectionLocked(connection,
3206 InputState::CANCEL_FALLBACK_EVENTS,
Jeff Brown00045a72010-12-09 18:10:30 -08003207 "application handled a non-fallback event, canceling all fallback events");
Jeff Brown49ed71d2010-12-06 17:13:33 -08003208 } else {
3209 // If the application did not handle a non-fallback key, then ask
3210 // the policy what to do with it. We might generate a fallback key
3211 // event here.
3212 KeyEvent event;
3213 initializeKeyEvent(&event, keyEntry);
Jeff Brown3915bb82010-11-05 15:02:16 -07003214
Jeff Brown49ed71d2010-12-06 17:13:33 -08003215 mLock.unlock();
Jeff Brown3915bb82010-11-05 15:02:16 -07003216
Jeff Brown928e0542011-01-10 11:17:36 -08003217 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003218 &event, keyEntry->policyFlags, &event);
Jeff Brown3915bb82010-11-05 15:02:16 -07003219
Jeff Brown49ed71d2010-12-06 17:13:33 -08003220 mLock.lock();
3221
Jeff Brown00045a72010-12-09 18:10:30 -08003222 if (connection->status != Connection::STATUS_NORMAL) {
3223 return;
3224 }
3225
3226 assert(connection->outboundQueue.headSentinel.next == dispatchEntry);
3227
Jeff Brown49ed71d2010-12-06 17:13:33 -08003228 if (fallback) {
3229 // Restart the dispatch cycle using the fallback key.
3230 keyEntry->eventTime = event.getEventTime();
3231 keyEntry->deviceId = event.getDeviceId();
3232 keyEntry->source = event.getSource();
3233 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
3234 keyEntry->keyCode = event.getKeyCode();
3235 keyEntry->scanCode = event.getScanCode();
3236 keyEntry->metaState = event.getMetaState();
3237 keyEntry->repeatCount = event.getRepeatCount();
3238 keyEntry->downTime = event.getDownTime();
3239 keyEntry->syntheticRepeat = false;
3240
3241 dispatchEntry->inProgress = false;
3242 startDispatchCycleLocked(now(), connection);
3243 return;
3244 }
3245 }
3246 }
Jeff Brown3915bb82010-11-05 15:02:16 -07003247 }
3248 }
3249
3250 startNextDispatchCycleLocked(now(), connection);
3251}
3252
Jeff Brownb88102f2010-09-08 11:49:43 -07003253void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3254 mLock.unlock();
3255
Jeff Brown01ce2e92010-09-26 22:20:12 -07003256 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07003257
3258 mLock.lock();
3259}
3260
Jeff Brown3915bb82010-11-05 15:02:16 -07003261void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
3262 event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3263 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3264 entry->downTime, entry->eventTime);
3265}
3266
Jeff Brown519e0242010-09-15 15:18:56 -07003267void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3268 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3269 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07003270}
3271
3272void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003273 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003274 dumpDispatchStateLocked(dump);
3275}
3276
Jeff Brown9c3cda02010-06-15 01:31:58 -07003277
Jeff Brown519e0242010-09-15 15:18:56 -07003278// --- InputDispatcher::Queue ---
3279
3280template <typename T>
3281uint32_t InputDispatcher::Queue<T>::count() const {
3282 uint32_t result = 0;
3283 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3284 result += 1;
3285 }
3286 return result;
3287}
3288
3289
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003290// --- InputDispatcher::Allocator ---
3291
3292InputDispatcher::Allocator::Allocator() {
3293}
3294
Jeff Brown01ce2e92010-09-26 22:20:12 -07003295InputDispatcher::InjectionState*
3296InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3297 InjectionState* injectionState = mInjectionStatePool.alloc();
3298 injectionState->refCount = 1;
3299 injectionState->injectorPid = injectorPid;
3300 injectionState->injectorUid = injectorUid;
3301 injectionState->injectionIsAsync = false;
3302 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3303 injectionState->pendingForegroundDispatches = 0;
3304 return injectionState;
3305}
3306
Jeff Brown7fbdc842010-06-17 20:52:56 -07003307void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brownb6997262010-10-08 22:31:17 -07003308 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003309 entry->type = type;
3310 entry->refCount = 1;
3311 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07003312 entry->eventTime = eventTime;
Jeff Brownb6997262010-10-08 22:31:17 -07003313 entry->policyFlags = policyFlags;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003314 entry->injectionState = NULL;
3315}
3316
3317void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3318 if (entry->injectionState) {
3319 releaseInjectionState(entry->injectionState);
3320 entry->injectionState = NULL;
3321 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07003322}
3323
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003324InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07003325InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003326 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003327 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003328 return entry;
3329}
3330
Jeff Brown7fbdc842010-06-17 20:52:56 -07003331InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown58a2da82011-01-25 16:02:22 -08003332 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003333 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3334 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003335 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003336 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003337
3338 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003339 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003340 entry->action = action;
3341 entry->flags = flags;
3342 entry->keyCode = keyCode;
3343 entry->scanCode = scanCode;
3344 entry->metaState = metaState;
3345 entry->repeatCount = repeatCount;
3346 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003347 entry->syntheticRepeat = false;
3348 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003349 return entry;
3350}
3351
Jeff Brown7fbdc842010-06-17 20:52:56 -07003352InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown58a2da82011-01-25 16:02:22 -08003353 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003354 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3355 nsecs_t downTime, uint32_t pointerCount,
3356 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003357 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003358 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003359
3360 entry->eventTime = eventTime;
3361 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003362 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003363 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07003364 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003365 entry->metaState = metaState;
3366 entry->edgeFlags = edgeFlags;
3367 entry->xPrecision = xPrecision;
3368 entry->yPrecision = yPrecision;
3369 entry->downTime = downTime;
3370 entry->pointerCount = pointerCount;
3371 entry->firstSample.eventTime = eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003372 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003373 entry->lastSample = & entry->firstSample;
3374 for (uint32_t i = 0; i < pointerCount; i++) {
3375 entry->pointerIds[i] = pointerIds[i];
3376 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3377 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003378 return entry;
3379}
3380
3381InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07003382 EventEntry* eventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07003383 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003384 DispatchEntry* entry = mDispatchEntryPool.alloc();
3385 entry->eventEntry = eventEntry;
3386 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07003387 entry->targetFlags = targetFlags;
3388 entry->xOffset = xOffset;
3389 entry->yOffset = yOffset;
Jeff Brownb88102f2010-09-08 11:49:43 -07003390 entry->inProgress = false;
3391 entry->headMotionSample = NULL;
3392 entry->tailMotionSample = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003393 return entry;
3394}
3395
Jeff Brown9c3cda02010-06-15 01:31:58 -07003396InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3397 CommandEntry* entry = mCommandEntryPool.alloc();
3398 entry->command = command;
3399 return entry;
3400}
3401
Jeff Brown01ce2e92010-09-26 22:20:12 -07003402void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3403 injectionState->refCount -= 1;
3404 if (injectionState->refCount == 0) {
3405 mInjectionStatePool.free(injectionState);
3406 } else {
3407 assert(injectionState->refCount > 0);
3408 }
3409}
3410
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003411void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3412 switch (entry->type) {
3413 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3414 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3415 break;
3416 case EventEntry::TYPE_KEY:
3417 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3418 break;
3419 case EventEntry::TYPE_MOTION:
3420 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3421 break;
3422 default:
3423 assert(false);
3424 break;
3425 }
3426}
3427
3428void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3429 ConfigurationChangedEntry* entry) {
3430 entry->refCount -= 1;
3431 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003432 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003433 mConfigurationChangeEntryPool.free(entry);
3434 } else {
3435 assert(entry->refCount > 0);
3436 }
3437}
3438
3439void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3440 entry->refCount -= 1;
3441 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003442 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003443 mKeyEntryPool.free(entry);
3444 } else {
3445 assert(entry->refCount > 0);
3446 }
3447}
3448
3449void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3450 entry->refCount -= 1;
3451 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003452 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003453 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3454 MotionSample* next = sample->next;
3455 mMotionSamplePool.free(sample);
3456 sample = next;
3457 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003458 mMotionEntryPool.free(entry);
3459 } else {
3460 assert(entry->refCount > 0);
3461 }
3462}
3463
3464void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3465 releaseEventEntry(entry->eventEntry);
3466 mDispatchEntryPool.free(entry);
3467}
3468
Jeff Brown9c3cda02010-06-15 01:31:58 -07003469void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3470 mCommandEntryPool.free(entry);
3471}
3472
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003473void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003474 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003475 MotionSample* sample = mMotionSamplePool.alloc();
3476 sample->eventTime = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003477 uint32_t pointerCount = motionEntry->pointerCount;
3478 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003479 sample->pointerCoords[i] = pointerCoords[i];
3480 }
3481
3482 sample->next = NULL;
3483 motionEntry->lastSample->next = sample;
3484 motionEntry->lastSample = sample;
3485}
3486
Jeff Brown01ce2e92010-09-26 22:20:12 -07003487void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3488 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003489
Jeff Brown01ce2e92010-09-26 22:20:12 -07003490 keyEntry->dispatchInProgress = false;
3491 keyEntry->syntheticRepeat = false;
3492 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003493}
3494
3495
Jeff Brownae9fc032010-08-18 15:51:08 -07003496// --- InputDispatcher::MotionEntry ---
3497
3498uint32_t InputDispatcher::MotionEntry::countSamples() const {
3499 uint32_t count = 1;
3500 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3501 count += 1;
3502 }
3503 return count;
3504}
3505
Jeff Brownb88102f2010-09-08 11:49:43 -07003506
3507// --- InputDispatcher::InputState ---
3508
Jeff Brownb6997262010-10-08 22:31:17 -07003509InputDispatcher::InputState::InputState() {
Jeff Brownb88102f2010-09-08 11:49:43 -07003510}
3511
3512InputDispatcher::InputState::~InputState() {
3513}
3514
3515bool InputDispatcher::InputState::isNeutral() const {
3516 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3517}
3518
Jeff Brownb88102f2010-09-08 11:49:43 -07003519InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3520 const EventEntry* entry) {
3521 switch (entry->type) {
3522 case EventEntry::TYPE_KEY:
3523 return trackKey(static_cast<const KeyEntry*>(entry));
3524
3525 case EventEntry::TYPE_MOTION:
3526 return trackMotion(static_cast<const MotionEntry*>(entry));
3527
3528 default:
3529 return CONSISTENT;
3530 }
3531}
3532
3533InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3534 const KeyEntry* entry) {
3535 int32_t action = entry->action;
3536 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3537 KeyMemento& memento = mKeyMementos.editItemAt(i);
3538 if (memento.deviceId == entry->deviceId
3539 && memento.source == entry->source
3540 && memento.keyCode == entry->keyCode
3541 && memento.scanCode == entry->scanCode) {
3542 switch (action) {
3543 case AKEY_EVENT_ACTION_UP:
3544 mKeyMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003545 return CONSISTENT;
3546
3547 case AKEY_EVENT_ACTION_DOWN:
3548 return TOLERABLE;
3549
3550 default:
3551 return BROKEN;
3552 }
3553 }
3554 }
3555
3556 switch (action) {
3557 case AKEY_EVENT_ACTION_DOWN: {
3558 mKeyMementos.push();
3559 KeyMemento& memento = mKeyMementos.editTop();
3560 memento.deviceId = entry->deviceId;
3561 memento.source = entry->source;
3562 memento.keyCode = entry->keyCode;
3563 memento.scanCode = entry->scanCode;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003564 memento.flags = entry->flags;
Jeff Brownb88102f2010-09-08 11:49:43 -07003565 memento.downTime = entry->downTime;
3566 return CONSISTENT;
3567 }
3568
3569 default:
3570 return BROKEN;
3571 }
3572}
3573
3574InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3575 const MotionEntry* entry) {
3576 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3577 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3578 MotionMemento& memento = mMotionMementos.editItemAt(i);
3579 if (memento.deviceId == entry->deviceId
3580 && memento.source == entry->source) {
3581 switch (action) {
3582 case AMOTION_EVENT_ACTION_UP:
3583 case AMOTION_EVENT_ACTION_CANCEL:
3584 mMotionMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003585 return CONSISTENT;
3586
3587 case AMOTION_EVENT_ACTION_DOWN:
3588 return TOLERABLE;
3589
3590 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3591 if (entry->pointerCount == memento.pointerCount + 1) {
3592 memento.setPointers(entry);
3593 return CONSISTENT;
3594 }
3595 return BROKEN;
3596
3597 case AMOTION_EVENT_ACTION_POINTER_UP:
3598 if (entry->pointerCount == memento.pointerCount - 1) {
3599 memento.setPointers(entry);
3600 return CONSISTENT;
3601 }
3602 return BROKEN;
3603
3604 case AMOTION_EVENT_ACTION_MOVE:
3605 if (entry->pointerCount == memento.pointerCount) {
3606 return CONSISTENT;
3607 }
3608 return BROKEN;
3609
3610 default:
3611 return BROKEN;
3612 }
3613 }
3614 }
3615
3616 switch (action) {
3617 case AMOTION_EVENT_ACTION_DOWN: {
3618 mMotionMementos.push();
3619 MotionMemento& memento = mMotionMementos.editTop();
3620 memento.deviceId = entry->deviceId;
3621 memento.source = entry->source;
3622 memento.xPrecision = entry->xPrecision;
3623 memento.yPrecision = entry->yPrecision;
3624 memento.downTime = entry->downTime;
3625 memento.setPointers(entry);
3626 return CONSISTENT;
3627 }
3628
3629 default:
3630 return BROKEN;
3631 }
3632}
3633
3634void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3635 pointerCount = entry->pointerCount;
3636 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3637 pointerIds[i] = entry->pointerIds[i];
3638 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3639 }
3640}
3641
Jeff Brownb6997262010-10-08 22:31:17 -07003642void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3643 Allocator* allocator, Vector<EventEntry*>& outEvents,
3644 CancelationOptions options) {
3645 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003646 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003647 if (shouldCancelKey(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003648 outEvents.push(allocator->obtainKeyEntry(currentTime,
3649 memento.deviceId, memento.source, 0,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003650 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
Jeff Brownb6997262010-10-08 22:31:17 -07003651 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3652 mKeyMementos.removeAt(i);
3653 } else {
3654 i += 1;
3655 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003656 }
3657
Jeff Browna1160a72010-10-11 18:22:53 -07003658 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003659 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003660 if (shouldCancelMotion(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003661 outEvents.push(allocator->obtainMotionEntry(currentTime,
3662 memento.deviceId, memento.source, 0,
3663 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3664 memento.xPrecision, memento.yPrecision, memento.downTime,
3665 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3666 mMotionMementos.removeAt(i);
3667 } else {
3668 i += 1;
3669 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003670 }
3671}
3672
3673void InputDispatcher::InputState::clear() {
3674 mKeyMementos.clear();
3675 mMotionMementos.clear();
Jeff Brownb6997262010-10-08 22:31:17 -07003676}
3677
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003678void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3679 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3680 const MotionMemento& memento = mMotionMementos.itemAt(i);
3681 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3682 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3683 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3684 if (memento.deviceId == otherMemento.deviceId
3685 && memento.source == otherMemento.source) {
3686 other.mMotionMementos.removeAt(j);
3687 } else {
3688 j += 1;
3689 }
3690 }
3691 other.mMotionMementos.push(memento);
3692 }
3693 }
3694}
3695
Jeff Brown49ed71d2010-12-06 17:13:33 -08003696bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
Jeff Brownb6997262010-10-08 22:31:17 -07003697 CancelationOptions options) {
3698 switch (options) {
Jeff Brown49ed71d2010-12-06 17:13:33 -08003699 case CANCEL_ALL_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003700 case CANCEL_NON_POINTER_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003701 return true;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003702 case CANCEL_FALLBACK_EVENTS:
3703 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
3704 default:
3705 return false;
3706 }
3707}
3708
3709bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
3710 CancelationOptions options) {
3711 switch (options) {
3712 case CANCEL_ALL_EVENTS:
3713 return true;
3714 case CANCEL_POINTER_EVENTS:
3715 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
3716 case CANCEL_NON_POINTER_EVENTS:
3717 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
3718 default:
3719 return false;
Jeff Brownb6997262010-10-08 22:31:17 -07003720 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003721}
3722
3723
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003724// --- InputDispatcher::Connection ---
3725
Jeff Brown928e0542011-01-10 11:17:36 -08003726InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
3727 const sp<InputWindowHandle>& inputWindowHandle) :
3728 status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
3729 inputPublisher(inputChannel),
Jeff Brown519e0242010-09-15 15:18:56 -07003730 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003731}
3732
3733InputDispatcher::Connection::~Connection() {
3734}
3735
3736status_t InputDispatcher::Connection::initialize() {
3737 return inputPublisher.initialize();
3738}
3739
Jeff Brown9c3cda02010-06-15 01:31:58 -07003740const char* InputDispatcher::Connection::getStatusLabel() const {
3741 switch (status) {
3742 case STATUS_NORMAL:
3743 return "NORMAL";
3744
3745 case STATUS_BROKEN:
3746 return "BROKEN";
3747
Jeff Brown9c3cda02010-06-15 01:31:58 -07003748 case STATUS_ZOMBIE:
3749 return "ZOMBIE";
3750
3751 default:
3752 return "UNKNOWN";
3753 }
3754}
3755
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003756InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3757 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07003758 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3759 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003760 if (dispatchEntry->eventEntry == eventEntry) {
3761 return dispatchEntry;
3762 }
3763 }
3764 return NULL;
3765}
3766
Jeff Brownb88102f2010-09-08 11:49:43 -07003767
Jeff Brown9c3cda02010-06-15 01:31:58 -07003768// --- InputDispatcher::CommandEntry ---
3769
Jeff Brownb88102f2010-09-08 11:49:43 -07003770InputDispatcher::CommandEntry::CommandEntry() :
3771 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003772}
3773
3774InputDispatcher::CommandEntry::~CommandEntry() {
3775}
3776
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003777
Jeff Brown01ce2e92010-09-26 22:20:12 -07003778// --- InputDispatcher::TouchState ---
3779
3780InputDispatcher::TouchState::TouchState() :
Jeff Brown58a2da82011-01-25 16:02:22 -08003781 down(false), split(false), deviceId(-1), source(0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003782}
3783
3784InputDispatcher::TouchState::~TouchState() {
3785}
3786
3787void InputDispatcher::TouchState::reset() {
3788 down = false;
3789 split = false;
Jeff Brown95712852011-01-04 19:41:59 -08003790 deviceId = -1;
Jeff Brown58a2da82011-01-25 16:02:22 -08003791 source = 0;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003792 windows.clear();
3793}
3794
3795void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3796 down = other.down;
3797 split = other.split;
Jeff Brown95712852011-01-04 19:41:59 -08003798 deviceId = other.deviceId;
Jeff Brown58a2da82011-01-25 16:02:22 -08003799 source = other.source;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003800 windows.clear();
3801 windows.appendVector(other.windows);
3802}
3803
3804void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3805 int32_t targetFlags, BitSet32 pointerIds) {
3806 if (targetFlags & InputTarget::FLAG_SPLIT) {
3807 split = true;
3808 }
3809
3810 for (size_t i = 0; i < windows.size(); i++) {
3811 TouchedWindow& touchedWindow = windows.editItemAt(i);
3812 if (touchedWindow.window == window) {
3813 touchedWindow.targetFlags |= targetFlags;
3814 touchedWindow.pointerIds.value |= pointerIds.value;
3815 return;
3816 }
3817 }
3818
3819 windows.push();
3820
3821 TouchedWindow& touchedWindow = windows.editTop();
3822 touchedWindow.window = window;
3823 touchedWindow.targetFlags = targetFlags;
3824 touchedWindow.pointerIds = pointerIds;
3825 touchedWindow.channel = window->inputChannel;
3826}
3827
3828void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3829 for (size_t i = 0 ; i < windows.size(); ) {
3830 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3831 windows.removeAt(i);
3832 } else {
3833 i += 1;
3834 }
3835 }
3836}
3837
3838const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3839 for (size_t i = 0; i < windows.size(); i++) {
3840 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3841 return windows[i].window;
3842 }
3843 }
3844 return NULL;
3845}
3846
3847
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003848// --- InputDispatcherThread ---
3849
3850InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3851 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3852}
3853
3854InputDispatcherThread::~InputDispatcherThread() {
3855}
3856
3857bool InputDispatcherThread::threadLoop() {
3858 mDispatcher->dispatchOnce();
3859 return true;
3860}
3861
3862} // namespace android