blob: ae11fb1e025efd26f9bbf88d711eee9652607b85 [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) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800485 int32_t x = int32_t(motionEntry->firstSample.pointerCoords[0].
Jeff Brownebbd5d12011-02-17 13:01:34 -0800486 getAxisValue(AMOTION_EVENT_AXIS_X));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800487 int32_t y = int32_t(motionEntry->firstSample.pointerCoords[0].
Jeff Brownebbd5d12011-02-17 13:01:34 -0800488 getAxisValue(AMOTION_EVENT_AXIS_Y));
Jeff Brown928e0542011-01-10 11:17:36 -0800489 const InputWindow* touchedWindow = findTouchedWindowAtLocked(x, y);
490 if (touchedWindow
491 && touchedWindow->inputWindowHandle != NULL
492 && touchedWindow->inputWindowHandle->getInputApplicationHandle()
493 != mInputTargetWaitApplication) {
494 // User touched a different application than the one we are waiting on.
495 // Flag the event, and start pruning the input queue.
496 mNextUnblockedEvent = motionEntry;
497 needWake = true;
498 }
499 }
500 break;
501 }
Jeff Brownb6997262010-10-08 22:31:17 -0700502 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700503
504 return needWake;
505}
506
Jeff Brown928e0542011-01-10 11:17:36 -0800507const InputWindow* InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
508 // Traverse windows from front to back to find touched window.
509 size_t numWindows = mWindows.size();
510 for (size_t i = 0; i < numWindows; i++) {
511 const InputWindow* window = & mWindows.editItemAt(i);
512 int32_t flags = window->layoutParamsFlags;
513
514 if (window->visible) {
515 if (!(flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
516 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
517 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
Jeff Brownfbf09772011-01-16 14:06:57 -0800518 if (isTouchModal || window->touchableRegionContainsPoint(x, y)) {
Jeff Brown928e0542011-01-10 11:17:36 -0800519 // Found window.
520 return window;
521 }
522 }
523 }
524
525 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
526 // Error window is on top but not visible, so touch is dropped.
527 return NULL;
528 }
529 }
530 return NULL;
531}
532
Jeff Brownb6997262010-10-08 22:31:17 -0700533void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
534 const char* reason;
535 switch (dropReason) {
536 case DROP_REASON_POLICY:
Jeff Browne20c9e02010-10-11 14:20:19 -0700537#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown3122e442010-10-11 23:32:49 -0700538 LOGD("Dropped event because policy consumed it.");
Jeff Browne20c9e02010-10-11 14:20:19 -0700539#endif
Jeff Brown3122e442010-10-11 23:32:49 -0700540 reason = "inbound event was dropped because the policy consumed it";
Jeff Brownb6997262010-10-08 22:31:17 -0700541 break;
542 case DROP_REASON_DISABLED:
543 LOGI("Dropped event because input dispatch is disabled.");
544 reason = "inbound event was dropped because input dispatch is disabled";
545 break;
546 case DROP_REASON_APP_SWITCH:
547 LOGI("Dropped event because of pending overdue app switch.");
548 reason = "inbound event was dropped because of pending overdue app switch";
549 break;
Jeff Brown928e0542011-01-10 11:17:36 -0800550 case DROP_REASON_BLOCKED:
551 LOGI("Dropped event because the current application is not responding and the user "
552 "has started interating with a different application.");
553 reason = "inbound event was dropped because the current application is not responding "
554 "and the user has started interating with a different application";
555 break;
556 case DROP_REASON_STALE:
557 LOGI("Dropped event because it is stale.");
558 reason = "inbound event was dropped because it is stale";
559 break;
Jeff Brownb6997262010-10-08 22:31:17 -0700560 default:
561 assert(false);
562 return;
563 }
564
565 switch (entry->type) {
566 case EventEntry::TYPE_KEY:
567 synthesizeCancelationEventsForAllConnectionsLocked(
568 InputState::CANCEL_NON_POINTER_EVENTS, reason);
569 break;
570 case EventEntry::TYPE_MOTION: {
571 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
572 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
573 synthesizeCancelationEventsForAllConnectionsLocked(
574 InputState::CANCEL_POINTER_EVENTS, reason);
575 } else {
576 synthesizeCancelationEventsForAllConnectionsLocked(
577 InputState::CANCEL_NON_POINTER_EVENTS, reason);
578 }
579 break;
580 }
581 }
582}
583
584bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700585 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
586}
587
Jeff Brownb6997262010-10-08 22:31:17 -0700588bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
589 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
590 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Browne20c9e02010-10-11 14:20:19 -0700591 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brownb6997262010-10-08 22:31:17 -0700592 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
593}
594
Jeff Brownb88102f2010-09-08 11:49:43 -0700595bool InputDispatcher::isAppSwitchPendingLocked() {
596 return mAppSwitchDueTime != LONG_LONG_MAX;
597}
598
Jeff Brownb88102f2010-09-08 11:49:43 -0700599void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
600 mAppSwitchDueTime = LONG_LONG_MAX;
601
602#if DEBUG_APP_SWITCH
603 if (handled) {
604 LOGD("App switch has arrived.");
605 } else {
606 LOGD("App switch was abandoned.");
607 }
608#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700609}
610
Jeff Brown928e0542011-01-10 11:17:36 -0800611bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
612 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
613}
614
Jeff Brown9c3cda02010-06-15 01:31:58 -0700615bool InputDispatcher::runCommandsLockedInterruptible() {
616 if (mCommandQueue.isEmpty()) {
617 return false;
618 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700619
Jeff Brown9c3cda02010-06-15 01:31:58 -0700620 do {
621 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
622
623 Command command = commandEntry->command;
624 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
625
Jeff Brown7fbdc842010-06-17 20:52:56 -0700626 commandEntry->connection.clear();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700627 mAllocator.releaseCommandEntry(commandEntry);
628 } while (! mCommandQueue.isEmpty());
629 return true;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700630}
631
Jeff Brown9c3cda02010-06-15 01:31:58 -0700632InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
633 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
634 mCommandQueue.enqueueAtTail(commandEntry);
635 return commandEntry;
636}
637
Jeff Brownb88102f2010-09-08 11:49:43 -0700638void InputDispatcher::drainInboundQueueLocked() {
639 while (! mInboundQueue.isEmpty()) {
640 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700641 releaseInboundEventLocked(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700642 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700643}
644
Jeff Brown54a18252010-09-16 14:07:33 -0700645void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700646 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700647 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700648 mPendingEvent = NULL;
649 }
650}
651
Jeff Brown54a18252010-09-16 14:07:33 -0700652void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700653 InjectionState* injectionState = entry->injectionState;
654 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700655#if DEBUG_DISPATCH_CYCLE
Jeff Brown01ce2e92010-09-26 22:20:12 -0700656 LOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700657#endif
658 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
659 }
660 mAllocator.releaseEventEntry(entry);
661}
662
Jeff Brownb88102f2010-09-08 11:49:43 -0700663void InputDispatcher::resetKeyRepeatLocked() {
664 if (mKeyRepeatState.lastKeyEntry) {
665 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
666 mKeyRepeatState.lastKeyEntry = NULL;
667 }
668}
669
670InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brownb21fb102010-09-07 10:44:57 -0700671 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown349703e2010-06-22 01:27:15 -0700672 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
673
Jeff Brown349703e2010-06-22 01:27:15 -0700674 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Browne20c9e02010-10-11 14:20:19 -0700675 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
676 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700677 if (entry->refCount == 1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700678 mAllocator.recycleKeyEntry(entry);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700679 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700680 entry->policyFlags = policyFlags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700681 entry->repeatCount += 1;
682 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700683 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700684 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700685 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700686 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700687
688 mKeyRepeatState.lastKeyEntry = newEntry;
689 mAllocator.releaseKeyEntry(entry);
690
691 entry = newEntry;
692 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700693 entry->syntheticRepeat = true;
694
695 // Increment reference count since we keep a reference to the event in
696 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
697 entry->refCount += 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700698
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700699 if (entry->repeatCount == 1) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700700 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700701 }
702
Jeff Brownb21fb102010-09-07 10:44:57 -0700703 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700704 return entry;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700705}
706
Jeff Brownb88102f2010-09-08 11:49:43 -0700707bool InputDispatcher::dispatchConfigurationChangedLocked(
708 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700709#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownb88102f2010-09-08 11:49:43 -0700710 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
711#endif
712
713 // Reset key repeating in case a keyboard device was added or removed or something.
714 resetKeyRepeatLocked();
715
716 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
717 CommandEntry* commandEntry = postCommandLocked(
718 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
719 commandEntry->eventTime = entry->eventTime;
720 return true;
721}
722
723bool InputDispatcher::dispatchKeyLocked(
724 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Browne20c9e02010-10-11 14:20:19 -0700725 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700726 // Preprocessing.
727 if (! entry->dispatchInProgress) {
728 if (entry->repeatCount == 0
729 && entry->action == AKEY_EVENT_ACTION_DOWN
730 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
731 && !entry->isInjected()) {
732 if (mKeyRepeatState.lastKeyEntry
733 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
734 // We have seen two identical key downs in a row which indicates that the device
735 // driver is automatically generating key repeats itself. We take note of the
736 // repeat here, but we disable our own next key repeat timer since it is clear that
737 // we will not need to synthesize key repeats ourselves.
738 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
739 resetKeyRepeatLocked();
740 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
741 } else {
742 // Not a repeat. Save key down state in case we do see a repeat later.
743 resetKeyRepeatLocked();
744 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
745 }
746 mKeyRepeatState.lastKeyEntry = entry;
747 entry->refCount += 1;
748 } else if (! entry->syntheticRepeat) {
749 resetKeyRepeatLocked();
750 }
751
752 entry->dispatchInProgress = true;
753 resetTargetsLocked();
754
755 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
756 }
757
Jeff Brown54a18252010-09-16 14:07:33 -0700758 // Give the policy a chance to intercept the key.
759 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700760 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brown54a18252010-09-16 14:07:33 -0700761 CommandEntry* commandEntry = postCommandLocked(
762 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Browne20c9e02010-10-11 14:20:19 -0700763 if (mFocusedWindow) {
Jeff Brown928e0542011-01-10 11:17:36 -0800764 commandEntry->inputWindowHandle = mFocusedWindow->inputWindowHandle;
Jeff Brown54a18252010-09-16 14:07:33 -0700765 }
766 commandEntry->keyEntry = entry;
767 entry->refCount += 1;
768 return false; // wait for the command to run
769 } else {
770 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
771 }
772 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700773 if (*dropReason == DROP_REASON_NOT_DROPPED) {
774 *dropReason = DROP_REASON_POLICY;
775 }
Jeff Brown54a18252010-09-16 14:07:33 -0700776 }
777
778 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700779 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700780 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700781 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
782 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700783 return true;
784 }
785
Jeff Brownb88102f2010-09-08 11:49:43 -0700786 // Identify targets.
787 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700788 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
789 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700790 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
791 return false;
792 }
793
794 setInjectionResultLocked(entry, injectionResult);
795 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
796 return true;
797 }
798
799 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700800 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700801 }
802
803 // Dispatch the key.
804 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700805 return true;
806}
807
808void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
809#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800810 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brownb88102f2010-09-08 11:49:43 -0700811 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
Jeff Browne46a0a42010-11-02 17:58:22 -0700812 "repeatCount=%d, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700813 prefix,
814 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
815 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Jeff Browne46a0a42010-11-02 17:58:22 -0700816 entry->repeatCount, entry->downTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700817#endif
818}
819
820bool InputDispatcher::dispatchMotionLocked(
Jeff Browne20c9e02010-10-11 14:20:19 -0700821 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700822 // Preprocessing.
823 if (! entry->dispatchInProgress) {
824 entry->dispatchInProgress = true;
825 resetTargetsLocked();
826
827 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
828 }
829
Jeff Brown54a18252010-09-16 14:07:33 -0700830 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700831 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700832 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700833 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
834 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700835 return true;
836 }
837
Jeff Brownb88102f2010-09-08 11:49:43 -0700838 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
839
840 // Identify targets.
841 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700842 int32_t injectionResult;
843 if (isPointerEvent) {
844 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700845 injectionResult = findTouchedWindowTargetsLocked(currentTime,
846 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700847 } else {
848 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700849 injectionResult = findFocusedWindowTargetsLocked(currentTime,
850 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700851 }
852 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
853 return false;
854 }
855
856 setInjectionResultLocked(entry, injectionResult);
857 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
858 return true;
859 }
860
861 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700862 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700863 }
864
865 // Dispatch the motion.
866 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700867 return true;
868}
869
870
871void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
872#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800873 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700874 "action=0x%x, flags=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700875 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700876 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700877 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
878 entry->action, entry->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700879 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
880 entry->downTime);
881
882 // Print the most recent sample that we have available, this may change due to batching.
883 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700884 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700885 for (; sample->next != NULL; sample = sample->next) {
886 sampleCount += 1;
887 }
888 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -0700889 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700890 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700891 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700892 i, entry->pointerIds[i],
Jeff Brownebbd5d12011-02-17 13:01:34 -0800893 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
894 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
895 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
896 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
897 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
898 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
899 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
900 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
901 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700902 }
903
904 // Keep in mind that due to batching, it is possible for the number of samples actually
905 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700906 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700907 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
908 }
909#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700910}
911
912void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
913 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
914#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -0700915 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700916 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700917 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700918#endif
919
Jeff Brown9c3cda02010-06-15 01:31:58 -0700920 assert(eventEntry->dispatchInProgress); // should already have been set to true
921
Jeff Browne2fe69e2010-10-18 13:21:23 -0700922 pokeUserActivityLocked(eventEntry);
923
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700924 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
925 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
926
Jeff Brown519e0242010-09-15 15:18:56 -0700927 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700928 if (connectionIndex >= 0) {
929 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700930 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700931 resumeWithAppendedMotionSample);
932 } else {
Jeff Brownb6997262010-10-08 22:31:17 -0700933#if DEBUG_FOCUS
934 LOGD("Dropping event delivery to target with channel '%s' because it "
935 "is no longer registered with the input dispatcher.",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700936 inputTarget.inputChannel->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -0700937#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700938 }
939 }
940}
941
Jeff Brown54a18252010-09-16 14:07:33 -0700942void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700943 mCurrentInputTargetsValid = false;
944 mCurrentInputTargets.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700945 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Jeff Brown928e0542011-01-10 11:17:36 -0800946 mInputTargetWaitApplication.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700947}
948
Jeff Brown01ce2e92010-09-26 22:20:12 -0700949void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700950 mCurrentInputTargetsValid = true;
951}
952
953int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
954 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
955 nsecs_t* nextWakeupTime) {
956 if (application == NULL && window == NULL) {
957 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
958#if DEBUG_FOCUS
959 LOGD("Waiting for system to become ready for input.");
960#endif
961 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
962 mInputTargetWaitStartTime = currentTime;
963 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
964 mInputTargetWaitTimeoutExpired = false;
Jeff Brown928e0542011-01-10 11:17:36 -0800965 mInputTargetWaitApplication.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700966 }
967 } else {
968 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
969#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700970 LOGD("Waiting for application to become ready for input: %s",
971 getApplicationWindowLabelLocked(application, window).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700972#endif
973 nsecs_t timeout = window ? window->dispatchingTimeout :
974 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
975
976 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
977 mInputTargetWaitStartTime = currentTime;
978 mInputTargetWaitTimeoutTime = currentTime + timeout;
979 mInputTargetWaitTimeoutExpired = false;
Jeff Brown928e0542011-01-10 11:17:36 -0800980 mInputTargetWaitApplication.clear();
981
982 if (window && window->inputWindowHandle != NULL) {
983 mInputTargetWaitApplication =
984 window->inputWindowHandle->getInputApplicationHandle();
985 }
986 if (mInputTargetWaitApplication == NULL && application) {
987 mInputTargetWaitApplication = application->inputApplicationHandle;
988 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700989 }
990 }
991
992 if (mInputTargetWaitTimeoutExpired) {
993 return INPUT_EVENT_INJECTION_TIMED_OUT;
994 }
995
996 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown519e0242010-09-15 15:18:56 -0700997 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700998
999 // Force poll loop to wake up immediately on next iteration once we get the
1000 // ANR response back from the policy.
1001 *nextWakeupTime = LONG_LONG_MIN;
1002 return INPUT_EVENT_INJECTION_PENDING;
1003 } else {
1004 // Force poll loop to wake up when timeout is due.
1005 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1006 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1007 }
1008 return INPUT_EVENT_INJECTION_PENDING;
1009 }
1010}
1011
Jeff Brown519e0242010-09-15 15:18:56 -07001012void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1013 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001014 if (newTimeout > 0) {
1015 // Extend the timeout.
1016 mInputTargetWaitTimeoutTime = now() + newTimeout;
1017 } else {
1018 // Give up.
1019 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -07001020
Jeff Brown01ce2e92010-09-26 22:20:12 -07001021 // Release the touch targets.
1022 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07001023
Jeff Brown519e0242010-09-15 15:18:56 -07001024 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -07001025 if (inputChannel.get()) {
1026 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1027 if (connectionIndex >= 0) {
1028 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown00045a72010-12-09 18:10:30 -08001029 if (connection->status == Connection::STATUS_NORMAL) {
1030 synthesizeCancelationEventsForConnectionLocked(
1031 connection, InputState::CANCEL_ALL_EVENTS,
1032 "application not responding");
1033 }
Jeff Browndc3e0052010-09-16 11:02:16 -07001034 }
Jeff Brown519e0242010-09-15 15:18:56 -07001035 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001036 }
1037}
1038
Jeff Brown519e0242010-09-15 15:18:56 -07001039nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -07001040 nsecs_t currentTime) {
1041 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1042 return currentTime - mInputTargetWaitStartTime;
1043 }
1044 return 0;
1045}
1046
1047void InputDispatcher::resetANRTimeoutsLocked() {
1048#if DEBUG_FOCUS
1049 LOGD("Resetting ANR timeouts.");
1050#endif
1051
Jeff Brownb88102f2010-09-08 11:49:43 -07001052 // Reset input target wait timeout.
1053 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
1054}
1055
Jeff Brown01ce2e92010-09-26 22:20:12 -07001056int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
1057 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001058 mCurrentInputTargets.clear();
1059
1060 int32_t injectionResult;
1061
1062 // If there is no currently focused window and no focused application
1063 // then drop the event.
1064 if (! mFocusedWindow) {
1065 if (mFocusedApplication) {
1066#if DEBUG_FOCUS
1067 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001068 "focused application that may eventually add a window: %s.",
1069 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001070#endif
1071 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1072 mFocusedApplication, NULL, nextWakeupTime);
1073 goto Unresponsive;
1074 }
1075
1076 LOGI("Dropping event because there is no focused window or focused application.");
1077 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1078 goto Failed;
1079 }
1080
1081 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001082 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001083 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1084 goto Failed;
1085 }
1086
1087 // If the currently focused window is paused then keep waiting.
1088 if (mFocusedWindow->paused) {
1089#if DEBUG_FOCUS
1090 LOGD("Waiting because focused window is paused.");
1091#endif
1092 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1093 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1094 goto Unresponsive;
1095 }
1096
Jeff Brown519e0242010-09-15 15:18:56 -07001097 // If the currently focused window is still working on previous events then keep waiting.
1098 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
1099#if DEBUG_FOCUS
1100 LOGD("Waiting because focused window still processing previous input.");
1101#endif
1102 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1103 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1104 goto Unresponsive;
1105 }
1106
Jeff Brownb88102f2010-09-08 11:49:43 -07001107 // Success! Output targets.
1108 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001109 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001110
1111 // Done.
1112Failed:
1113Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001114 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1115 updateDispatchStatisticsLocked(currentTime, entry,
1116 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001117#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -07001118 LOGD("findFocusedWindow finished: injectionResult=%d, "
1119 "timeSpendWaitingForApplication=%0.1fms",
1120 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001121#endif
1122 return injectionResult;
1123}
1124
Jeff Brown01ce2e92010-09-26 22:20:12 -07001125int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1126 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001127 enum InjectionPermission {
1128 INJECTION_PERMISSION_UNKNOWN,
1129 INJECTION_PERMISSION_GRANTED,
1130 INJECTION_PERMISSION_DENIED
1131 };
1132
Jeff Brownb88102f2010-09-08 11:49:43 -07001133 mCurrentInputTargets.clear();
1134
1135 nsecs_t startTime = now();
1136
1137 // For security reasons, we defer updating the touch state until we are sure that
1138 // event injection will be allowed.
1139 //
1140 // FIXME In the original code, screenWasOff could never be set to true.
1141 // The reason is that the POLICY_FLAG_WOKE_HERE
1142 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1143 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1144 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1145 // events upon which no preprocessing took place. So policyFlags was always 0.
1146 // In the new native input dispatcher we're a bit more careful about event
1147 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1148 // Unfortunately we obtain undesirable behavior.
1149 //
1150 // Here's what happens:
1151 //
1152 // When the device dims in anticipation of going to sleep, touches
1153 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1154 // the device to brighten and reset the user activity timer.
1155 // Touches on other windows (such as the launcher window)
1156 // are dropped. Then after a moment, the device goes to sleep. Oops.
1157 //
1158 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1159 // instead of POLICY_FLAG_WOKE_HERE...
1160 //
1161 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1162
1163 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001164 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001165
1166 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001167 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1168 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Jeff Brown95712852011-01-04 19:41:59 -08001169 bool isSplit, wrongDevice;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001170 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1171 mTempTouchState.reset();
1172 mTempTouchState.down = true;
Jeff Brown95712852011-01-04 19:41:59 -08001173 mTempTouchState.deviceId = entry->deviceId;
Jeff Brown58a2da82011-01-25 16:02:22 -08001174 mTempTouchState.source = entry->source;
Jeff Brown95712852011-01-04 19:41:59 -08001175 isSplit = false;
1176 wrongDevice = false;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001177 } else {
1178 mTempTouchState.copyFrom(mTouchState);
Jeff Brown95712852011-01-04 19:41:59 -08001179 isSplit = mTempTouchState.split;
Jeff Brown58a2da82011-01-25 16:02:22 -08001180 wrongDevice = mTempTouchState.down
1181 && (mTempTouchState.deviceId != entry->deviceId
1182 || mTempTouchState.source != entry->source);
Jeff Brown95712852011-01-04 19:41:59 -08001183 if (wrongDevice) {
1184#if DEBUG_INPUT_DISPATCHER_POLICY
1185 LOGD("Dropping event because a pointer for a different device is already down.");
1186#endif
1187 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1188 goto Failed;
1189 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001190 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001191
Jeff Brown01ce2e92010-09-26 22:20:12 -07001192 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1193 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1194 /* Case 1: New splittable pointer going down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001195
Jeff Brown01ce2e92010-09-26 22:20:12 -07001196 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Jeff Brown91c69ab2011-02-14 17:03:18 -08001197 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].
Jeff Brownebbd5d12011-02-17 13:01:34 -08001198 getAxisValue(AMOTION_EVENT_AXIS_X));
Jeff Brown91c69ab2011-02-14 17:03:18 -08001199 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].
Jeff Brownebbd5d12011-02-17 13:01:34 -08001200 getAxisValue(AMOTION_EVENT_AXIS_Y));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001201 const InputWindow* newTouchedWindow = NULL;
1202 const InputWindow* topErrorWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07001203
1204 // Traverse windows from front to back to find touched window and outside targets.
1205 size_t numWindows = mWindows.size();
1206 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001207 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001208 int32_t flags = window->layoutParamsFlags;
1209
1210 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1211 if (! topErrorWindow) {
1212 topErrorWindow = window;
1213 }
1214 }
1215
1216 if (window->visible) {
1217 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1218 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1219 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
Jeff Brownfbf09772011-01-16 14:06:57 -08001220 if (isTouchModal || window->touchableRegionContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001221 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1222 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001223 }
1224 break; // found touched window, exit window loop
1225 }
1226 }
1227
Jeff Brown01ce2e92010-09-26 22:20:12 -07001228 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1229 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001230 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1231 if (isWindowObscuredAtPointLocked(window, x, y)) {
1232 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1233 }
1234
1235 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001236 }
1237 }
1238 }
1239
1240 // If there is an error window but it is not taking focus (typically because
1241 // it is invisible) then wait for it. Any other focused window may in
1242 // fact be in ANR state.
1243 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1244#if DEBUG_FOCUS
1245 LOGD("Waiting because system error window is pending.");
1246#endif
1247 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1248 NULL, NULL, nextWakeupTime);
1249 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1250 goto Unresponsive;
1251 }
1252
Jeff Brown01ce2e92010-09-26 22:20:12 -07001253 // Figure out whether splitting will be allowed for this window.
Jeff Brown46e75292010-11-10 16:53:45 -08001254 if (newTouchedWindow && newTouchedWindow->supportsSplitTouch()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001255 // New window supports splitting.
1256 isSplit = true;
1257 } else if (isSplit) {
1258 // New window does not support splitting but we have already split events.
1259 // Assign the pointer to the first foreground window we find.
1260 // (May be NULL which is why we put this code block before the next check.)
1261 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1262 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001263
Jeff Brownb88102f2010-09-08 11:49:43 -07001264 // If we did not find a touched window then fail.
1265 if (! newTouchedWindow) {
1266 if (mFocusedApplication) {
1267#if DEBUG_FOCUS
1268 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001269 "focused application that may eventually add a new window: %s.",
1270 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001271#endif
1272 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1273 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001274 goto Unresponsive;
1275 }
1276
1277 LOGI("Dropping event because there is no touched window or focused application.");
1278 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001279 goto Failed;
1280 }
1281
Jeff Brown19dfc832010-10-05 12:26:23 -07001282 // Set target flags.
1283 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1284 if (isSplit) {
1285 targetFlags |= InputTarget::FLAG_SPLIT;
1286 }
1287 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1288 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1289 }
1290
Jeff Brown01ce2e92010-09-26 22:20:12 -07001291 // Update the temporary touch state.
1292 BitSet32 pointerIds;
1293 if (isSplit) {
1294 uint32_t pointerId = entry->pointerIds[pointerIndex];
1295 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001296 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001297 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001298 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001299 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001300
1301 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001302 if (! mTempTouchState.down) {
Jeff Brown76860e32010-10-25 17:37:46 -07001303#if DEBUG_INPUT_DISPATCHER_POLICY
1304 LOGD("Dropping event because the pointer is not down or we previously "
1305 "dropped the pointer down event.");
1306#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001307 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001308 goto Failed;
1309 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001310 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001311
Jeff Brown01ce2e92010-09-26 22:20:12 -07001312 // Check permission to inject into all touched foreground windows and ensure there
1313 // is at least one touched foreground window.
1314 {
1315 bool haveForegroundWindow = false;
1316 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1317 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1318 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1319 haveForegroundWindow = true;
1320 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1321 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1322 injectionPermission = INJECTION_PERMISSION_DENIED;
1323 goto Failed;
1324 }
1325 }
1326 }
1327 if (! haveForegroundWindow) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001328#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown01ce2e92010-09-26 22:20:12 -07001329 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001330#endif
1331 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001332 goto Failed;
1333 }
1334
Jeff Brown01ce2e92010-09-26 22:20:12 -07001335 // Permission granted to injection into all touched foreground windows.
1336 injectionPermission = INJECTION_PERMISSION_GRANTED;
1337 }
Jeff Brown519e0242010-09-15 15:18:56 -07001338
Jeff Brown01ce2e92010-09-26 22:20:12 -07001339 // Ensure all touched foreground windows are ready for new input.
1340 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1341 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1342 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1343 // If the touched window is paused then keep waiting.
1344 if (touchedWindow.window->paused) {
1345#if DEBUG_INPUT_DISPATCHER_POLICY
1346 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001347#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001348 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1349 NULL, touchedWindow.window, nextWakeupTime);
1350 goto Unresponsive;
1351 }
1352
1353 // If the touched window is still working on previous events then keep waiting.
1354 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1355#if DEBUG_FOCUS
1356 LOGD("Waiting because touched window still processing previous input.");
1357#endif
1358 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1359 NULL, touchedWindow.window, nextWakeupTime);
1360 goto Unresponsive;
1361 }
1362 }
1363 }
1364
1365 // If this is the first pointer going down and the touched window has a wallpaper
1366 // then also add the touched wallpaper windows so they are locked in for the duration
1367 // of the touch gesture.
1368 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1369 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1370 if (foregroundWindow->hasWallpaper) {
1371 for (size_t i = 0; i < mWindows.size(); i++) {
1372 const InputWindow* window = & mWindows[i];
1373 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001374 mTempTouchState.addOrUpdateWindow(window,
1375 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001376 }
1377 }
1378 }
1379 }
1380
Jeff Brownb88102f2010-09-08 11:49:43 -07001381 // Success! Output targets.
1382 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001383
Jeff Brown01ce2e92010-09-26 22:20:12 -07001384 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1385 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1386 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1387 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001388 }
1389
Jeff Brown01ce2e92010-09-26 22:20:12 -07001390 // Drop the outside touch window since we will not care about them in the next iteration.
1391 mTempTouchState.removeOutsideTouchWindows();
1392
Jeff Brownb88102f2010-09-08 11:49:43 -07001393Failed:
1394 // Check injection permission once and for all.
1395 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001396 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001397 injectionPermission = INJECTION_PERMISSION_GRANTED;
1398 } else {
1399 injectionPermission = INJECTION_PERMISSION_DENIED;
1400 }
1401 }
1402
1403 // Update final pieces of touch state if the injector had permission.
1404 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown95712852011-01-04 19:41:59 -08001405 if (!wrongDevice) {
1406 if (maskedAction == AMOTION_EVENT_ACTION_UP
1407 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1408 // All pointers up or canceled.
1409 mTempTouchState.reset();
1410 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1411 // First pointer went down.
1412 if (mTouchState.down) {
Jeff Brownb6997262010-10-08 22:31:17 -07001413#if DEBUG_FOCUS
Jeff Brown95712852011-01-04 19:41:59 -08001414 LOGD("Pointer down received while already down.");
Jeff Brownb6997262010-10-08 22:31:17 -07001415#endif
Jeff Brown95712852011-01-04 19:41:59 -08001416 }
1417 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1418 // One pointer went up.
1419 if (isSplit) {
1420 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1421 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001422
Jeff Brown95712852011-01-04 19:41:59 -08001423 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1424 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1425 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1426 touchedWindow.pointerIds.clearBit(pointerId);
1427 if (touchedWindow.pointerIds.isEmpty()) {
1428 mTempTouchState.windows.removeAt(i);
1429 continue;
1430 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001431 }
Jeff Brown95712852011-01-04 19:41:59 -08001432 i += 1;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001433 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001434 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001435 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001436
Jeff Brown95712852011-01-04 19:41:59 -08001437 // Save changes to touch state.
1438 mTouchState.copyFrom(mTempTouchState);
1439 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001440 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001441#if DEBUG_FOCUS
1442 LOGD("Not updating touch focus because injection was denied.");
1443#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001444 }
1445
1446Unresponsive:
Jeff Brown120a4592010-10-27 18:43:51 -07001447 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1448 mTempTouchState.reset();
1449
Jeff Brown519e0242010-09-15 15:18:56 -07001450 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1451 updateDispatchStatisticsLocked(currentTime, entry,
1452 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001453#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001454 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1455 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001456 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001457#endif
1458 return injectionResult;
1459}
1460
Jeff Brown01ce2e92010-09-26 22:20:12 -07001461void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1462 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001463 mCurrentInputTargets.push();
1464
1465 InputTarget& target = mCurrentInputTargets.editTop();
1466 target.inputChannel = window->inputChannel;
1467 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001468 target.xOffset = - window->frameLeft;
1469 target.yOffset = - window->frameTop;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001470 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001471}
1472
1473void InputDispatcher::addMonitoringTargetsLocked() {
1474 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1475 mCurrentInputTargets.push();
1476
1477 InputTarget& target = mCurrentInputTargets.editTop();
1478 target.inputChannel = mMonitoringChannels[i];
1479 target.flags = 0;
Jeff Brownb88102f2010-09-08 11:49:43 -07001480 target.xOffset = 0;
1481 target.yOffset = 0;
1482 }
1483}
1484
1485bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001486 const InjectionState* injectionState) {
1487 if (injectionState
Jeff Brownb6997262010-10-08 22:31:17 -07001488 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1489 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1490 if (window) {
1491 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1492 "with input channel %s owned by uid %d",
1493 injectionState->injectorPid, injectionState->injectorUid,
1494 window->inputChannel->getName().string(),
1495 window->ownerUid);
1496 } else {
1497 LOGW("Permission denied: injecting event from pid %d uid %d",
1498 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001499 }
Jeff Brownb6997262010-10-08 22:31:17 -07001500 return false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001501 }
1502 return true;
1503}
1504
Jeff Brown19dfc832010-10-05 12:26:23 -07001505bool InputDispatcher::isWindowObscuredAtPointLocked(
1506 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07001507 size_t numWindows = mWindows.size();
1508 for (size_t i = 0; i < numWindows; i++) {
1509 const InputWindow* other = & mWindows.itemAt(i);
1510 if (other == window) {
1511 break;
1512 }
Jeff Brown19dfc832010-10-05 12:26:23 -07001513 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001514 return true;
1515 }
1516 }
1517 return false;
1518}
1519
Jeff Brown519e0242010-09-15 15:18:56 -07001520bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1521 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1522 if (connectionIndex >= 0) {
1523 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1524 return connection->outboundQueue.isEmpty();
1525 } else {
1526 return true;
1527 }
1528}
1529
1530String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1531 const InputWindow* window) {
1532 if (application) {
1533 if (window) {
1534 String8 label(application->name);
1535 label.append(" - ");
1536 label.append(window->name);
1537 return label;
1538 } else {
1539 return application->name;
1540 }
1541 } else if (window) {
1542 return window->name;
1543 } else {
1544 return String8("<unknown application or window>");
1545 }
1546}
1547
Jeff Browne2fe69e2010-10-18 13:21:23 -07001548void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1549 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brown4d396052010-10-29 21:50:21 -07001550 switch (eventEntry->type) {
1551 case EventEntry::TYPE_MOTION: {
Jeff Browne2fe69e2010-10-18 13:21:23 -07001552 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Brown4d396052010-10-29 21:50:21 -07001553 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1554 return;
1555 }
1556
Jeff Browne2fe69e2010-10-18 13:21:23 -07001557 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
Joe Onorato1a542c72010-11-08 09:48:20 -08001558 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001559 }
Jeff Brown4d396052010-10-29 21:50:21 -07001560 break;
1561 }
1562 case EventEntry::TYPE_KEY: {
1563 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1564 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1565 return;
1566 }
1567 break;
1568 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001569 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001570
Jeff Brownb88102f2010-09-08 11:49:43 -07001571 CommandEntry* commandEntry = postCommandLocked(
1572 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Browne2fe69e2010-10-18 13:21:23 -07001573 commandEntry->eventTime = eventEntry->eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001574 commandEntry->userActivityEventType = eventType;
1575}
1576
Jeff Brown7fbdc842010-06-17 20:52:56 -07001577void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1578 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001579 bool resumeWithAppendedMotionSample) {
1580#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001581 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001582 "xOffset=%f, yOffset=%f, "
Jeff Brown83c09682010-12-23 17:50:18 -08001583 "pointerIds=0x%x, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001584 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001585 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001586 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brown83c09682010-12-23 17:50:18 -08001587 inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001588 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001589#endif
1590
Jeff Brown01ce2e92010-09-26 22:20:12 -07001591 // Make sure we are never called for streaming when splitting across multiple windows.
1592 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1593 assert(! (resumeWithAppendedMotionSample && isSplit));
1594
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001595 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001596 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001597 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb6997262010-10-08 22:31:17 -07001598#if DEBUG_DISPATCH_CYCLE
1599 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001600 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brownb6997262010-10-08 22:31:17 -07001601#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001602 return;
1603 }
1604
Jeff Brown01ce2e92010-09-26 22:20:12 -07001605 // Split a motion event if needed.
1606 if (isSplit) {
1607 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1608
1609 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1610 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1611 MotionEntry* splitMotionEntry = splitMotionEvent(
1612 originalMotionEntry, inputTarget->pointerIds);
Jeff Brown58a2da82011-01-25 16:02:22 -08001613 if (!splitMotionEntry) {
1614 return; // split event was dropped
1615 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001616#if DEBUG_FOCUS
1617 LOGD("channel '%s' ~ Split motion event.",
1618 connection->getInputChannelName());
1619 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1620#endif
1621 eventEntry = splitMotionEntry;
1622 }
1623 }
1624
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001625 // Resume the dispatch cycle with a freshly appended motion sample.
1626 // First we check that the last dispatch entry in the outbound queue is for the same
1627 // motion event to which we appended the motion sample. If we find such a dispatch
1628 // entry, and if it is currently in progress then we try to stream the new sample.
1629 bool wasEmpty = connection->outboundQueue.isEmpty();
1630
1631 if (! wasEmpty && resumeWithAppendedMotionSample) {
1632 DispatchEntry* motionEventDispatchEntry =
1633 connection->findQueuedDispatchEntryForEvent(eventEntry);
1634 if (motionEventDispatchEntry) {
1635 // If the dispatch entry is not in progress, then we must be busy dispatching an
1636 // earlier event. Not a problem, the motion event is on the outbound queue and will
1637 // be dispatched later.
1638 if (! motionEventDispatchEntry->inProgress) {
1639#if DEBUG_BATCHING
1640 LOGD("channel '%s' ~ Not streaming because the motion event has "
1641 "not yet been dispatched. "
1642 "(Waiting for earlier events to be consumed.)",
1643 connection->getInputChannelName());
1644#endif
1645 return;
1646 }
1647
1648 // If the dispatch entry is in progress but it already has a tail of pending
1649 // motion samples, then it must mean that the shared memory buffer filled up.
1650 // Not a problem, when this dispatch cycle is finished, we will eventually start
1651 // a new dispatch cycle to process the tail and that tail includes the newly
1652 // appended motion sample.
1653 if (motionEventDispatchEntry->tailMotionSample) {
1654#if DEBUG_BATCHING
1655 LOGD("channel '%s' ~ Not streaming because no new samples can "
1656 "be appended to the motion event in this dispatch cycle. "
1657 "(Waiting for next dispatch cycle to start.)",
1658 connection->getInputChannelName());
1659#endif
1660 return;
1661 }
1662
1663 // The dispatch entry is in progress and is still potentially open for streaming.
1664 // Try to stream the new motion sample. This might fail if the consumer has already
1665 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001666 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1667 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001668 status_t status = connection->inputPublisher.appendMotionSample(
1669 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1670 if (status == OK) {
1671#if DEBUG_BATCHING
1672 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1673 connection->getInputChannelName());
1674#endif
1675 return;
1676 }
1677
1678#if DEBUG_BATCHING
1679 if (status == NO_MEMORY) {
1680 LOGD("channel '%s' ~ Could not append motion sample to currently "
1681 "dispatched move event because the shared memory buffer is full. "
1682 "(Waiting for next dispatch cycle to start.)",
1683 connection->getInputChannelName());
1684 } else if (status == status_t(FAILED_TRANSACTION)) {
1685 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001686 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001687 "(Waiting for next dispatch cycle to start.)",
1688 connection->getInputChannelName());
1689 } else {
1690 LOGD("channel '%s' ~ Could not append motion sample to currently "
1691 "dispatched move event due to an error, status=%d. "
1692 "(Waiting for next dispatch cycle to start.)",
1693 connection->getInputChannelName(), status);
1694 }
1695#endif
1696 // Failed to stream. Start a new tail of pending motion samples to dispatch
1697 // in the next cycle.
1698 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1699 return;
1700 }
1701 }
1702
1703 // This is a new event.
1704 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001705 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown519e0242010-09-15 15:18:56 -07001706 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1707 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001708 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001709 }
1710
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001711 // Handle the case where we could not stream a new motion sample because the consumer has
1712 // already consumed the motion event (otherwise the corresponding dispatch entry would
1713 // still be in the outbound queue for this connection). We set the head motion sample
1714 // to the list starting with the newly appended motion sample.
1715 if (resumeWithAppendedMotionSample) {
1716#if DEBUG_BATCHING
1717 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1718 "that cannot be streamed because the motion event has already been consumed.",
1719 connection->getInputChannelName());
1720#endif
1721 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1722 dispatchEntry->headMotionSample = appendedMotionSample;
1723 }
1724
1725 // Enqueue the dispatch entry.
1726 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1727
1728 // If the outbound queue was previously empty, start the dispatch cycle going.
1729 if (wasEmpty) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001730 activateConnectionLocked(connection.get());
Jeff Brown519e0242010-09-15 15:18:56 -07001731 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001732 }
1733}
1734
Jeff Brown7fbdc842010-06-17 20:52:56 -07001735void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001736 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001737#if DEBUG_DISPATCH_CYCLE
1738 LOGD("channel '%s' ~ startDispatchCycle",
1739 connection->getInputChannelName());
1740#endif
1741
1742 assert(connection->status == Connection::STATUS_NORMAL);
1743 assert(! connection->outboundQueue.isEmpty());
1744
Jeff Brownb88102f2010-09-08 11:49:43 -07001745 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001746 assert(! dispatchEntry->inProgress);
1747
Jeff Brownb88102f2010-09-08 11:49:43 -07001748 // Mark the dispatch entry as in progress.
1749 dispatchEntry->inProgress = true;
1750
1751 // Update the connection's input state.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001752 EventEntry* eventEntry = dispatchEntry->eventEntry;
1753 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001754
1755#if FILTER_INPUT_EVENTS
1756 // Filter out inconsistent sequences of input events.
1757 // The input system may drop or inject events in a way that could violate implicit
1758 // invariants on input state and potentially cause an application to crash
1759 // or think that a key or pointer is stuck down. Technically we make no guarantees
1760 // of consistency but it would be nice to improve on this where possible.
1761 // XXX: This code is a proof of concept only. Not ready for prime time.
1762 if (consistency == InputState::TOLERABLE) {
1763#if DEBUG_DISPATCH_CYCLE
1764 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1765 "current input state but that is likely to be tolerated by the application.",
1766 connection->getInputChannelName());
1767#endif
1768 } else if (consistency == InputState::BROKEN) {
1769 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1770 "current input state and that is likely to cause the application to crash.",
1771 connection->getInputChannelName());
1772 startNextDispatchCycleLocked(currentTime, connection);
1773 return;
1774 }
1775#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001776
1777 // Publish the event.
1778 status_t status;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001779 switch (eventEntry->type) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001780 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001781 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001782
1783 // Apply target flags.
1784 int32_t action = keyEntry->action;
1785 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001786
1787 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001788 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001789 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1790 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1791 keyEntry->eventTime);
1792
1793 if (status) {
1794 LOGE("channel '%s' ~ Could not publish key event, "
1795 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001796 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001797 return;
1798 }
1799 break;
1800 }
1801
1802 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001803 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001804
1805 // Apply target flags.
1806 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001807 int32_t flags = motionEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001808 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001809 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001810 }
Jeff Brown85a31762010-09-01 17:01:00 -07001811 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1812 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1813 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001814
1815 // If headMotionSample is non-NULL, then it points to the first new sample that we
1816 // were unable to dispatch during the previous cycle so we resume dispatching from
1817 // that point in the list of motion samples.
1818 // Otherwise, we just start from the first sample of the motion event.
1819 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1820 if (! firstMotionSample) {
1821 firstMotionSample = & motionEntry->firstSample;
1822 }
1823
Jeff Brownd3616592010-07-16 17:21:06 -07001824 // Set the X and Y offset depending on the input source.
1825 float xOffset, yOffset;
1826 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1827 xOffset = dispatchEntry->xOffset;
1828 yOffset = dispatchEntry->yOffset;
1829 } else {
1830 xOffset = 0.0f;
1831 yOffset = 0.0f;
1832 }
1833
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001834 // Publish the motion event and the first motion sample.
1835 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07001836 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownd3616592010-07-16 17:21:06 -07001837 xOffset, yOffset,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001838 motionEntry->xPrecision, motionEntry->yPrecision,
1839 motionEntry->downTime, firstMotionSample->eventTime,
1840 motionEntry->pointerCount, motionEntry->pointerIds,
1841 firstMotionSample->pointerCoords);
1842
1843 if (status) {
1844 LOGE("channel '%s' ~ Could not publish motion event, "
1845 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001846 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001847 return;
1848 }
1849
1850 // Append additional motion samples.
1851 MotionSample* nextMotionSample = firstMotionSample->next;
1852 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1853 status = connection->inputPublisher.appendMotionSample(
1854 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1855 if (status == NO_MEMORY) {
1856#if DEBUG_DISPATCH_CYCLE
1857 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1858 "be sent in the next dispatch cycle.",
1859 connection->getInputChannelName());
1860#endif
1861 break;
1862 }
1863 if (status != OK) {
1864 LOGE("channel '%s' ~ Could not append motion sample "
1865 "for a reason other than out of memory, status=%d",
1866 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001867 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001868 return;
1869 }
1870 }
1871
1872 // Remember the next motion sample that we could not dispatch, in case we ran out
1873 // of space in the shared memory buffer.
1874 dispatchEntry->tailMotionSample = nextMotionSample;
1875 break;
1876 }
1877
1878 default: {
1879 assert(false);
1880 }
1881 }
1882
1883 // Send the dispatch signal.
1884 status = connection->inputPublisher.sendDispatchSignal();
1885 if (status) {
1886 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1887 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001888 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001889 return;
1890 }
1891
1892 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001893 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001894 connection->lastDispatchTime = currentTime;
1895
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001896 // Notify other system components.
1897 onDispatchCycleStartedLocked(currentTime, connection);
1898}
1899
Jeff Brown7fbdc842010-06-17 20:52:56 -07001900void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown3915bb82010-11-05 15:02:16 -07001901 const sp<Connection>& connection, bool handled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001902#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001903 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown3915bb82010-11-05 15:02:16 -07001904 "%01.1fms since dispatch, handled=%s",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001905 connection->getInputChannelName(),
1906 connection->getEventLatencyMillis(currentTime),
Jeff Brown3915bb82010-11-05 15:02:16 -07001907 connection->getDispatchLatencyMillis(currentTime),
1908 toString(handled));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001909#endif
1910
Jeff Brown9c3cda02010-06-15 01:31:58 -07001911 if (connection->status == Connection::STATUS_BROKEN
1912 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001913 return;
1914 }
1915
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001916 // Reset the publisher since the event has been consumed.
1917 // We do this now so that the publisher can release some of its internal resources
1918 // while waiting for the next dispatch cycle to begin.
1919 status_t status = connection->inputPublisher.reset();
1920 if (status) {
1921 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1922 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001923 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001924 return;
1925 }
1926
Jeff Brown3915bb82010-11-05 15:02:16 -07001927 // Notify other system components and prepare to start the next dispatch cycle.
1928 onDispatchCycleFinishedLocked(currentTime, connection, handled);
Jeff Brownb88102f2010-09-08 11:49:43 -07001929}
1930
1931void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1932 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001933 // Start the next dispatch cycle for this connection.
1934 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001935 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001936 if (dispatchEntry->inProgress) {
1937 // Finish or resume current event in progress.
1938 if (dispatchEntry->tailMotionSample) {
1939 // We have a tail of undispatched motion samples.
1940 // Reuse the same DispatchEntry and start a new cycle.
1941 dispatchEntry->inProgress = false;
1942 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1943 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07001944 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001945 return;
1946 }
1947 // Finished.
1948 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07001949 if (dispatchEntry->hasForegroundTarget()) {
1950 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001951 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001952 mAllocator.releaseDispatchEntry(dispatchEntry);
1953 } else {
1954 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07001955 // progress event, which means we actually aborted it.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001956 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07001957 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001958 return;
1959 }
1960 }
1961
1962 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07001963 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001964}
1965
Jeff Brownb6997262010-10-08 22:31:17 -07001966void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1967 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001968#if DEBUG_DISPATCH_CYCLE
Jeff Brown83c09682010-12-23 17:50:18 -08001969 LOGD("channel '%s' ~ abortBrokenDispatchCycle",
1970 connection->getInputChannelName());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001971#endif
1972
Jeff Brownb88102f2010-09-08 11:49:43 -07001973 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07001974 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001975
Jeff Brownb6997262010-10-08 22:31:17 -07001976 // The connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07001977 // Ignore already broken or zombie connections.
Jeff Brownb6997262010-10-08 22:31:17 -07001978 if (connection->status == Connection::STATUS_NORMAL) {
1979 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001980
Jeff Brownb6997262010-10-08 22:31:17 -07001981 // Notify other system components.
1982 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001983 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001984}
1985
Jeff Brown519e0242010-09-15 15:18:56 -07001986void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1987 while (! connection->outboundQueue.isEmpty()) {
1988 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1989 if (dispatchEntry->hasForegroundTarget()) {
1990 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001991 }
1992 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001993 }
1994
Jeff Brown519e0242010-09-15 15:18:56 -07001995 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07001996}
1997
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001998int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001999 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2000
2001 { // acquire lock
2002 AutoMutex _l(d->mLock);
2003
2004 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
2005 if (connectionIndex < 0) {
2006 LOGE("Received spurious receive callback for unknown input channel. "
2007 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002008 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002009 }
2010
Jeff Brown7fbdc842010-06-17 20:52:56 -07002011 nsecs_t currentTime = now();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002012
2013 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002014 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002015 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
2016 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brownb6997262010-10-08 22:31:17 -07002017 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002018 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002019 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002020 }
2021
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002022 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002023 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
2024 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002025 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002026 }
2027
Jeff Brown3915bb82010-11-05 15:02:16 -07002028 bool handled = false;
Jeff Brown49ed71d2010-12-06 17:13:33 -08002029 status_t status = connection->inputPublisher.receiveFinishedSignal(&handled);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002030 if (status) {
2031 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
2032 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07002033 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002034 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002035 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002036 }
2037
Jeff Brown3915bb82010-11-05 15:02:16 -07002038 d->finishDispatchCycleLocked(currentTime, connection, handled);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002039 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002040 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002041 } // release lock
2042}
2043
Jeff Brownb6997262010-10-08 22:31:17 -07002044void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
2045 InputState::CancelationOptions options, const char* reason) {
2046 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
2047 synthesizeCancelationEventsForConnectionLocked(
2048 mConnectionsByReceiveFd.valueAt(i), options, reason);
2049 }
2050}
2051
2052void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2053 const sp<InputChannel>& channel, InputState::CancelationOptions options,
2054 const char* reason) {
2055 ssize_t index = getConnectionIndexLocked(channel);
2056 if (index >= 0) {
2057 synthesizeCancelationEventsForConnectionLocked(
2058 mConnectionsByReceiveFd.valueAt(index), options, reason);
2059 }
2060}
2061
2062void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2063 const sp<Connection>& connection, InputState::CancelationOptions options,
2064 const char* reason) {
2065 nsecs_t currentTime = now();
2066
2067 mTempCancelationEvents.clear();
2068 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
2069 mTempCancelationEvents, options);
2070
2071 if (! mTempCancelationEvents.isEmpty()
2072 && connection->status != Connection::STATUS_BROKEN) {
2073#if DEBUG_OUTBOUND_EVENT_DETAILS
2074 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
2075 "with reality: %s, options=%d.",
2076 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
2077#endif
2078 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
2079 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
2080 switch (cancelationEventEntry->type) {
2081 case EventEntry::TYPE_KEY:
2082 logOutboundKeyDetailsLocked("cancel - ",
2083 static_cast<KeyEntry*>(cancelationEventEntry));
2084 break;
2085 case EventEntry::TYPE_MOTION:
2086 logOutboundMotionDetailsLocked("cancel - ",
2087 static_cast<MotionEntry*>(cancelationEventEntry));
2088 break;
2089 }
2090
2091 int32_t xOffset, yOffset;
2092 const InputWindow* window = getWindowLocked(connection->inputChannel);
2093 if (window) {
2094 xOffset = -window->frameLeft;
2095 yOffset = -window->frameTop;
2096 } else {
2097 xOffset = 0;
2098 yOffset = 0;
2099 }
2100
2101 DispatchEntry* cancelationDispatchEntry =
2102 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
2103 0, xOffset, yOffset);
2104 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
2105
2106 mAllocator.releaseEventEntry(cancelationEventEntry);
2107 }
2108
2109 if (!connection->outboundQueue.headSentinel.next->inProgress) {
2110 startDispatchCycleLocked(currentTime, connection);
2111 }
2112 }
2113}
2114
Jeff Brown01ce2e92010-09-26 22:20:12 -07002115InputDispatcher::MotionEntry*
2116InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2117 assert(pointerIds.value != 0);
2118
2119 uint32_t splitPointerIndexMap[MAX_POINTERS];
2120 int32_t splitPointerIds[MAX_POINTERS];
2121 PointerCoords splitPointerCoords[MAX_POINTERS];
2122
2123 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2124 uint32_t splitPointerCount = 0;
2125
2126 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2127 originalPointerIndex++) {
2128 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
2129 if (pointerIds.hasBit(pointerId)) {
2130 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2131 splitPointerIds[splitPointerCount] = pointerId;
2132 splitPointerCoords[splitPointerCount] =
2133 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
2134 splitPointerCount += 1;
2135 }
2136 }
Jeff Brown58a2da82011-01-25 16:02:22 -08002137
2138 if (splitPointerCount != pointerIds.count()) {
2139 // This is bad. We are missing some of the pointers that we expected to deliver.
2140 // Most likely this indicates that we received an ACTION_MOVE events that has
2141 // different pointer ids than we expected based on the previous ACTION_DOWN
2142 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2143 // in this way.
2144 LOGW("Dropping split motion event because the pointer count is %d but "
2145 "we expected there to be %d pointers. This probably means we received "
2146 "a broken sequence of pointer ids from the input device.",
2147 splitPointerCount, pointerIds.count());
2148 return NULL;
2149 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002150
2151 int32_t action = originalMotionEntry->action;
2152 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2153 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2154 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2155 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2156 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2157 if (pointerIds.hasBit(pointerId)) {
2158 if (pointerIds.count() == 1) {
2159 // The first/last pointer went down/up.
2160 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2161 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07002162 } else {
2163 // A secondary pointer went down/up.
2164 uint32_t splitPointerIndex = 0;
2165 while (pointerId != splitPointerIds[splitPointerIndex]) {
2166 splitPointerIndex += 1;
2167 }
2168 action = maskedAction | (splitPointerIndex
2169 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002170 }
2171 } else {
2172 // An unrelated pointer changed.
2173 action = AMOTION_EVENT_ACTION_MOVE;
2174 }
2175 }
2176
2177 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2178 originalMotionEntry->eventTime,
2179 originalMotionEntry->deviceId,
2180 originalMotionEntry->source,
2181 originalMotionEntry->policyFlags,
2182 action,
2183 originalMotionEntry->flags,
2184 originalMotionEntry->metaState,
2185 originalMotionEntry->edgeFlags,
2186 originalMotionEntry->xPrecision,
2187 originalMotionEntry->yPrecision,
2188 originalMotionEntry->downTime,
2189 splitPointerCount, splitPointerIds, splitPointerCoords);
2190
2191 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2192 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2193 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2194 splitPointerIndex++) {
2195 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2196 splitPointerCoords[splitPointerIndex] =
2197 originalMotionSample->pointerCoords[originalPointerIndex];
2198 }
2199
2200 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2201 splitPointerCoords);
2202 }
2203
2204 return splitMotionEntry;
2205}
2206
Jeff Brown9c3cda02010-06-15 01:31:58 -07002207void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002208#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07002209 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002210#endif
2211
Jeff Brownb88102f2010-09-08 11:49:43 -07002212 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002213 { // acquire lock
2214 AutoMutex _l(mLock);
2215
Jeff Brown7fbdc842010-06-17 20:52:56 -07002216 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07002217 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002218 } // release lock
2219
Jeff Brownb88102f2010-09-08 11:49:43 -07002220 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002221 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002222 }
2223}
2224
Jeff Brown58a2da82011-01-25 16:02:22 -08002225void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002226 uint32_t policyFlags, int32_t action, int32_t flags,
2227 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2228#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002229 LOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002230 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07002231 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002232 keyCode, scanCode, metaState, downTime);
2233#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002234 if (! validateKeyEvent(action)) {
2235 return;
2236 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002237
Jeff Brown1f245102010-11-18 20:53:46 -08002238 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2239 policyFlags |= POLICY_FLAG_VIRTUAL;
2240 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2241 }
2242
Jeff Browne20c9e02010-10-11 14:20:19 -07002243 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown1f245102010-11-18 20:53:46 -08002244
2245 KeyEvent event;
2246 event.initialize(deviceId, source, action, flags, keyCode, scanCode,
2247 metaState, 0, downTime, eventTime);
2248
2249 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
2250
2251 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2252 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2253 }
Jeff Brownb6997262010-10-08 22:31:17 -07002254
Jeff Brownb88102f2010-09-08 11:49:43 -07002255 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002256 { // acquire lock
2257 AutoMutex _l(mLock);
2258
Jeff Brown7fbdc842010-06-17 20:52:56 -07002259 int32_t repeatCount = 0;
2260 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002261 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002262 metaState, repeatCount, downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002263
Jeff Brownb88102f2010-09-08 11:49:43 -07002264 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002265 } // release lock
2266
Jeff Brownb88102f2010-09-08 11:49:43 -07002267 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002268 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002269 }
2270}
2271
Jeff Brown58a2da82011-01-25 16:02:22 -08002272void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002273 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002274 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2275 float xPrecision, float yPrecision, nsecs_t downTime) {
2276#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002277 LOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002278 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2279 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2280 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002281 xPrecision, yPrecision, downTime);
2282 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002283 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002284 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002285 "orientation=%f",
Jeff Brown91c69ab2011-02-14 17:03:18 -08002286 i, pointerIds[i],
Jeff Brownebbd5d12011-02-17 13:01:34 -08002287 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2288 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2289 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2290 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2291 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2292 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2293 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2294 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2295 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002296 }
2297#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002298 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2299 return;
2300 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002301
Jeff Browne20c9e02010-10-11 14:20:19 -07002302 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002303 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2304
Jeff Brownb88102f2010-09-08 11:49:43 -07002305 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002306 { // acquire lock
2307 AutoMutex _l(mLock);
2308
2309 // Attempt batching and streaming of move events.
Jeff Brownc5ed5912010-07-14 18:48:53 -07002310 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002311 // BATCHING CASE
2312 //
2313 // Try to append a move sample to the tail of the inbound queue for this device.
2314 // Give up if we encounter a non-move motion event for this device since that
2315 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002316 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2317 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002318 if (entry->type != EventEntry::TYPE_MOTION) {
2319 // Keep looking for motion events.
2320 continue;
2321 }
2322
2323 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2324 if (motionEntry->deviceId != deviceId) {
2325 // Keep looking for this device.
2326 continue;
2327 }
2328
Jeff Brownc5ed5912010-07-14 18:48:53 -07002329 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown58a2da82011-01-25 16:02:22 -08002330 || motionEntry->source != source
Jeff Brown7fbdc842010-06-17 20:52:56 -07002331 || motionEntry->pointerCount != pointerCount
2332 || motionEntry->isInjected()) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002333 // Last motion event in the queue for this device is not compatible for
2334 // appending new samples. Stop here.
2335 goto NoBatchingOrStreaming;
2336 }
2337
2338 // The last motion event is a move and is compatible for appending.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002339 // Do the batching magic.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002340 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002341#if DEBUG_BATCHING
2342 LOGD("Appended motion sample onto batch for most recent "
2343 "motion event for this device in the inbound queue.");
2344#endif
Jeff Brown9c3cda02010-06-15 01:31:58 -07002345 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002346 }
2347
2348 // STREAMING CASE
2349 //
2350 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002351 // Search the outbound queue for the current foreground targets to find a dispatched
2352 // motion event that is still in progress. If found, then, appen the new sample to
2353 // that event and push it out to all current targets. The logic in
2354 // prepareDispatchCycleLocked takes care of the case where some targets may
2355 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002356 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002357 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2358 const InputTarget& inputTarget = mCurrentInputTargets[i];
2359 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2360 // Skip non-foreground targets. We only want to stream if there is at
2361 // least one foreground target whose dispatch is still in progress.
2362 continue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002363 }
Jeff Brown519e0242010-09-15 15:18:56 -07002364
2365 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2366 if (connectionIndex < 0) {
2367 // Connection must no longer be valid.
2368 continue;
2369 }
2370
2371 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2372 if (connection->outboundQueue.isEmpty()) {
2373 // This foreground target has an empty outbound queue.
2374 continue;
2375 }
2376
2377 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2378 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002379 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2380 || dispatchEntry->isSplit()) {
2381 // No motion event is being dispatched, or it is being split across
2382 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002383 continue;
2384 }
2385
2386 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2387 dispatchEntry->eventEntry);
2388 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2389 || motionEntry->deviceId != deviceId
Jeff Brown58a2da82011-01-25 16:02:22 -08002390 || motionEntry->source != source
Jeff Brown519e0242010-09-15 15:18:56 -07002391 || motionEntry->pointerCount != pointerCount
2392 || motionEntry->isInjected()) {
2393 // The motion event is not compatible with this move.
2394 continue;
2395 }
2396
2397 // Hurray! This foreground target is currently dispatching a move event
2398 // that we can stream onto. Append the motion sample and resume dispatch.
2399 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2400#if DEBUG_BATCHING
2401 LOGD("Appended motion sample onto batch for most recently dispatched "
2402 "motion event for this device in the outbound queues. "
2403 "Attempting to stream the motion sample.");
2404#endif
2405 nsecs_t currentTime = now();
2406 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2407 true /*resumeWithAppendedMotionSample*/);
2408
2409 runCommandsLockedInterruptible();
2410 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002411 }
2412 }
2413
2414NoBatchingOrStreaming:;
2415 }
2416
2417 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002418 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002419 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002420 xPrecision, yPrecision, downTime,
2421 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002422
Jeff Brownb88102f2010-09-08 11:49:43 -07002423 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002424 } // release lock
2425
Jeff Brownb88102f2010-09-08 11:49:43 -07002426 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002427 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002428 }
2429}
2430
Jeff Brownb6997262010-10-08 22:31:17 -07002431void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2432 uint32_t policyFlags) {
2433#if DEBUG_INBOUND_EVENT_DETAILS
2434 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2435 switchCode, switchValue, policyFlags);
2436#endif
2437
Jeff Browne20c9e02010-10-11 14:20:19 -07002438 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002439 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2440}
2441
Jeff Brown7fbdc842010-06-17 20:52:56 -07002442int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002443 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002444#if DEBUG_INBOUND_EVENT_DETAILS
2445 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002446 "syncMode=%d, timeoutMillis=%d",
2447 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002448#endif
2449
2450 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Browne20c9e02010-10-11 14:20:19 -07002451
2452 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2453 if (hasInjectionPermission(injectorPid, injectorUid)) {
2454 policyFlags |= POLICY_FLAG_TRUSTED;
2455 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002456
Jeff Brownb6997262010-10-08 22:31:17 -07002457 EventEntry* injectedEntry;
2458 switch (event->getType()) {
2459 case AINPUT_EVENT_TYPE_KEY: {
2460 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2461 int32_t action = keyEvent->getAction();
2462 if (! validateKeyEvent(action)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002463 return INPUT_EVENT_INJECTION_FAILED;
2464 }
2465
Jeff Brownb6997262010-10-08 22:31:17 -07002466 int32_t flags = keyEvent->getFlags();
Jeff Brown1f245102010-11-18 20:53:46 -08002467 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2468 policyFlags |= POLICY_FLAG_VIRTUAL;
2469 }
2470
2471 mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
2472
2473 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2474 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2475 }
Jeff Brown6ec402b2010-07-28 15:48:59 -07002476
Jeff Brownb6997262010-10-08 22:31:17 -07002477 mLock.lock();
Jeff Brown1f245102010-11-18 20:53:46 -08002478 injectedEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
2479 keyEvent->getDeviceId(), keyEvent->getSource(),
2480 policyFlags, action, flags,
2481 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
Jeff Brownb6997262010-10-08 22:31:17 -07002482 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2483 break;
2484 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002485
Jeff Brownb6997262010-10-08 22:31:17 -07002486 case AINPUT_EVENT_TYPE_MOTION: {
2487 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2488 int32_t action = motionEvent->getAction();
2489 size_t pointerCount = motionEvent->getPointerCount();
2490 const int32_t* pointerIds = motionEvent->getPointerIds();
2491 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2492 return INPUT_EVENT_INJECTION_FAILED;
2493 }
2494
2495 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Browne20c9e02010-10-11 14:20:19 -07002496 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002497
2498 mLock.lock();
2499 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2500 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2501 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2502 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2503 action, motionEvent->getFlags(),
2504 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2505 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2506 motionEvent->getDownTime(), uint32_t(pointerCount),
2507 pointerIds, samplePointerCoords);
2508 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2509 sampleEventTimes += 1;
2510 samplePointerCoords += pointerCount;
2511 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2512 }
2513 injectedEntry = motionEntry;
2514 break;
2515 }
2516
2517 default:
2518 LOGW("Cannot inject event of type %d", event->getType());
2519 return INPUT_EVENT_INJECTION_FAILED;
2520 }
2521
2522 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2523 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2524 injectionState->injectionIsAsync = true;
2525 }
2526
2527 injectionState->refCount += 1;
2528 injectedEntry->injectionState = injectionState;
2529
2530 bool needWake = enqueueInboundEventLocked(injectedEntry);
2531 mLock.unlock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002532
Jeff Brownb88102f2010-09-08 11:49:43 -07002533 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002534 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002535 }
2536
2537 int32_t injectionResult;
2538 { // acquire lock
2539 AutoMutex _l(mLock);
2540
Jeff Brown6ec402b2010-07-28 15:48:59 -07002541 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2542 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2543 } else {
2544 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002545 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002546 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2547 break;
2548 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002549
Jeff Brown7fbdc842010-06-17 20:52:56 -07002550 nsecs_t remainingTimeout = endTime - now();
2551 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002552#if DEBUG_INJECTION
2553 LOGD("injectInputEvent - Timed out waiting for injection result "
2554 "to become available.");
2555#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002556 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2557 break;
2558 }
2559
Jeff Brown6ec402b2010-07-28 15:48:59 -07002560 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2561 }
2562
2563 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2564 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002565 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002566#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002567 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002568 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002569#endif
2570 nsecs_t remainingTimeout = endTime - now();
2571 if (remainingTimeout <= 0) {
2572#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002573 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002574 "dispatches to finish.");
2575#endif
2576 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2577 break;
2578 }
2579
2580 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2581 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002582 }
2583 }
2584
Jeff Brown01ce2e92010-09-26 22:20:12 -07002585 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002586 } // release lock
2587
Jeff Brown6ec402b2010-07-28 15:48:59 -07002588#if DEBUG_INJECTION
2589 LOGD("injectInputEvent - Finished with result %d. "
2590 "injectorPid=%d, injectorUid=%d",
2591 injectionResult, injectorPid, injectorUid);
2592#endif
2593
Jeff Brown7fbdc842010-06-17 20:52:56 -07002594 return injectionResult;
2595}
2596
Jeff Brownb6997262010-10-08 22:31:17 -07002597bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2598 return injectorUid == 0
2599 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2600}
2601
Jeff Brown7fbdc842010-06-17 20:52:56 -07002602void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002603 InjectionState* injectionState = entry->injectionState;
2604 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002605#if DEBUG_INJECTION
2606 LOGD("Setting input event injection result to %d. "
2607 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002608 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002609#endif
2610
Jeff Brown01ce2e92010-09-26 22:20:12 -07002611 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002612 // Log the outcome since the injector did not wait for the injection result.
2613 switch (injectionResult) {
2614 case INPUT_EVENT_INJECTION_SUCCEEDED:
2615 LOGV("Asynchronous input event injection succeeded.");
2616 break;
2617 case INPUT_EVENT_INJECTION_FAILED:
2618 LOGW("Asynchronous input event injection failed.");
2619 break;
2620 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2621 LOGW("Asynchronous input event injection permission denied.");
2622 break;
2623 case INPUT_EVENT_INJECTION_TIMED_OUT:
2624 LOGW("Asynchronous input event injection timed out.");
2625 break;
2626 }
2627 }
2628
Jeff Brown01ce2e92010-09-26 22:20:12 -07002629 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002630 mInjectionResultAvailableCondition.broadcast();
2631 }
2632}
2633
Jeff Brown01ce2e92010-09-26 22:20:12 -07002634void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2635 InjectionState* injectionState = entry->injectionState;
2636 if (injectionState) {
2637 injectionState->pendingForegroundDispatches += 1;
2638 }
2639}
2640
Jeff Brown519e0242010-09-15 15:18:56 -07002641void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002642 InjectionState* injectionState = entry->injectionState;
2643 if (injectionState) {
2644 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002645
Jeff Brown01ce2e92010-09-26 22:20:12 -07002646 if (injectionState->pendingForegroundDispatches == 0) {
2647 mInjectionSyncFinishedCondition.broadcast();
2648 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002649 }
2650}
2651
Jeff Brown01ce2e92010-09-26 22:20:12 -07002652const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2653 for (size_t i = 0; i < mWindows.size(); i++) {
2654 const InputWindow* window = & mWindows[i];
2655 if (window->inputChannel == inputChannel) {
2656 return window;
2657 }
2658 }
2659 return NULL;
2660}
2661
Jeff Brownb88102f2010-09-08 11:49:43 -07002662void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2663#if DEBUG_FOCUS
2664 LOGD("setInputWindows");
2665#endif
2666 { // acquire lock
2667 AutoMutex _l(mLock);
2668
Jeff Brown01ce2e92010-09-26 22:20:12 -07002669 // Clear old window pointers.
Jeff Brownb6997262010-10-08 22:31:17 -07002670 sp<InputChannel> oldFocusedWindowChannel;
2671 if (mFocusedWindow) {
2672 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2673 mFocusedWindow = NULL;
2674 }
2675
Jeff Brownb88102f2010-09-08 11:49:43 -07002676 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002677
2678 // Loop over new windows and rebuild the necessary window pointers for
2679 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002680 mWindows.appendVector(inputWindows);
2681
2682 size_t numWindows = mWindows.size();
2683 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002684 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002685 if (window->hasFocus) {
2686 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002687 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002688 }
2689 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002690
Jeff Brownb6997262010-10-08 22:31:17 -07002691 if (oldFocusedWindowChannel != NULL) {
2692 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2693#if DEBUG_FOCUS
2694 LOGD("Focus left window: %s",
2695 oldFocusedWindowChannel->getName().string());
2696#endif
2697 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2698 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2699 oldFocusedWindowChannel.clear();
2700 }
2701 }
2702 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2703#if DEBUG_FOCUS
2704 LOGD("Focus entered window: %s",
2705 mFocusedWindow->inputChannel->getName().string());
2706#endif
2707 }
2708
Jeff Brown01ce2e92010-09-26 22:20:12 -07002709 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2710 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2711 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2712 if (window) {
2713 touchedWindow.window = window;
2714 i += 1;
2715 } else {
Jeff Brownb6997262010-10-08 22:31:17 -07002716#if DEBUG_FOCUS
2717 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2718#endif
Jeff Brownb6997262010-10-08 22:31:17 -07002719 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2720 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownaf48cae2010-10-15 16:20:51 -07002721 mTouchState.windows.removeAt(i);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002722 }
2723 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002724
Jeff Brownb88102f2010-09-08 11:49:43 -07002725#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002726 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002727#endif
2728 } // release lock
2729
2730 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002731 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002732}
2733
2734void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2735#if DEBUG_FOCUS
2736 LOGD("setFocusedApplication");
2737#endif
2738 { // acquire lock
2739 AutoMutex _l(mLock);
2740
2741 releaseFocusedApplicationLocked();
2742
2743 if (inputApplication) {
2744 mFocusedApplicationStorage = *inputApplication;
2745 mFocusedApplication = & mFocusedApplicationStorage;
2746 }
2747
2748#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002749 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002750#endif
2751 } // release lock
2752
2753 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002754 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002755}
2756
2757void InputDispatcher::releaseFocusedApplicationLocked() {
2758 if (mFocusedApplication) {
2759 mFocusedApplication = NULL;
Jeff Brown928e0542011-01-10 11:17:36 -08002760 mFocusedApplicationStorage.inputApplicationHandle.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -07002761 }
2762}
2763
2764void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2765#if DEBUG_FOCUS
2766 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2767#endif
2768
2769 bool changed;
2770 { // acquire lock
2771 AutoMutex _l(mLock);
2772
2773 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brown120a4592010-10-27 18:43:51 -07002774 if (mDispatchFrozen && !frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002775 resetANRTimeoutsLocked();
2776 }
2777
Jeff Brown120a4592010-10-27 18:43:51 -07002778 if (mDispatchEnabled && !enabled) {
2779 resetAndDropEverythingLocked("dispatcher is being disabled");
2780 }
2781
Jeff Brownb88102f2010-09-08 11:49:43 -07002782 mDispatchEnabled = enabled;
2783 mDispatchFrozen = frozen;
2784 changed = true;
2785 } else {
2786 changed = false;
2787 }
2788
2789#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002790 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002791#endif
2792 } // release lock
2793
2794 if (changed) {
2795 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002796 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002797 }
2798}
2799
Jeff Browne6504122010-09-27 14:52:15 -07002800bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2801 const sp<InputChannel>& toChannel) {
2802#if DEBUG_FOCUS
2803 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2804 fromChannel->getName().string(), toChannel->getName().string());
2805#endif
2806 { // acquire lock
2807 AutoMutex _l(mLock);
2808
2809 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2810 const InputWindow* toWindow = getWindowLocked(toChannel);
2811 if (! fromWindow || ! toWindow) {
2812#if DEBUG_FOCUS
2813 LOGD("Cannot transfer focus because from or to window not found.");
2814#endif
2815 return false;
2816 }
2817 if (fromWindow == toWindow) {
2818#if DEBUG_FOCUS
2819 LOGD("Trivial transfer to same window.");
2820#endif
2821 return true;
2822 }
2823
2824 bool found = false;
2825 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2826 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2827 if (touchedWindow.window == fromWindow) {
2828 int32_t oldTargetFlags = touchedWindow.targetFlags;
2829 BitSet32 pointerIds = touchedWindow.pointerIds;
2830
2831 mTouchState.windows.removeAt(i);
2832
Jeff Brown46e75292010-11-10 16:53:45 -08002833 int32_t newTargetFlags = oldTargetFlags
2834 & (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT);
Jeff Browne6504122010-09-27 14:52:15 -07002835 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2836
2837 found = true;
2838 break;
2839 }
2840 }
2841
2842 if (! found) {
2843#if DEBUG_FOCUS
2844 LOGD("Focus transfer failed because from window did not have focus.");
2845#endif
2846 return false;
2847 }
2848
Jeff Brown9c9f1a32010-10-11 18:32:20 -07002849 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2850 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2851 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2852 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2853 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2854
2855 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2856 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2857 InputState::CANCEL_POINTER_EVENTS,
2858 "transferring touch focus from this window to another window");
2859 }
2860
Jeff Browne6504122010-09-27 14:52:15 -07002861#if DEBUG_FOCUS
2862 logDispatchStateLocked();
2863#endif
2864 } // release lock
2865
2866 // Wake up poll loop since it may need to make new input dispatching choices.
2867 mLooper->wake();
2868 return true;
2869}
2870
Jeff Brown120a4592010-10-27 18:43:51 -07002871void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2872#if DEBUG_FOCUS
2873 LOGD("Resetting and dropping all events (%s).", reason);
2874#endif
2875
2876 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2877
2878 resetKeyRepeatLocked();
2879 releasePendingEventLocked();
2880 drainInboundQueueLocked();
2881 resetTargetsLocked();
2882
2883 mTouchState.reset();
2884}
2885
Jeff Brownb88102f2010-09-08 11:49:43 -07002886void InputDispatcher::logDispatchStateLocked() {
2887 String8 dump;
2888 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002889
2890 char* text = dump.lockBuffer(dump.size());
2891 char* start = text;
2892 while (*start != '\0') {
2893 char* end = strchr(start, '\n');
2894 if (*end == '\n') {
2895 *(end++) = '\0';
2896 }
2897 LOGD("%s", start);
2898 start = end;
2899 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002900}
2901
2902void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002903 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2904 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07002905
2906 if (mFocusedApplication) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002907 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002908 mFocusedApplication->name.string(),
2909 mFocusedApplication->dispatchingTimeout / 1000000.0);
2910 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002911 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002912 }
Jeff Brownf2f487182010-10-01 17:46:21 -07002913 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002914 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f487182010-10-01 17:46:21 -07002915
2916 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2917 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
Jeff Brown95712852011-01-04 19:41:59 -08002918 dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
Jeff Brown58a2da82011-01-25 16:02:22 -08002919 dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
Jeff Brownf2f487182010-10-01 17:46:21 -07002920 if (!mTouchState.windows.isEmpty()) {
2921 dump.append(INDENT "TouchedWindows:\n");
2922 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2923 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2924 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2925 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2926 touchedWindow.targetFlags);
2927 }
2928 } else {
2929 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002930 }
2931
Jeff Brownf2f487182010-10-01 17:46:21 -07002932 if (!mWindows.isEmpty()) {
2933 dump.append(INDENT "Windows:\n");
2934 for (size_t i = 0; i < mWindows.size(); i++) {
2935 const InputWindow& window = mWindows[i];
2936 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2937 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2938 "frame=[%d,%d][%d,%d], "
Jeff Brownfbf09772011-01-16 14:06:57 -08002939 "touchableRegion=",
Jeff Brownf2f487182010-10-01 17:46:21 -07002940 i, window.name.string(),
2941 toString(window.paused),
2942 toString(window.hasFocus),
2943 toString(window.hasWallpaper),
2944 toString(window.visible),
2945 toString(window.canReceiveKeys),
2946 window.layoutParamsFlags, window.layoutParamsType,
2947 window.layer,
2948 window.frameLeft, window.frameTop,
Jeff Brownfbf09772011-01-16 14:06:57 -08002949 window.frameRight, window.frameBottom);
2950 dumpRegion(dump, window.touchableRegion);
2951 dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07002952 window.ownerPid, window.ownerUid,
2953 window.dispatchingTimeout / 1000000.0);
2954 }
2955 } else {
2956 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002957 }
2958
Jeff Brownf2f487182010-10-01 17:46:21 -07002959 if (!mMonitoringChannels.isEmpty()) {
2960 dump.append(INDENT "MonitoringChannels:\n");
2961 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2962 const sp<InputChannel>& channel = mMonitoringChannels[i];
2963 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2964 }
2965 } else {
2966 dump.append(INDENT "MonitoringChannels: <none>\n");
2967 }
Jeff Brown519e0242010-09-15 15:18:56 -07002968
Jeff Brownf2f487182010-10-01 17:46:21 -07002969 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2970
2971 if (!mActiveConnections.isEmpty()) {
2972 dump.append(INDENT "ActiveConnections:\n");
2973 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2974 const Connection* connection = mActiveConnections[i];
Jeff Brown76860e32010-10-25 17:37:46 -07002975 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brownb6997262010-10-08 22:31:17 -07002976 "inputState.isNeutral=%s\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07002977 i, connection->getInputChannelName(), connection->getStatusLabel(),
2978 connection->outboundQueue.count(),
Jeff Brownb6997262010-10-08 22:31:17 -07002979 toString(connection->inputState.isNeutral()));
Jeff Brownf2f487182010-10-01 17:46:21 -07002980 }
2981 } else {
2982 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002983 }
2984
2985 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002986 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002987 (mAppSwitchDueTime - now()) / 1000000.0);
2988 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002989 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002990 }
2991}
2992
Jeff Brown928e0542011-01-10 11:17:36 -08002993status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
2994 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002995#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07002996 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2997 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07002998#endif
2999
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003000 { // acquire lock
3001 AutoMutex _l(mLock);
3002
Jeff Brown519e0242010-09-15 15:18:56 -07003003 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003004 LOGW("Attempted to register already registered input channel '%s'",
3005 inputChannel->getName().string());
3006 return BAD_VALUE;
3007 }
3008
Jeff Brown928e0542011-01-10 11:17:36 -08003009 sp<Connection> connection = new Connection(inputChannel, inputWindowHandle);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003010 status_t status = connection->initialize();
3011 if (status) {
3012 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
3013 inputChannel->getName().string(), status);
3014 return status;
3015 }
3016
Jeff Brown2cbecea2010-08-17 15:59:26 -07003017 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003018 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003019
Jeff Brownb88102f2010-09-08 11:49:43 -07003020 if (monitor) {
3021 mMonitoringChannels.push(inputChannel);
3022 }
3023
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003024 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07003025
Jeff Brown9c3cda02010-06-15 01:31:58 -07003026 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003027 } // release lock
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003028 return OK;
3029}
3030
3031status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003032#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07003033 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07003034#endif
3035
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003036 { // acquire lock
3037 AutoMutex _l(mLock);
3038
Jeff Brown519e0242010-09-15 15:18:56 -07003039 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003040 if (connectionIndex < 0) {
3041 LOGW("Attempted to unregister already unregistered input channel '%s'",
3042 inputChannel->getName().string());
3043 return BAD_VALUE;
3044 }
3045
3046 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3047 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
3048
3049 connection->status = Connection::STATUS_ZOMBIE;
3050
Jeff Brownb88102f2010-09-08 11:49:43 -07003051 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3052 if (mMonitoringChannels[i] == inputChannel) {
3053 mMonitoringChannels.removeAt(i);
3054 break;
3055 }
3056 }
3057
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003058 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07003059
Jeff Brown7fbdc842010-06-17 20:52:56 -07003060 nsecs_t currentTime = now();
Jeff Brownb6997262010-10-08 22:31:17 -07003061 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003062
3063 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003064 } // release lock
3065
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003066 // Wake the poll loop because removing the connection may have changed the current
3067 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003068 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003069 return OK;
3070}
3071
Jeff Brown519e0242010-09-15 15:18:56 -07003072ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07003073 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
3074 if (connectionIndex >= 0) {
3075 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3076 if (connection->inputChannel.get() == inputChannel.get()) {
3077 return connectionIndex;
3078 }
3079 }
3080
3081 return -1;
3082}
3083
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003084void InputDispatcher::activateConnectionLocked(Connection* connection) {
3085 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3086 if (mActiveConnections.itemAt(i) == connection) {
3087 return;
3088 }
3089 }
3090 mActiveConnections.add(connection);
3091}
3092
3093void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
3094 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3095 if (mActiveConnections.itemAt(i) == connection) {
3096 mActiveConnections.removeAt(i);
3097 return;
3098 }
3099 }
3100}
3101
Jeff Brown9c3cda02010-06-15 01:31:58 -07003102void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003103 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003104}
3105
Jeff Brown9c3cda02010-06-15 01:31:58 -07003106void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown3915bb82010-11-05 15:02:16 -07003107 nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
3108 CommandEntry* commandEntry = postCommandLocked(
3109 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
3110 commandEntry->connection = connection;
3111 commandEntry->handled = handled;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003112}
3113
Jeff Brown9c3cda02010-06-15 01:31:58 -07003114void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003115 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003116 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3117 connection->getInputChannelName());
3118
Jeff Brown9c3cda02010-06-15 01:31:58 -07003119 CommandEntry* commandEntry = postCommandLocked(
3120 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003121 commandEntry->connection = connection;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003122}
3123
Jeff Brown519e0242010-09-15 15:18:56 -07003124void InputDispatcher::onANRLocked(
3125 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
3126 nsecs_t eventTime, nsecs_t waitStartTime) {
3127 LOGI("Application is not responding: %s. "
3128 "%01.1fms since event, %01.1fms since wait started",
3129 getApplicationWindowLabelLocked(application, window).string(),
3130 (currentTime - eventTime) / 1000000.0,
3131 (currentTime - waitStartTime) / 1000000.0);
3132
3133 CommandEntry* commandEntry = postCommandLocked(
3134 & InputDispatcher::doNotifyANRLockedInterruptible);
3135 if (application) {
Jeff Brown928e0542011-01-10 11:17:36 -08003136 commandEntry->inputApplicationHandle = application->inputApplicationHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003137 }
3138 if (window) {
Jeff Brown928e0542011-01-10 11:17:36 -08003139 commandEntry->inputWindowHandle = window->inputWindowHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003140 commandEntry->inputChannel = window->inputChannel;
3141 }
3142}
3143
Jeff Brownb88102f2010-09-08 11:49:43 -07003144void InputDispatcher::doNotifyConfigurationChangedInterruptible(
3145 CommandEntry* commandEntry) {
3146 mLock.unlock();
3147
3148 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
3149
3150 mLock.lock();
3151}
3152
Jeff Brown9c3cda02010-06-15 01:31:58 -07003153void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
3154 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003155 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07003156
Jeff Brown7fbdc842010-06-17 20:52:56 -07003157 if (connection->status != Connection::STATUS_ZOMBIE) {
3158 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003159
Jeff Brown928e0542011-01-10 11:17:36 -08003160 mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003161
3162 mLock.lock();
3163 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07003164}
3165
Jeff Brown519e0242010-09-15 15:18:56 -07003166void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07003167 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07003168 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003169
Jeff Brown519e0242010-09-15 15:18:56 -07003170 nsecs_t newTimeout = mPolicy->notifyANR(
Jeff Brown928e0542011-01-10 11:17:36 -08003171 commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003172
Jeff Brown519e0242010-09-15 15:18:56 -07003173 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07003174
Jeff Brown519e0242010-09-15 15:18:56 -07003175 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003176}
3177
Jeff Brownb88102f2010-09-08 11:49:43 -07003178void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3179 CommandEntry* commandEntry) {
3180 KeyEntry* entry = commandEntry->keyEntry;
Jeff Brown1f245102010-11-18 20:53:46 -08003181
3182 KeyEvent event;
3183 initializeKeyEvent(&event, entry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003184
3185 mLock.unlock();
3186
Jeff Brown928e0542011-01-10 11:17:36 -08003187 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
Jeff Brown1f245102010-11-18 20:53:46 -08003188 &event, entry->policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -07003189
3190 mLock.lock();
3191
3192 entry->interceptKeyResult = consumed
3193 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
3194 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3195 mAllocator.releaseKeyEntry(entry);
3196}
3197
Jeff Brown3915bb82010-11-05 15:02:16 -07003198void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3199 CommandEntry* commandEntry) {
3200 sp<Connection> connection = commandEntry->connection;
3201 bool handled = commandEntry->handled;
3202
Jeff Brown49ed71d2010-12-06 17:13:33 -08003203 if (!connection->outboundQueue.isEmpty()) {
Jeff Brown3915bb82010-11-05 15:02:16 -07003204 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
3205 if (dispatchEntry->inProgress
3206 && dispatchEntry->hasForegroundTarget()
3207 && dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3208 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003209 if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
3210 if (handled) {
3211 // If the application handled a non-fallback key, then immediately
3212 // cancel all fallback keys previously dispatched to the application.
3213 // This behavior will prevent chording with fallback keys (so they cannot
3214 // be used as modifiers) but it will ensure that fallback keys do not
3215 // get stuck. This takes care of the case where the application does not handle
3216 // the original DOWN so we generate a fallback DOWN but it does handle
3217 // the original UP in which case we would not generate the fallback UP.
3218 synthesizeCancelationEventsForConnectionLocked(connection,
3219 InputState::CANCEL_FALLBACK_EVENTS,
Jeff Brown00045a72010-12-09 18:10:30 -08003220 "application handled a non-fallback event, canceling all fallback events");
Jeff Brown49ed71d2010-12-06 17:13:33 -08003221 } else {
3222 // If the application did not handle a non-fallback key, then ask
3223 // the policy what to do with it. We might generate a fallback key
3224 // event here.
3225 KeyEvent event;
3226 initializeKeyEvent(&event, keyEntry);
Jeff Brown3915bb82010-11-05 15:02:16 -07003227
Jeff Brown49ed71d2010-12-06 17:13:33 -08003228 mLock.unlock();
Jeff Brown3915bb82010-11-05 15:02:16 -07003229
Jeff Brown928e0542011-01-10 11:17:36 -08003230 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003231 &event, keyEntry->policyFlags, &event);
Jeff Brown3915bb82010-11-05 15:02:16 -07003232
Jeff Brown49ed71d2010-12-06 17:13:33 -08003233 mLock.lock();
3234
Jeff Brown00045a72010-12-09 18:10:30 -08003235 if (connection->status != Connection::STATUS_NORMAL) {
3236 return;
3237 }
3238
3239 assert(connection->outboundQueue.headSentinel.next == dispatchEntry);
3240
Jeff Brown49ed71d2010-12-06 17:13:33 -08003241 if (fallback) {
3242 // Restart the dispatch cycle using the fallback key.
3243 keyEntry->eventTime = event.getEventTime();
3244 keyEntry->deviceId = event.getDeviceId();
3245 keyEntry->source = event.getSource();
3246 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
3247 keyEntry->keyCode = event.getKeyCode();
3248 keyEntry->scanCode = event.getScanCode();
3249 keyEntry->metaState = event.getMetaState();
3250 keyEntry->repeatCount = event.getRepeatCount();
3251 keyEntry->downTime = event.getDownTime();
3252 keyEntry->syntheticRepeat = false;
3253
3254 dispatchEntry->inProgress = false;
3255 startDispatchCycleLocked(now(), connection);
3256 return;
3257 }
3258 }
3259 }
Jeff Brown3915bb82010-11-05 15:02:16 -07003260 }
3261 }
3262
3263 startNextDispatchCycleLocked(now(), connection);
3264}
3265
Jeff Brownb88102f2010-09-08 11:49:43 -07003266void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3267 mLock.unlock();
3268
Jeff Brown01ce2e92010-09-26 22:20:12 -07003269 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07003270
3271 mLock.lock();
3272}
3273
Jeff Brown3915bb82010-11-05 15:02:16 -07003274void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
3275 event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3276 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3277 entry->downTime, entry->eventTime);
3278}
3279
Jeff Brown519e0242010-09-15 15:18:56 -07003280void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3281 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3282 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07003283}
3284
3285void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003286 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003287 dumpDispatchStateLocked(dump);
3288}
3289
Jeff Brown9c3cda02010-06-15 01:31:58 -07003290
Jeff Brown519e0242010-09-15 15:18:56 -07003291// --- InputDispatcher::Queue ---
3292
3293template <typename T>
3294uint32_t InputDispatcher::Queue<T>::count() const {
3295 uint32_t result = 0;
3296 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3297 result += 1;
3298 }
3299 return result;
3300}
3301
3302
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003303// --- InputDispatcher::Allocator ---
3304
3305InputDispatcher::Allocator::Allocator() {
3306}
3307
Jeff Brown01ce2e92010-09-26 22:20:12 -07003308InputDispatcher::InjectionState*
3309InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3310 InjectionState* injectionState = mInjectionStatePool.alloc();
3311 injectionState->refCount = 1;
3312 injectionState->injectorPid = injectorPid;
3313 injectionState->injectorUid = injectorUid;
3314 injectionState->injectionIsAsync = false;
3315 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3316 injectionState->pendingForegroundDispatches = 0;
3317 return injectionState;
3318}
3319
Jeff Brown7fbdc842010-06-17 20:52:56 -07003320void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brownb6997262010-10-08 22:31:17 -07003321 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003322 entry->type = type;
3323 entry->refCount = 1;
3324 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07003325 entry->eventTime = eventTime;
Jeff Brownb6997262010-10-08 22:31:17 -07003326 entry->policyFlags = policyFlags;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003327 entry->injectionState = NULL;
3328}
3329
3330void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3331 if (entry->injectionState) {
3332 releaseInjectionState(entry->injectionState);
3333 entry->injectionState = NULL;
3334 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07003335}
3336
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003337InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07003338InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003339 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003340 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003341 return entry;
3342}
3343
Jeff Brown7fbdc842010-06-17 20:52:56 -07003344InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown58a2da82011-01-25 16:02:22 -08003345 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003346 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3347 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003348 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003349 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003350
3351 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003352 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003353 entry->action = action;
3354 entry->flags = flags;
3355 entry->keyCode = keyCode;
3356 entry->scanCode = scanCode;
3357 entry->metaState = metaState;
3358 entry->repeatCount = repeatCount;
3359 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003360 entry->syntheticRepeat = false;
3361 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003362 return entry;
3363}
3364
Jeff Brown7fbdc842010-06-17 20:52:56 -07003365InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown58a2da82011-01-25 16:02:22 -08003366 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003367 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3368 nsecs_t downTime, uint32_t pointerCount,
3369 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003370 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003371 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003372
3373 entry->eventTime = eventTime;
3374 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003375 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003376 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07003377 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003378 entry->metaState = metaState;
3379 entry->edgeFlags = edgeFlags;
3380 entry->xPrecision = xPrecision;
3381 entry->yPrecision = yPrecision;
3382 entry->downTime = downTime;
3383 entry->pointerCount = pointerCount;
3384 entry->firstSample.eventTime = eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003385 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003386 entry->lastSample = & entry->firstSample;
3387 for (uint32_t i = 0; i < pointerCount; i++) {
3388 entry->pointerIds[i] = pointerIds[i];
3389 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3390 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003391 return entry;
3392}
3393
3394InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07003395 EventEntry* eventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07003396 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003397 DispatchEntry* entry = mDispatchEntryPool.alloc();
3398 entry->eventEntry = eventEntry;
3399 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07003400 entry->targetFlags = targetFlags;
3401 entry->xOffset = xOffset;
3402 entry->yOffset = yOffset;
Jeff Brownb88102f2010-09-08 11:49:43 -07003403 entry->inProgress = false;
3404 entry->headMotionSample = NULL;
3405 entry->tailMotionSample = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003406 return entry;
3407}
3408
Jeff Brown9c3cda02010-06-15 01:31:58 -07003409InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3410 CommandEntry* entry = mCommandEntryPool.alloc();
3411 entry->command = command;
3412 return entry;
3413}
3414
Jeff Brown01ce2e92010-09-26 22:20:12 -07003415void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3416 injectionState->refCount -= 1;
3417 if (injectionState->refCount == 0) {
3418 mInjectionStatePool.free(injectionState);
3419 } else {
3420 assert(injectionState->refCount > 0);
3421 }
3422}
3423
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003424void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3425 switch (entry->type) {
3426 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3427 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3428 break;
3429 case EventEntry::TYPE_KEY:
3430 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3431 break;
3432 case EventEntry::TYPE_MOTION:
3433 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3434 break;
3435 default:
3436 assert(false);
3437 break;
3438 }
3439}
3440
3441void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3442 ConfigurationChangedEntry* entry) {
3443 entry->refCount -= 1;
3444 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003445 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003446 mConfigurationChangeEntryPool.free(entry);
3447 } else {
3448 assert(entry->refCount > 0);
3449 }
3450}
3451
3452void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3453 entry->refCount -= 1;
3454 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003455 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003456 mKeyEntryPool.free(entry);
3457 } else {
3458 assert(entry->refCount > 0);
3459 }
3460}
3461
3462void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3463 entry->refCount -= 1;
3464 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003465 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003466 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3467 MotionSample* next = sample->next;
3468 mMotionSamplePool.free(sample);
3469 sample = next;
3470 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003471 mMotionEntryPool.free(entry);
3472 } else {
3473 assert(entry->refCount > 0);
3474 }
3475}
3476
3477void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3478 releaseEventEntry(entry->eventEntry);
3479 mDispatchEntryPool.free(entry);
3480}
3481
Jeff Brown9c3cda02010-06-15 01:31:58 -07003482void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3483 mCommandEntryPool.free(entry);
3484}
3485
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003486void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003487 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003488 MotionSample* sample = mMotionSamplePool.alloc();
3489 sample->eventTime = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003490 uint32_t pointerCount = motionEntry->pointerCount;
3491 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003492 sample->pointerCoords[i] = pointerCoords[i];
3493 }
3494
3495 sample->next = NULL;
3496 motionEntry->lastSample->next = sample;
3497 motionEntry->lastSample = sample;
3498}
3499
Jeff Brown01ce2e92010-09-26 22:20:12 -07003500void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3501 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003502
Jeff Brown01ce2e92010-09-26 22:20:12 -07003503 keyEntry->dispatchInProgress = false;
3504 keyEntry->syntheticRepeat = false;
3505 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003506}
3507
3508
Jeff Brownae9fc032010-08-18 15:51:08 -07003509// --- InputDispatcher::MotionEntry ---
3510
3511uint32_t InputDispatcher::MotionEntry::countSamples() const {
3512 uint32_t count = 1;
3513 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3514 count += 1;
3515 }
3516 return count;
3517}
3518
Jeff Brownb88102f2010-09-08 11:49:43 -07003519
3520// --- InputDispatcher::InputState ---
3521
Jeff Brownb6997262010-10-08 22:31:17 -07003522InputDispatcher::InputState::InputState() {
Jeff Brownb88102f2010-09-08 11:49:43 -07003523}
3524
3525InputDispatcher::InputState::~InputState() {
3526}
3527
3528bool InputDispatcher::InputState::isNeutral() const {
3529 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3530}
3531
Jeff Brownb88102f2010-09-08 11:49:43 -07003532InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3533 const EventEntry* entry) {
3534 switch (entry->type) {
3535 case EventEntry::TYPE_KEY:
3536 return trackKey(static_cast<const KeyEntry*>(entry));
3537
3538 case EventEntry::TYPE_MOTION:
3539 return trackMotion(static_cast<const MotionEntry*>(entry));
3540
3541 default:
3542 return CONSISTENT;
3543 }
3544}
3545
3546InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3547 const KeyEntry* entry) {
3548 int32_t action = entry->action;
3549 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3550 KeyMemento& memento = mKeyMementos.editItemAt(i);
3551 if (memento.deviceId == entry->deviceId
3552 && memento.source == entry->source
3553 && memento.keyCode == entry->keyCode
3554 && memento.scanCode == entry->scanCode) {
3555 switch (action) {
3556 case AKEY_EVENT_ACTION_UP:
3557 mKeyMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003558 return CONSISTENT;
3559
3560 case AKEY_EVENT_ACTION_DOWN:
3561 return TOLERABLE;
3562
3563 default:
3564 return BROKEN;
3565 }
3566 }
3567 }
3568
3569 switch (action) {
3570 case AKEY_EVENT_ACTION_DOWN: {
3571 mKeyMementos.push();
3572 KeyMemento& memento = mKeyMementos.editTop();
3573 memento.deviceId = entry->deviceId;
3574 memento.source = entry->source;
3575 memento.keyCode = entry->keyCode;
3576 memento.scanCode = entry->scanCode;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003577 memento.flags = entry->flags;
Jeff Brownb88102f2010-09-08 11:49:43 -07003578 memento.downTime = entry->downTime;
3579 return CONSISTENT;
3580 }
3581
3582 default:
3583 return BROKEN;
3584 }
3585}
3586
3587InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3588 const MotionEntry* entry) {
3589 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3590 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3591 MotionMemento& memento = mMotionMementos.editItemAt(i);
3592 if (memento.deviceId == entry->deviceId
3593 && memento.source == entry->source) {
3594 switch (action) {
3595 case AMOTION_EVENT_ACTION_UP:
3596 case AMOTION_EVENT_ACTION_CANCEL:
3597 mMotionMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003598 return CONSISTENT;
3599
3600 case AMOTION_EVENT_ACTION_DOWN:
3601 return TOLERABLE;
3602
3603 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3604 if (entry->pointerCount == memento.pointerCount + 1) {
3605 memento.setPointers(entry);
3606 return CONSISTENT;
3607 }
3608 return BROKEN;
3609
3610 case AMOTION_EVENT_ACTION_POINTER_UP:
3611 if (entry->pointerCount == memento.pointerCount - 1) {
3612 memento.setPointers(entry);
3613 return CONSISTENT;
3614 }
3615 return BROKEN;
3616
3617 case AMOTION_EVENT_ACTION_MOVE:
3618 if (entry->pointerCount == memento.pointerCount) {
3619 return CONSISTENT;
3620 }
3621 return BROKEN;
3622
3623 default:
3624 return BROKEN;
3625 }
3626 }
3627 }
3628
3629 switch (action) {
3630 case AMOTION_EVENT_ACTION_DOWN: {
3631 mMotionMementos.push();
3632 MotionMemento& memento = mMotionMementos.editTop();
3633 memento.deviceId = entry->deviceId;
3634 memento.source = entry->source;
3635 memento.xPrecision = entry->xPrecision;
3636 memento.yPrecision = entry->yPrecision;
3637 memento.downTime = entry->downTime;
3638 memento.setPointers(entry);
3639 return CONSISTENT;
3640 }
3641
3642 default:
3643 return BROKEN;
3644 }
3645}
3646
3647void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3648 pointerCount = entry->pointerCount;
3649 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3650 pointerIds[i] = entry->pointerIds[i];
3651 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3652 }
3653}
3654
Jeff Brownb6997262010-10-08 22:31:17 -07003655void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3656 Allocator* allocator, Vector<EventEntry*>& outEvents,
3657 CancelationOptions options) {
3658 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003659 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003660 if (shouldCancelKey(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003661 outEvents.push(allocator->obtainKeyEntry(currentTime,
3662 memento.deviceId, memento.source, 0,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003663 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
Jeff Brownb6997262010-10-08 22:31:17 -07003664 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3665 mKeyMementos.removeAt(i);
3666 } else {
3667 i += 1;
3668 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003669 }
3670
Jeff Browna1160a72010-10-11 18:22:53 -07003671 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003672 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003673 if (shouldCancelMotion(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003674 outEvents.push(allocator->obtainMotionEntry(currentTime,
3675 memento.deviceId, memento.source, 0,
3676 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3677 memento.xPrecision, memento.yPrecision, memento.downTime,
3678 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3679 mMotionMementos.removeAt(i);
3680 } else {
3681 i += 1;
3682 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003683 }
3684}
3685
3686void InputDispatcher::InputState::clear() {
3687 mKeyMementos.clear();
3688 mMotionMementos.clear();
Jeff Brownb6997262010-10-08 22:31:17 -07003689}
3690
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003691void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3692 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3693 const MotionMemento& memento = mMotionMementos.itemAt(i);
3694 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3695 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3696 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3697 if (memento.deviceId == otherMemento.deviceId
3698 && memento.source == otherMemento.source) {
3699 other.mMotionMementos.removeAt(j);
3700 } else {
3701 j += 1;
3702 }
3703 }
3704 other.mMotionMementos.push(memento);
3705 }
3706 }
3707}
3708
Jeff Brown49ed71d2010-12-06 17:13:33 -08003709bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
Jeff Brownb6997262010-10-08 22:31:17 -07003710 CancelationOptions options) {
3711 switch (options) {
Jeff Brown49ed71d2010-12-06 17:13:33 -08003712 case CANCEL_ALL_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003713 case CANCEL_NON_POINTER_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003714 return true;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003715 case CANCEL_FALLBACK_EVENTS:
3716 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
3717 default:
3718 return false;
3719 }
3720}
3721
3722bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
3723 CancelationOptions options) {
3724 switch (options) {
3725 case CANCEL_ALL_EVENTS:
3726 return true;
3727 case CANCEL_POINTER_EVENTS:
3728 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
3729 case CANCEL_NON_POINTER_EVENTS:
3730 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
3731 default:
3732 return false;
Jeff Brownb6997262010-10-08 22:31:17 -07003733 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003734}
3735
3736
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003737// --- InputDispatcher::Connection ---
3738
Jeff Brown928e0542011-01-10 11:17:36 -08003739InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
3740 const sp<InputWindowHandle>& inputWindowHandle) :
3741 status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
3742 inputPublisher(inputChannel),
Jeff Brown519e0242010-09-15 15:18:56 -07003743 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003744}
3745
3746InputDispatcher::Connection::~Connection() {
3747}
3748
3749status_t InputDispatcher::Connection::initialize() {
3750 return inputPublisher.initialize();
3751}
3752
Jeff Brown9c3cda02010-06-15 01:31:58 -07003753const char* InputDispatcher::Connection::getStatusLabel() const {
3754 switch (status) {
3755 case STATUS_NORMAL:
3756 return "NORMAL";
3757
3758 case STATUS_BROKEN:
3759 return "BROKEN";
3760
Jeff Brown9c3cda02010-06-15 01:31:58 -07003761 case STATUS_ZOMBIE:
3762 return "ZOMBIE";
3763
3764 default:
3765 return "UNKNOWN";
3766 }
3767}
3768
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003769InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3770 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07003771 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3772 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003773 if (dispatchEntry->eventEntry == eventEntry) {
3774 return dispatchEntry;
3775 }
3776 }
3777 return NULL;
3778}
3779
Jeff Brownb88102f2010-09-08 11:49:43 -07003780
Jeff Brown9c3cda02010-06-15 01:31:58 -07003781// --- InputDispatcher::CommandEntry ---
3782
Jeff Brownb88102f2010-09-08 11:49:43 -07003783InputDispatcher::CommandEntry::CommandEntry() :
3784 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003785}
3786
3787InputDispatcher::CommandEntry::~CommandEntry() {
3788}
3789
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003790
Jeff Brown01ce2e92010-09-26 22:20:12 -07003791// --- InputDispatcher::TouchState ---
3792
3793InputDispatcher::TouchState::TouchState() :
Jeff Brown58a2da82011-01-25 16:02:22 -08003794 down(false), split(false), deviceId(-1), source(0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003795}
3796
3797InputDispatcher::TouchState::~TouchState() {
3798}
3799
3800void InputDispatcher::TouchState::reset() {
3801 down = false;
3802 split = false;
Jeff Brown95712852011-01-04 19:41:59 -08003803 deviceId = -1;
Jeff Brown58a2da82011-01-25 16:02:22 -08003804 source = 0;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003805 windows.clear();
3806}
3807
3808void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3809 down = other.down;
3810 split = other.split;
Jeff Brown95712852011-01-04 19:41:59 -08003811 deviceId = other.deviceId;
Jeff Brown58a2da82011-01-25 16:02:22 -08003812 source = other.source;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003813 windows.clear();
3814 windows.appendVector(other.windows);
3815}
3816
3817void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3818 int32_t targetFlags, BitSet32 pointerIds) {
3819 if (targetFlags & InputTarget::FLAG_SPLIT) {
3820 split = true;
3821 }
3822
3823 for (size_t i = 0; i < windows.size(); i++) {
3824 TouchedWindow& touchedWindow = windows.editItemAt(i);
3825 if (touchedWindow.window == window) {
3826 touchedWindow.targetFlags |= targetFlags;
3827 touchedWindow.pointerIds.value |= pointerIds.value;
3828 return;
3829 }
3830 }
3831
3832 windows.push();
3833
3834 TouchedWindow& touchedWindow = windows.editTop();
3835 touchedWindow.window = window;
3836 touchedWindow.targetFlags = targetFlags;
3837 touchedWindow.pointerIds = pointerIds;
3838 touchedWindow.channel = window->inputChannel;
3839}
3840
3841void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3842 for (size_t i = 0 ; i < windows.size(); ) {
3843 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3844 windows.removeAt(i);
3845 } else {
3846 i += 1;
3847 }
3848 }
3849}
3850
3851const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3852 for (size_t i = 0; i < windows.size(); i++) {
3853 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3854 return windows[i].window;
3855 }
3856 }
3857 return NULL;
3858}
3859
3860
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003861// --- InputDispatcherThread ---
3862
3863InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3864 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3865}
3866
3867InputDispatcherThread::~InputDispatcherThread() {
3868}
3869
3870bool InputDispatcherThread::threadLoop() {
3871 mDispatcher->dispatchOnce();
3872 return true;
3873}
3874
3875} // namespace android