blob: e314145112bf32ec4e107f47541200af7bcf6b47 [file] [log] [blame]
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070017#define LOG_TAG "InputDispatcher"
18
19//#define LOG_NDEBUG 0
20
21// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070022#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070023
24// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070025#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070026
27// Log debug messages about batching.
Jeff Brown349703e2010-06-22 01:27:15 -070028#define DEBUG_BATCHING 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070029
30// Log debug messages about the dispatch cycle.
Jeff Brown349703e2010-06-22 01:27:15 -070031#define DEBUG_DISPATCH_CYCLE 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070032
Jeff Brown9c3cda02010-06-15 01:31:58 -070033// Log debug messages about registrations.
Jeff Brown349703e2010-06-22 01:27:15 -070034#define DEBUG_REGISTRATION 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070035
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070036// Log debug messages about performance statistics.
Jeff Brown349703e2010-06-22 01:27:15 -070037#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070038
Jeff Brown7fbdc842010-06-17 20:52:56 -070039// Log debug messages about input event injection.
Jeff Brown349703e2010-06-22 01:27:15 -070040#define DEBUG_INJECTION 0
Jeff Brown7fbdc842010-06-17 20:52:56 -070041
Jeff Brownae9fc032010-08-18 15:51:08 -070042// Log debug messages about input event throttling.
43#define DEBUG_THROTTLING 0
44
Jeff Brownb88102f2010-09-08 11:49:43 -070045// Log debug messages about input focus tracking.
46#define DEBUG_FOCUS 0
47
48// Log debug messages about the app switch latency optimization.
49#define DEBUG_APP_SWITCH 0
50
Jeff Brownb4ff35d2011-01-02 16:37:43 -080051#include "InputDispatcher.h"
52
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070053#include <cutils/log.h>
Jeff Brownb88102f2010-09-08 11:49:43 -070054#include <ui/PowerManager.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070055
56#include <stddef.h>
57#include <unistd.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070058#include <errno.h>
59#include <limits.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070060
Jeff Brownf2f487182010-10-01 17:46:21 -070061#define INDENT " "
62#define INDENT2 " "
63
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070064namespace android {
65
Jeff Brownb88102f2010-09-08 11:49:43 -070066// Default input dispatching timeout if there is no focused application or paused window
67// from which to determine an appropriate dispatching timeout.
68const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
69
70// Amount of time to allow for all pending events to be processed when an app switch
71// key is on the way. This is used to preempt input dispatch and drop input events
72// when an application takes too long to respond and the user has pressed an app switch key.
73const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
74
Jeff Brown928e0542011-01-10 11:17:36 -080075// Amount of time to allow for an event to be dispatched (measured since its eventTime)
76// before considering it stale and dropping it.
77const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
78
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070079
Jeff Brown7fbdc842010-06-17 20:52:56 -070080static inline nsecs_t now() {
81 return systemTime(SYSTEM_TIME_MONOTONIC);
82}
83
Jeff Brownb88102f2010-09-08 11:49:43 -070084static inline const char* toString(bool value) {
85 return value ? "true" : "false";
86}
87
Jeff Brown01ce2e92010-09-26 22:20:12 -070088static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
89 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
90 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
91}
92
93static bool isValidKeyAction(int32_t action) {
94 switch (action) {
95 case AKEY_EVENT_ACTION_DOWN:
96 case AKEY_EVENT_ACTION_UP:
97 return true;
98 default:
99 return false;
100 }
101}
102
103static bool validateKeyEvent(int32_t action) {
104 if (! isValidKeyAction(action)) {
105 LOGE("Key event has invalid action code 0x%x", action);
106 return false;
107 }
108 return true;
109}
110
Jeff Brownb6997262010-10-08 22:31:17 -0700111static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700112 switch (action & AMOTION_EVENT_ACTION_MASK) {
113 case AMOTION_EVENT_ACTION_DOWN:
114 case AMOTION_EVENT_ACTION_UP:
115 case AMOTION_EVENT_ACTION_CANCEL:
116 case AMOTION_EVENT_ACTION_MOVE:
Jeff Brown01ce2e92010-09-26 22:20:12 -0700117 case AMOTION_EVENT_ACTION_OUTSIDE:
118 return true;
Jeff Brownb6997262010-10-08 22:31:17 -0700119 case AMOTION_EVENT_ACTION_POINTER_DOWN:
120 case AMOTION_EVENT_ACTION_POINTER_UP: {
121 int32_t index = getMotionEventActionPointerIndex(action);
122 return index >= 0 && size_t(index) < pointerCount;
123 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700124 default:
125 return false;
126 }
127}
128
129static bool validateMotionEvent(int32_t action, size_t pointerCount,
130 const int32_t* pointerIds) {
Jeff Brownb6997262010-10-08 22:31:17 -0700131 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700132 LOGE("Motion event has invalid action code 0x%x", action);
133 return false;
134 }
135 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
136 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
137 pointerCount, MAX_POINTERS);
138 return false;
139 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700140 BitSet32 pointerIdBits;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700141 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownc3db8582010-10-20 15:33:38 -0700142 int32_t id = pointerIds[i];
143 if (id < 0 || id > MAX_POINTER_ID) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700144 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
Jeff Brownc3db8582010-10-20 15:33:38 -0700145 id, MAX_POINTER_ID);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700146 return false;
147 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700148 if (pointerIdBits.hasBit(id)) {
149 LOGE("Motion event has duplicate pointer id %d", id);
150 return false;
151 }
152 pointerIdBits.markBit(id);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700153 }
154 return true;
155}
156
Jeff Brownfbf09772011-01-16 14:06:57 -0800157static void dumpRegion(String8& dump, const SkRegion& region) {
158 if (region.isEmpty()) {
159 dump.append("<empty>");
160 return;
161 }
162
163 bool first = true;
164 for (SkRegion::Iterator it(region); !it.done(); it.next()) {
165 if (first) {
166 first = false;
167 } else {
168 dump.append("|");
169 }
170 const SkIRect& rect = it.rect();
171 dump.appendFormat("[%d,%d][%d,%d]", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
172 }
173}
174
Jeff Brownb88102f2010-09-08 11:49:43 -0700175
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700176// --- InputDispatcher ---
177
Jeff Brown9c3cda02010-06-15 01:31:58 -0700178InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Brownb88102f2010-09-08 11:49:43 -0700179 mPolicy(policy),
Jeff Brown928e0542011-01-10 11:17:36 -0800180 mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
181 mNextUnblockedEvent(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700182 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brown01ce2e92010-09-26 22:20:12 -0700183 mFocusedWindow(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700184 mFocusedApplication(NULL),
185 mCurrentInputTargetsValid(false),
186 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700187 mLooper = new Looper(false);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700188
Jeff Brownb88102f2010-09-08 11:49:43 -0700189 mInboundQueue.headSentinel.refCount = -1;
190 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
191 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700192
Jeff Brownb88102f2010-09-08 11:49:43 -0700193 mInboundQueue.tailSentinel.refCount = -1;
194 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
195 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700196
197 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700198
Jeff Brownae9fc032010-08-18 15:51:08 -0700199 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
200 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
201 mThrottleState.lastDeviceId = -1;
202
203#if DEBUG_THROTTLING
204 mThrottleState.originalSampleCount = 0;
205 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
206#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700207}
208
209InputDispatcher::~InputDispatcher() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700210 { // acquire lock
211 AutoMutex _l(mLock);
212
213 resetKeyRepeatLocked();
Jeff Brown54a18252010-09-16 14:07:33 -0700214 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700215 drainInboundQueueLocked();
216 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700217
218 while (mConnectionsByReceiveFd.size() != 0) {
219 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
220 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700221}
222
223void InputDispatcher::dispatchOnce() {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700224 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700225 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700226
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700227 nsecs_t nextWakeupTime = LONG_LONG_MAX;
228 { // acquire lock
229 AutoMutex _l(mLock);
Jeff Brownb88102f2010-09-08 11:49:43 -0700230 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700231
Jeff Brownb88102f2010-09-08 11:49:43 -0700232 if (runCommandsLockedInterruptible()) {
233 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700234 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700235 } // release lock
236
Jeff Brownb88102f2010-09-08 11:49:43 -0700237 // Wait for callback or timeout or wake. (make sure we round up, not down)
238 nsecs_t currentTime = now();
239 int32_t timeoutMillis;
240 if (nextWakeupTime > currentTime) {
241 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
242 timeout = (timeout + 999999LL) / 1000000LL;
243 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
244 } else {
245 timeoutMillis = 0;
246 }
247
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700248 mLooper->pollOnce(timeoutMillis);
Jeff Brownb88102f2010-09-08 11:49:43 -0700249}
250
251void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
252 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
253 nsecs_t currentTime = now();
254
255 // Reset the key repeat timer whenever we disallow key events, even if the next event
256 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
257 // out of sleep.
258 if (keyRepeatTimeout < 0) {
259 resetKeyRepeatLocked();
260 }
261
Jeff Brownb88102f2010-09-08 11:49:43 -0700262 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
263 if (mDispatchFrozen) {
264#if DEBUG_FOCUS
265 LOGD("Dispatch frozen. Waiting some more.");
266#endif
267 return;
268 }
269
270 // Optimize latency of app switches.
271 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
272 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
273 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
274 if (mAppSwitchDueTime < *nextWakeupTime) {
275 *nextWakeupTime = mAppSwitchDueTime;
276 }
277
Jeff Brownb88102f2010-09-08 11:49:43 -0700278 // Ready to start a new event.
279 // If we don't already have a pending event, go grab one.
280 if (! mPendingEvent) {
281 if (mInboundQueue.isEmpty()) {
282 if (isAppSwitchDue) {
283 // The inbound queue is empty so the app switch key we were waiting
284 // for will never arrive. Stop waiting for it.
285 resetPendingAppSwitchLocked(false);
286 isAppSwitchDue = false;
287 }
288
289 // Synthesize a key repeat if appropriate.
290 if (mKeyRepeatState.lastKeyEntry) {
291 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
292 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
293 } else {
294 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
295 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
296 }
297 }
298 }
299 if (! mPendingEvent) {
300 return;
301 }
302 } else {
303 // Inbound queue has at least one entry.
304 EventEntry* entry = mInboundQueue.headSentinel.next;
305
306 // Throttle the entry if it is a move event and there are no
307 // other events behind it in the queue. Due to movement batching, additional
308 // samples may be appended to this event by the time the throttling timeout
309 // expires.
310 // TODO Make this smarter and consider throttling per device independently.
Jeff Brownb6997262010-10-08 22:31:17 -0700311 if (entry->type == EventEntry::TYPE_MOTION
312 && !isAppSwitchDue
313 && mDispatchEnabled
314 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
315 && !entry->isInjected()) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700316 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
317 int32_t deviceId = motionEntry->deviceId;
318 uint32_t source = motionEntry->source;
319 if (! isAppSwitchDue
320 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
321 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
322 && deviceId == mThrottleState.lastDeviceId
323 && source == mThrottleState.lastSource) {
324 nsecs_t nextTime = mThrottleState.lastEventTime
325 + mThrottleState.minTimeBetweenEvents;
326 if (currentTime < nextTime) {
327 // Throttle it!
328#if DEBUG_THROTTLING
329 LOGD("Throttling - Delaying motion event for "
Jeff Brown90655042010-12-02 13:50:46 -0800330 "device %d, source 0x%08x by up to %0.3fms.",
Jeff Brownb88102f2010-09-08 11:49:43 -0700331 deviceId, source, (nextTime - currentTime) * 0.000001);
332#endif
333 if (nextTime < *nextWakeupTime) {
334 *nextWakeupTime = nextTime;
335 }
336 if (mThrottleState.originalSampleCount == 0) {
337 mThrottleState.originalSampleCount =
338 motionEntry->countSamples();
339 }
340 return;
341 }
342 }
343
344#if DEBUG_THROTTLING
345 if (mThrottleState.originalSampleCount != 0) {
346 uint32_t count = motionEntry->countSamples();
347 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
348 count - mThrottleState.originalSampleCount,
349 mThrottleState.originalSampleCount, count);
350 mThrottleState.originalSampleCount = 0;
351 }
352#endif
353
354 mThrottleState.lastEventTime = entry->eventTime < currentTime
355 ? entry->eventTime : currentTime;
356 mThrottleState.lastDeviceId = deviceId;
357 mThrottleState.lastSource = source;
358 }
359
360 mInboundQueue.dequeue(entry);
361 mPendingEvent = entry;
362 }
Jeff Browne2fe69e2010-10-18 13:21:23 -0700363
364 // Poke user activity for this event.
365 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
366 pokeUserActivityLocked(mPendingEvent);
367 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700368 }
369
370 // Now we have an event to dispatch.
Jeff Brown928e0542011-01-10 11:17:36 -0800371 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Jeff Brownb88102f2010-09-08 11:49:43 -0700372 assert(mPendingEvent != NULL);
Jeff Brown54a18252010-09-16 14:07:33 -0700373 bool done = false;
Jeff Brownb6997262010-10-08 22:31:17 -0700374 DropReason dropReason = DROP_REASON_NOT_DROPPED;
375 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
376 dropReason = DROP_REASON_POLICY;
377 } else if (!mDispatchEnabled) {
378 dropReason = DROP_REASON_DISABLED;
379 }
Jeff Brown928e0542011-01-10 11:17:36 -0800380
381 if (mNextUnblockedEvent == mPendingEvent) {
382 mNextUnblockedEvent = NULL;
383 }
384
Jeff Brownb88102f2010-09-08 11:49:43 -0700385 switch (mPendingEvent->type) {
386 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
387 ConfigurationChangedEntry* typedEntry =
388 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700389 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brownb6997262010-10-08 22:31:17 -0700390 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Brownb88102f2010-09-08 11:49:43 -0700391 break;
392 }
393
394 case EventEntry::TYPE_KEY: {
395 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700396 if (isAppSwitchDue) {
397 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700398 resetPendingAppSwitchLocked(true);
Jeff Brownb6997262010-10-08 22:31:17 -0700399 isAppSwitchDue = false;
400 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
401 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700402 }
403 }
Jeff Brown928e0542011-01-10 11:17:36 -0800404 if (dropReason == DROP_REASON_NOT_DROPPED
405 && isStaleEventLocked(currentTime, typedEntry)) {
406 dropReason = DROP_REASON_STALE;
407 }
408 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
409 dropReason = DROP_REASON_BLOCKED;
410 }
Jeff Brownb6997262010-10-08 22:31:17 -0700411 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Browne20c9e02010-10-11 14:20:19 -0700412 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700413 break;
414 }
415
416 case EventEntry::TYPE_MOTION: {
417 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700418 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
419 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700420 }
Jeff Brown928e0542011-01-10 11:17:36 -0800421 if (dropReason == DROP_REASON_NOT_DROPPED
422 && isStaleEventLocked(currentTime, typedEntry)) {
423 dropReason = DROP_REASON_STALE;
424 }
425 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
426 dropReason = DROP_REASON_BLOCKED;
427 }
Jeff Brownb6997262010-10-08 22:31:17 -0700428 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Browne20c9e02010-10-11 14:20:19 -0700429 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700430 break;
431 }
432
433 default:
434 assert(false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700435 break;
436 }
437
Jeff Brown54a18252010-09-16 14:07:33 -0700438 if (done) {
Jeff Brownb6997262010-10-08 22:31:17 -0700439 if (dropReason != DROP_REASON_NOT_DROPPED) {
440 dropInboundEventLocked(mPendingEvent, dropReason);
441 }
442
Jeff Brown54a18252010-09-16 14:07:33 -0700443 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700444 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
445 }
446}
447
448bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
449 bool needWake = mInboundQueue.isEmpty();
450 mInboundQueue.enqueueAtTail(entry);
451
452 switch (entry->type) {
Jeff Brownb6997262010-10-08 22:31:17 -0700453 case EventEntry::TYPE_KEY: {
Jeff Brown928e0542011-01-10 11:17:36 -0800454 // Optimize app switch latency.
455 // If the application takes too long to catch up then we drop all events preceding
456 // the app switch key.
Jeff Brownb6997262010-10-08 22:31:17 -0700457 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
458 if (isAppSwitchKeyEventLocked(keyEntry)) {
459 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
460 mAppSwitchSawKeyDown = true;
461 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
462 if (mAppSwitchSawKeyDown) {
463#if DEBUG_APP_SWITCH
464 LOGD("App switch is pending!");
465#endif
466 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
467 mAppSwitchSawKeyDown = false;
468 needWake = true;
469 }
470 }
471 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700472 break;
473 }
Jeff Brown928e0542011-01-10 11:17:36 -0800474
475 case EventEntry::TYPE_MOTION: {
476 // Optimize case where the current application is unresponsive and the user
477 // decides to touch a window in a different application.
478 // If the application takes too long to catch up then we drop all events preceding
479 // the touch into the other window.
480 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
481 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
482 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
483 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
484 && mInputTargetWaitApplication != NULL) {
485 int32_t x = int32_t(motionEntry->firstSample.pointerCoords[0].x);
486 int32_t y = int32_t(motionEntry->firstSample.pointerCoords[0].y);
487 const InputWindow* touchedWindow = findTouchedWindowAtLocked(x, y);
488 if (touchedWindow
489 && touchedWindow->inputWindowHandle != NULL
490 && touchedWindow->inputWindowHandle->getInputApplicationHandle()
491 != mInputTargetWaitApplication) {
492 // User touched a different application than the one we are waiting on.
493 // Flag the event, and start pruning the input queue.
494 mNextUnblockedEvent = motionEntry;
495 needWake = true;
496 }
497 }
498 break;
499 }
Jeff Brownb6997262010-10-08 22:31:17 -0700500 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700501
502 return needWake;
503}
504
Jeff Brown928e0542011-01-10 11:17:36 -0800505const InputWindow* InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
506 // Traverse windows from front to back to find touched window.
507 size_t numWindows = mWindows.size();
508 for (size_t i = 0; i < numWindows; i++) {
509 const InputWindow* window = & mWindows.editItemAt(i);
510 int32_t flags = window->layoutParamsFlags;
511
512 if (window->visible) {
513 if (!(flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
514 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
515 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
Jeff Brownfbf09772011-01-16 14:06:57 -0800516 if (isTouchModal || window->touchableRegionContainsPoint(x, y)) {
Jeff Brown928e0542011-01-10 11:17:36 -0800517 // Found window.
518 return window;
519 }
520 }
521 }
522
523 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
524 // Error window is on top but not visible, so touch is dropped.
525 return NULL;
526 }
527 }
528 return NULL;
529}
530
Jeff Brownb6997262010-10-08 22:31:17 -0700531void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
532 const char* reason;
533 switch (dropReason) {
534 case DROP_REASON_POLICY:
Jeff Browne20c9e02010-10-11 14:20:19 -0700535#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown3122e442010-10-11 23:32:49 -0700536 LOGD("Dropped event because policy consumed it.");
Jeff Browne20c9e02010-10-11 14:20:19 -0700537#endif
Jeff Brown3122e442010-10-11 23:32:49 -0700538 reason = "inbound event was dropped because the policy consumed it";
Jeff Brownb6997262010-10-08 22:31:17 -0700539 break;
540 case DROP_REASON_DISABLED:
541 LOGI("Dropped event because input dispatch is disabled.");
542 reason = "inbound event was dropped because input dispatch is disabled";
543 break;
544 case DROP_REASON_APP_SWITCH:
545 LOGI("Dropped event because of pending overdue app switch.");
546 reason = "inbound event was dropped because of pending overdue app switch";
547 break;
Jeff Brown928e0542011-01-10 11:17:36 -0800548 case DROP_REASON_BLOCKED:
549 LOGI("Dropped event because the current application is not responding and the user "
550 "has started interating with a different application.");
551 reason = "inbound event was dropped because the current application is not responding "
552 "and the user has started interating with a different application";
553 break;
554 case DROP_REASON_STALE:
555 LOGI("Dropped event because it is stale.");
556 reason = "inbound event was dropped because it is stale";
557 break;
Jeff Brownb6997262010-10-08 22:31:17 -0700558 default:
559 assert(false);
560 return;
561 }
562
563 switch (entry->type) {
564 case EventEntry::TYPE_KEY:
565 synthesizeCancelationEventsForAllConnectionsLocked(
566 InputState::CANCEL_NON_POINTER_EVENTS, reason);
567 break;
568 case EventEntry::TYPE_MOTION: {
569 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
570 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
571 synthesizeCancelationEventsForAllConnectionsLocked(
572 InputState::CANCEL_POINTER_EVENTS, reason);
573 } else {
574 synthesizeCancelationEventsForAllConnectionsLocked(
575 InputState::CANCEL_NON_POINTER_EVENTS, reason);
576 }
577 break;
578 }
579 }
580}
581
582bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700583 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
584}
585
Jeff Brownb6997262010-10-08 22:31:17 -0700586bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
587 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
588 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Browne20c9e02010-10-11 14:20:19 -0700589 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brownb6997262010-10-08 22:31:17 -0700590 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
591}
592
Jeff Brownb88102f2010-09-08 11:49:43 -0700593bool InputDispatcher::isAppSwitchPendingLocked() {
594 return mAppSwitchDueTime != LONG_LONG_MAX;
595}
596
Jeff Brownb88102f2010-09-08 11:49:43 -0700597void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
598 mAppSwitchDueTime = LONG_LONG_MAX;
599
600#if DEBUG_APP_SWITCH
601 if (handled) {
602 LOGD("App switch has arrived.");
603 } else {
604 LOGD("App switch was abandoned.");
605 }
606#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700607}
608
Jeff Brown928e0542011-01-10 11:17:36 -0800609bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
610 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
611}
612
Jeff Brown9c3cda02010-06-15 01:31:58 -0700613bool InputDispatcher::runCommandsLockedInterruptible() {
614 if (mCommandQueue.isEmpty()) {
615 return false;
616 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700617
Jeff Brown9c3cda02010-06-15 01:31:58 -0700618 do {
619 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
620
621 Command command = commandEntry->command;
622 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
623
Jeff Brown7fbdc842010-06-17 20:52:56 -0700624 commandEntry->connection.clear();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700625 mAllocator.releaseCommandEntry(commandEntry);
626 } while (! mCommandQueue.isEmpty());
627 return true;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700628}
629
Jeff Brown9c3cda02010-06-15 01:31:58 -0700630InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
631 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
632 mCommandQueue.enqueueAtTail(commandEntry);
633 return commandEntry;
634}
635
Jeff Brownb88102f2010-09-08 11:49:43 -0700636void InputDispatcher::drainInboundQueueLocked() {
637 while (! mInboundQueue.isEmpty()) {
638 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700639 releaseInboundEventLocked(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700640 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700641}
642
Jeff Brown54a18252010-09-16 14:07:33 -0700643void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700644 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700645 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700646 mPendingEvent = NULL;
647 }
648}
649
Jeff Brown54a18252010-09-16 14:07:33 -0700650void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700651 InjectionState* injectionState = entry->injectionState;
652 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700653#if DEBUG_DISPATCH_CYCLE
Jeff Brown01ce2e92010-09-26 22:20:12 -0700654 LOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700655#endif
656 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
657 }
658 mAllocator.releaseEventEntry(entry);
659}
660
Jeff Brownb88102f2010-09-08 11:49:43 -0700661void InputDispatcher::resetKeyRepeatLocked() {
662 if (mKeyRepeatState.lastKeyEntry) {
663 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
664 mKeyRepeatState.lastKeyEntry = NULL;
665 }
666}
667
668InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brownb21fb102010-09-07 10:44:57 -0700669 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown349703e2010-06-22 01:27:15 -0700670 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
671
Jeff Brown349703e2010-06-22 01:27:15 -0700672 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Browne20c9e02010-10-11 14:20:19 -0700673 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
674 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700675 if (entry->refCount == 1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700676 mAllocator.recycleKeyEntry(entry);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700677 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700678 entry->policyFlags = policyFlags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700679 entry->repeatCount += 1;
680 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700681 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700682 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700683 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700684 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700685
686 mKeyRepeatState.lastKeyEntry = newEntry;
687 mAllocator.releaseKeyEntry(entry);
688
689 entry = newEntry;
690 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700691 entry->syntheticRepeat = true;
692
693 // Increment reference count since we keep a reference to the event in
694 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
695 entry->refCount += 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700696
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700697 if (entry->repeatCount == 1) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700698 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700699 }
700
Jeff Brownb21fb102010-09-07 10:44:57 -0700701 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700702 return entry;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700703}
704
Jeff Brownb88102f2010-09-08 11:49:43 -0700705bool InputDispatcher::dispatchConfigurationChangedLocked(
706 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700707#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownb88102f2010-09-08 11:49:43 -0700708 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
709#endif
710
711 // Reset key repeating in case a keyboard device was added or removed or something.
712 resetKeyRepeatLocked();
713
714 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
715 CommandEntry* commandEntry = postCommandLocked(
716 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
717 commandEntry->eventTime = entry->eventTime;
718 return true;
719}
720
721bool InputDispatcher::dispatchKeyLocked(
722 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Browne20c9e02010-10-11 14:20:19 -0700723 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700724 // Preprocessing.
725 if (! entry->dispatchInProgress) {
726 if (entry->repeatCount == 0
727 && entry->action == AKEY_EVENT_ACTION_DOWN
728 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
729 && !entry->isInjected()) {
730 if (mKeyRepeatState.lastKeyEntry
731 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
732 // We have seen two identical key downs in a row which indicates that the device
733 // driver is automatically generating key repeats itself. We take note of the
734 // repeat here, but we disable our own next key repeat timer since it is clear that
735 // we will not need to synthesize key repeats ourselves.
736 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
737 resetKeyRepeatLocked();
738 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
739 } else {
740 // Not a repeat. Save key down state in case we do see a repeat later.
741 resetKeyRepeatLocked();
742 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
743 }
744 mKeyRepeatState.lastKeyEntry = entry;
745 entry->refCount += 1;
746 } else if (! entry->syntheticRepeat) {
747 resetKeyRepeatLocked();
748 }
749
750 entry->dispatchInProgress = true;
751 resetTargetsLocked();
752
753 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
754 }
755
Jeff Brown54a18252010-09-16 14:07:33 -0700756 // Give the policy a chance to intercept the key.
757 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700758 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brown54a18252010-09-16 14:07:33 -0700759 CommandEntry* commandEntry = postCommandLocked(
760 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Browne20c9e02010-10-11 14:20:19 -0700761 if (mFocusedWindow) {
Jeff Brown928e0542011-01-10 11:17:36 -0800762 commandEntry->inputWindowHandle = mFocusedWindow->inputWindowHandle;
Jeff Brown54a18252010-09-16 14:07:33 -0700763 }
764 commandEntry->keyEntry = entry;
765 entry->refCount += 1;
766 return false; // wait for the command to run
767 } else {
768 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
769 }
770 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700771 if (*dropReason == DROP_REASON_NOT_DROPPED) {
772 *dropReason = DROP_REASON_POLICY;
773 }
Jeff Brown54a18252010-09-16 14:07:33 -0700774 }
775
776 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700777 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700778 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700779 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
780 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700781 return true;
782 }
783
Jeff Brownb88102f2010-09-08 11:49:43 -0700784 // Identify targets.
785 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700786 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
787 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700788 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
789 return false;
790 }
791
792 setInjectionResultLocked(entry, injectionResult);
793 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
794 return true;
795 }
796
797 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700798 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700799 }
800
801 // Dispatch the key.
802 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700803 return true;
804}
805
806void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
807#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800808 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brownb88102f2010-09-08 11:49:43 -0700809 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
Jeff Browne46a0a42010-11-02 17:58:22 -0700810 "repeatCount=%d, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700811 prefix,
812 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
813 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Jeff Browne46a0a42010-11-02 17:58:22 -0700814 entry->repeatCount, entry->downTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700815#endif
816}
817
818bool InputDispatcher::dispatchMotionLocked(
Jeff Browne20c9e02010-10-11 14:20:19 -0700819 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700820 // Preprocessing.
821 if (! entry->dispatchInProgress) {
822 entry->dispatchInProgress = true;
823 resetTargetsLocked();
824
825 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
826 }
827
Jeff Brown54a18252010-09-16 14:07:33 -0700828 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700829 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700830 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700831 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
832 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700833 return true;
834 }
835
Jeff Brownb88102f2010-09-08 11:49:43 -0700836 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
837
838 // Identify targets.
839 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700840 int32_t injectionResult;
841 if (isPointerEvent) {
842 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700843 injectionResult = findTouchedWindowTargetsLocked(currentTime,
844 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700845 } else {
846 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700847 injectionResult = findFocusedWindowTargetsLocked(currentTime,
848 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700849 }
850 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
851 return false;
852 }
853
854 setInjectionResultLocked(entry, injectionResult);
855 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
856 return true;
857 }
858
859 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700860 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700861 }
862
863 // Dispatch the motion.
864 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700865 return true;
866}
867
868
869void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
870#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800871 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700872 "action=0x%x, flags=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700873 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700874 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700875 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
876 entry->action, entry->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700877 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
878 entry->downTime);
879
880 // Print the most recent sample that we have available, this may change due to batching.
881 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700882 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700883 for (; sample->next != NULL; sample = sample->next) {
884 sampleCount += 1;
885 }
886 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -0700887 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700888 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700889 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700890 i, entry->pointerIds[i],
Jeff Brown8d608662010-08-30 03:02:23 -0700891 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
892 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
893 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
894 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
895 sample->pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700896 }
897
898 // Keep in mind that due to batching, it is possible for the number of samples actually
899 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700900 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700901 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
902 }
903#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700904}
905
906void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
907 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
908#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -0700909 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700910 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700911 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700912#endif
913
Jeff Brown9c3cda02010-06-15 01:31:58 -0700914 assert(eventEntry->dispatchInProgress); // should already have been set to true
915
Jeff Browne2fe69e2010-10-18 13:21:23 -0700916 pokeUserActivityLocked(eventEntry);
917
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700918 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
919 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
920
Jeff Brown519e0242010-09-15 15:18:56 -0700921 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700922 if (connectionIndex >= 0) {
923 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700924 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700925 resumeWithAppendedMotionSample);
926 } else {
Jeff Brownb6997262010-10-08 22:31:17 -0700927#if DEBUG_FOCUS
928 LOGD("Dropping event delivery to target with channel '%s' because it "
929 "is no longer registered with the input dispatcher.",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700930 inputTarget.inputChannel->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -0700931#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700932 }
933 }
934}
935
Jeff Brown54a18252010-09-16 14:07:33 -0700936void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700937 mCurrentInputTargetsValid = false;
938 mCurrentInputTargets.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700939 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Jeff Brown928e0542011-01-10 11:17:36 -0800940 mInputTargetWaitApplication.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700941}
942
Jeff Brown01ce2e92010-09-26 22:20:12 -0700943void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700944 mCurrentInputTargetsValid = true;
945}
946
947int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
948 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
949 nsecs_t* nextWakeupTime) {
950 if (application == NULL && window == NULL) {
951 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
952#if DEBUG_FOCUS
953 LOGD("Waiting for system to become ready for input.");
954#endif
955 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
956 mInputTargetWaitStartTime = currentTime;
957 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
958 mInputTargetWaitTimeoutExpired = false;
Jeff Brown928e0542011-01-10 11:17:36 -0800959 mInputTargetWaitApplication.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700960 }
961 } else {
962 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
963#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700964 LOGD("Waiting for application to become ready for input: %s",
965 getApplicationWindowLabelLocked(application, window).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700966#endif
967 nsecs_t timeout = window ? window->dispatchingTimeout :
968 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
969
970 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
971 mInputTargetWaitStartTime = currentTime;
972 mInputTargetWaitTimeoutTime = currentTime + timeout;
973 mInputTargetWaitTimeoutExpired = false;
Jeff Brown928e0542011-01-10 11:17:36 -0800974 mInputTargetWaitApplication.clear();
975
976 if (window && window->inputWindowHandle != NULL) {
977 mInputTargetWaitApplication =
978 window->inputWindowHandle->getInputApplicationHandle();
979 }
980 if (mInputTargetWaitApplication == NULL && application) {
981 mInputTargetWaitApplication = application->inputApplicationHandle;
982 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700983 }
984 }
985
986 if (mInputTargetWaitTimeoutExpired) {
987 return INPUT_EVENT_INJECTION_TIMED_OUT;
988 }
989
990 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown519e0242010-09-15 15:18:56 -0700991 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700992
993 // Force poll loop to wake up immediately on next iteration once we get the
994 // ANR response back from the policy.
995 *nextWakeupTime = LONG_LONG_MIN;
996 return INPUT_EVENT_INJECTION_PENDING;
997 } else {
998 // Force poll loop to wake up when timeout is due.
999 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1000 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1001 }
1002 return INPUT_EVENT_INJECTION_PENDING;
1003 }
1004}
1005
Jeff Brown519e0242010-09-15 15:18:56 -07001006void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1007 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001008 if (newTimeout > 0) {
1009 // Extend the timeout.
1010 mInputTargetWaitTimeoutTime = now() + newTimeout;
1011 } else {
1012 // Give up.
1013 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -07001014
Jeff Brown01ce2e92010-09-26 22:20:12 -07001015 // Release the touch targets.
1016 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07001017
Jeff Brown519e0242010-09-15 15:18:56 -07001018 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -07001019 if (inputChannel.get()) {
1020 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1021 if (connectionIndex >= 0) {
1022 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown00045a72010-12-09 18:10:30 -08001023 if (connection->status == Connection::STATUS_NORMAL) {
1024 synthesizeCancelationEventsForConnectionLocked(
1025 connection, InputState::CANCEL_ALL_EVENTS,
1026 "application not responding");
1027 }
Jeff Browndc3e0052010-09-16 11:02:16 -07001028 }
Jeff Brown519e0242010-09-15 15:18:56 -07001029 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001030 }
1031}
1032
Jeff Brown519e0242010-09-15 15:18:56 -07001033nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -07001034 nsecs_t currentTime) {
1035 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1036 return currentTime - mInputTargetWaitStartTime;
1037 }
1038 return 0;
1039}
1040
1041void InputDispatcher::resetANRTimeoutsLocked() {
1042#if DEBUG_FOCUS
1043 LOGD("Resetting ANR timeouts.");
1044#endif
1045
Jeff Brownb88102f2010-09-08 11:49:43 -07001046 // Reset input target wait timeout.
1047 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
1048}
1049
Jeff Brown01ce2e92010-09-26 22:20:12 -07001050int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
1051 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001052 mCurrentInputTargets.clear();
1053
1054 int32_t injectionResult;
1055
1056 // If there is no currently focused window and no focused application
1057 // then drop the event.
1058 if (! mFocusedWindow) {
1059 if (mFocusedApplication) {
1060#if DEBUG_FOCUS
1061 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001062 "focused application that may eventually add a window: %s.",
1063 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001064#endif
1065 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1066 mFocusedApplication, NULL, nextWakeupTime);
1067 goto Unresponsive;
1068 }
1069
1070 LOGI("Dropping event because there is no focused window or focused application.");
1071 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1072 goto Failed;
1073 }
1074
1075 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001076 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001077 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1078 goto Failed;
1079 }
1080
1081 // If the currently focused window is paused then keep waiting.
1082 if (mFocusedWindow->paused) {
1083#if DEBUG_FOCUS
1084 LOGD("Waiting because focused window is paused.");
1085#endif
1086 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1087 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1088 goto Unresponsive;
1089 }
1090
Jeff Brown519e0242010-09-15 15:18:56 -07001091 // If the currently focused window is still working on previous events then keep waiting.
1092 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
1093#if DEBUG_FOCUS
1094 LOGD("Waiting because focused window still processing previous input.");
1095#endif
1096 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1097 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1098 goto Unresponsive;
1099 }
1100
Jeff Brownb88102f2010-09-08 11:49:43 -07001101 // Success! Output targets.
1102 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001103 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001104
1105 // Done.
1106Failed:
1107Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001108 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1109 updateDispatchStatisticsLocked(currentTime, entry,
1110 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001111#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -07001112 LOGD("findFocusedWindow finished: injectionResult=%d, "
1113 "timeSpendWaitingForApplication=%0.1fms",
1114 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001115#endif
1116 return injectionResult;
1117}
1118
Jeff Brown01ce2e92010-09-26 22:20:12 -07001119int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1120 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001121 enum InjectionPermission {
1122 INJECTION_PERMISSION_UNKNOWN,
1123 INJECTION_PERMISSION_GRANTED,
1124 INJECTION_PERMISSION_DENIED
1125 };
1126
Jeff Brownb88102f2010-09-08 11:49:43 -07001127 mCurrentInputTargets.clear();
1128
1129 nsecs_t startTime = now();
1130
1131 // For security reasons, we defer updating the touch state until we are sure that
1132 // event injection will be allowed.
1133 //
1134 // FIXME In the original code, screenWasOff could never be set to true.
1135 // The reason is that the POLICY_FLAG_WOKE_HERE
1136 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1137 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1138 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1139 // events upon which no preprocessing took place. So policyFlags was always 0.
1140 // In the new native input dispatcher we're a bit more careful about event
1141 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1142 // Unfortunately we obtain undesirable behavior.
1143 //
1144 // Here's what happens:
1145 //
1146 // When the device dims in anticipation of going to sleep, touches
1147 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1148 // the device to brighten and reset the user activity timer.
1149 // Touches on other windows (such as the launcher window)
1150 // are dropped. Then after a moment, the device goes to sleep. Oops.
1151 //
1152 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1153 // instead of POLICY_FLAG_WOKE_HERE...
1154 //
1155 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1156
1157 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001158 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001159
1160 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001161 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1162 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Jeff Brown95712852011-01-04 19:41:59 -08001163 bool isSplit, wrongDevice;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001164 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1165 mTempTouchState.reset();
1166 mTempTouchState.down = true;
Jeff Brown95712852011-01-04 19:41:59 -08001167 mTempTouchState.deviceId = entry->deviceId;
1168 isSplit = false;
1169 wrongDevice = false;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001170 } else {
1171 mTempTouchState.copyFrom(mTouchState);
Jeff Brown95712852011-01-04 19:41:59 -08001172 isSplit = mTempTouchState.split;
1173 wrongDevice = mTempTouchState.down && mTempTouchState.deviceId != entry->deviceId;
1174 if (wrongDevice) {
1175#if DEBUG_INPUT_DISPATCHER_POLICY
1176 LOGD("Dropping event because a pointer for a different device is already down.");
1177#endif
1178 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1179 goto Failed;
1180 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001181 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001182
Jeff Brown01ce2e92010-09-26 22:20:12 -07001183 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1184 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1185 /* Case 1: New splittable pointer going down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001186
Jeff Brown01ce2e92010-09-26 22:20:12 -07001187 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1188 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1189 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1190 const InputWindow* newTouchedWindow = NULL;
1191 const InputWindow* topErrorWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07001192
1193 // Traverse windows from front to back to find touched window and outside targets.
1194 size_t numWindows = mWindows.size();
1195 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001196 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001197 int32_t flags = window->layoutParamsFlags;
1198
1199 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1200 if (! topErrorWindow) {
1201 topErrorWindow = window;
1202 }
1203 }
1204
1205 if (window->visible) {
1206 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1207 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1208 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
Jeff Brownfbf09772011-01-16 14:06:57 -08001209 if (isTouchModal || window->touchableRegionContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001210 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1211 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001212 }
1213 break; // found touched window, exit window loop
1214 }
1215 }
1216
Jeff Brown01ce2e92010-09-26 22:20:12 -07001217 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1218 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001219 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1220 if (isWindowObscuredAtPointLocked(window, x, y)) {
1221 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1222 }
1223
1224 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001225 }
1226 }
1227 }
1228
1229 // If there is an error window but it is not taking focus (typically because
1230 // it is invisible) then wait for it. Any other focused window may in
1231 // fact be in ANR state.
1232 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1233#if DEBUG_FOCUS
1234 LOGD("Waiting because system error window is pending.");
1235#endif
1236 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1237 NULL, NULL, nextWakeupTime);
1238 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1239 goto Unresponsive;
1240 }
1241
Jeff Brown01ce2e92010-09-26 22:20:12 -07001242 // Figure out whether splitting will be allowed for this window.
Jeff Brown46e75292010-11-10 16:53:45 -08001243 if (newTouchedWindow && newTouchedWindow->supportsSplitTouch()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001244 // New window supports splitting.
1245 isSplit = true;
1246 } else if (isSplit) {
1247 // New window does not support splitting but we have already split events.
1248 // Assign the pointer to the first foreground window we find.
1249 // (May be NULL which is why we put this code block before the next check.)
1250 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1251 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001252
Jeff Brownb88102f2010-09-08 11:49:43 -07001253 // If we did not find a touched window then fail.
1254 if (! newTouchedWindow) {
1255 if (mFocusedApplication) {
1256#if DEBUG_FOCUS
1257 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001258 "focused application that may eventually add a new window: %s.",
1259 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001260#endif
1261 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1262 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001263 goto Unresponsive;
1264 }
1265
1266 LOGI("Dropping event because there is no touched window or focused application.");
1267 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001268 goto Failed;
1269 }
1270
Jeff Brown19dfc832010-10-05 12:26:23 -07001271 // Set target flags.
1272 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1273 if (isSplit) {
1274 targetFlags |= InputTarget::FLAG_SPLIT;
1275 }
1276 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1277 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1278 }
1279
Jeff Brown01ce2e92010-09-26 22:20:12 -07001280 // Update the temporary touch state.
1281 BitSet32 pointerIds;
1282 if (isSplit) {
1283 uint32_t pointerId = entry->pointerIds[pointerIndex];
1284 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001285 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001286 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001287 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001288 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001289
1290 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001291 if (! mTempTouchState.down) {
Jeff Brown76860e32010-10-25 17:37:46 -07001292#if DEBUG_INPUT_DISPATCHER_POLICY
1293 LOGD("Dropping event because the pointer is not down or we previously "
1294 "dropped the pointer down event.");
1295#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001296 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001297 goto Failed;
1298 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001299 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001300
Jeff Brown01ce2e92010-09-26 22:20:12 -07001301 // Check permission to inject into all touched foreground windows and ensure there
1302 // is at least one touched foreground window.
1303 {
1304 bool haveForegroundWindow = false;
1305 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1306 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1307 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1308 haveForegroundWindow = true;
1309 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1310 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1311 injectionPermission = INJECTION_PERMISSION_DENIED;
1312 goto Failed;
1313 }
1314 }
1315 }
1316 if (! haveForegroundWindow) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001317#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown01ce2e92010-09-26 22:20:12 -07001318 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001319#endif
1320 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001321 goto Failed;
1322 }
1323
Jeff Brown01ce2e92010-09-26 22:20:12 -07001324 // Permission granted to injection into all touched foreground windows.
1325 injectionPermission = INJECTION_PERMISSION_GRANTED;
1326 }
Jeff Brown519e0242010-09-15 15:18:56 -07001327
Jeff Brown01ce2e92010-09-26 22:20:12 -07001328 // Ensure all touched foreground windows are ready for new input.
1329 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1330 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1331 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1332 // If the touched window is paused then keep waiting.
1333 if (touchedWindow.window->paused) {
1334#if DEBUG_INPUT_DISPATCHER_POLICY
1335 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001336#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001337 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1338 NULL, touchedWindow.window, nextWakeupTime);
1339 goto Unresponsive;
1340 }
1341
1342 // If the touched window is still working on previous events then keep waiting.
1343 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1344#if DEBUG_FOCUS
1345 LOGD("Waiting because touched window still processing previous input.");
1346#endif
1347 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1348 NULL, touchedWindow.window, nextWakeupTime);
1349 goto Unresponsive;
1350 }
1351 }
1352 }
1353
1354 // If this is the first pointer going down and the touched window has a wallpaper
1355 // then also add the touched wallpaper windows so they are locked in for the duration
1356 // of the touch gesture.
1357 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1358 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1359 if (foregroundWindow->hasWallpaper) {
1360 for (size_t i = 0; i < mWindows.size(); i++) {
1361 const InputWindow* window = & mWindows[i];
1362 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001363 mTempTouchState.addOrUpdateWindow(window,
1364 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001365 }
1366 }
1367 }
1368 }
1369
Jeff Brownb88102f2010-09-08 11:49:43 -07001370 // Success! Output targets.
1371 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001372
Jeff Brown01ce2e92010-09-26 22:20:12 -07001373 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1374 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1375 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1376 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001377 }
1378
Jeff Brown01ce2e92010-09-26 22:20:12 -07001379 // Drop the outside touch window since we will not care about them in the next iteration.
1380 mTempTouchState.removeOutsideTouchWindows();
1381
Jeff Brownb88102f2010-09-08 11:49:43 -07001382Failed:
1383 // Check injection permission once and for all.
1384 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001385 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001386 injectionPermission = INJECTION_PERMISSION_GRANTED;
1387 } else {
1388 injectionPermission = INJECTION_PERMISSION_DENIED;
1389 }
1390 }
1391
1392 // Update final pieces of touch state if the injector had permission.
1393 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown95712852011-01-04 19:41:59 -08001394 if (!wrongDevice) {
1395 if (maskedAction == AMOTION_EVENT_ACTION_UP
1396 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1397 // All pointers up or canceled.
1398 mTempTouchState.reset();
1399 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1400 // First pointer went down.
1401 if (mTouchState.down) {
Jeff Brownb6997262010-10-08 22:31:17 -07001402#if DEBUG_FOCUS
Jeff Brown95712852011-01-04 19:41:59 -08001403 LOGD("Pointer down received while already down.");
Jeff Brownb6997262010-10-08 22:31:17 -07001404#endif
Jeff Brown95712852011-01-04 19:41:59 -08001405 }
1406 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1407 // One pointer went up.
1408 if (isSplit) {
1409 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1410 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001411
Jeff Brown95712852011-01-04 19:41:59 -08001412 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1413 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1414 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1415 touchedWindow.pointerIds.clearBit(pointerId);
1416 if (touchedWindow.pointerIds.isEmpty()) {
1417 mTempTouchState.windows.removeAt(i);
1418 continue;
1419 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001420 }
Jeff Brown95712852011-01-04 19:41:59 -08001421 i += 1;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001422 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001423 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001424 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001425
Jeff Brown95712852011-01-04 19:41:59 -08001426 // Save changes to touch state.
1427 mTouchState.copyFrom(mTempTouchState);
1428 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001429 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001430#if DEBUG_FOCUS
1431 LOGD("Not updating touch focus because injection was denied.");
1432#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001433 }
1434
1435Unresponsive:
Jeff Brown120a4592010-10-27 18:43:51 -07001436 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1437 mTempTouchState.reset();
1438
Jeff Brown519e0242010-09-15 15:18:56 -07001439 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1440 updateDispatchStatisticsLocked(currentTime, entry,
1441 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001442#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001443 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1444 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001445 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001446#endif
1447 return injectionResult;
1448}
1449
Jeff Brown01ce2e92010-09-26 22:20:12 -07001450void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1451 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001452 mCurrentInputTargets.push();
1453
1454 InputTarget& target = mCurrentInputTargets.editTop();
1455 target.inputChannel = window->inputChannel;
1456 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001457 target.xOffset = - window->frameLeft;
1458 target.yOffset = - window->frameTop;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001459 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001460}
1461
1462void InputDispatcher::addMonitoringTargetsLocked() {
1463 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1464 mCurrentInputTargets.push();
1465
1466 InputTarget& target = mCurrentInputTargets.editTop();
1467 target.inputChannel = mMonitoringChannels[i];
1468 target.flags = 0;
Jeff Brownb88102f2010-09-08 11:49:43 -07001469 target.xOffset = 0;
1470 target.yOffset = 0;
1471 }
1472}
1473
1474bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001475 const InjectionState* injectionState) {
1476 if (injectionState
Jeff Brownb6997262010-10-08 22:31:17 -07001477 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1478 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1479 if (window) {
1480 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1481 "with input channel %s owned by uid %d",
1482 injectionState->injectorPid, injectionState->injectorUid,
1483 window->inputChannel->getName().string(),
1484 window->ownerUid);
1485 } else {
1486 LOGW("Permission denied: injecting event from pid %d uid %d",
1487 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001488 }
Jeff Brownb6997262010-10-08 22:31:17 -07001489 return false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001490 }
1491 return true;
1492}
1493
Jeff Brown19dfc832010-10-05 12:26:23 -07001494bool InputDispatcher::isWindowObscuredAtPointLocked(
1495 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07001496 size_t numWindows = mWindows.size();
1497 for (size_t i = 0; i < numWindows; i++) {
1498 const InputWindow* other = & mWindows.itemAt(i);
1499 if (other == window) {
1500 break;
1501 }
Jeff Brown19dfc832010-10-05 12:26:23 -07001502 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001503 return true;
1504 }
1505 }
1506 return false;
1507}
1508
Jeff Brown519e0242010-09-15 15:18:56 -07001509bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1510 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1511 if (connectionIndex >= 0) {
1512 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1513 return connection->outboundQueue.isEmpty();
1514 } else {
1515 return true;
1516 }
1517}
1518
1519String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1520 const InputWindow* window) {
1521 if (application) {
1522 if (window) {
1523 String8 label(application->name);
1524 label.append(" - ");
1525 label.append(window->name);
1526 return label;
1527 } else {
1528 return application->name;
1529 }
1530 } else if (window) {
1531 return window->name;
1532 } else {
1533 return String8("<unknown application or window>");
1534 }
1535}
1536
Jeff Browne2fe69e2010-10-18 13:21:23 -07001537void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1538 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brown4d396052010-10-29 21:50:21 -07001539 switch (eventEntry->type) {
1540 case EventEntry::TYPE_MOTION: {
Jeff Browne2fe69e2010-10-18 13:21:23 -07001541 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Brown4d396052010-10-29 21:50:21 -07001542 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1543 return;
1544 }
1545
Jeff Browne2fe69e2010-10-18 13:21:23 -07001546 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
Joe Onorato1a542c72010-11-08 09:48:20 -08001547 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001548 }
Jeff Brown4d396052010-10-29 21:50:21 -07001549 break;
1550 }
1551 case EventEntry::TYPE_KEY: {
1552 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1553 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1554 return;
1555 }
1556 break;
1557 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001558 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001559
Jeff Brownb88102f2010-09-08 11:49:43 -07001560 CommandEntry* commandEntry = postCommandLocked(
1561 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Browne2fe69e2010-10-18 13:21:23 -07001562 commandEntry->eventTime = eventEntry->eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001563 commandEntry->userActivityEventType = eventType;
1564}
1565
Jeff Brown7fbdc842010-06-17 20:52:56 -07001566void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1567 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001568 bool resumeWithAppendedMotionSample) {
1569#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001570 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001571 "xOffset=%f, yOffset=%f, "
Jeff Brown83c09682010-12-23 17:50:18 -08001572 "pointerIds=0x%x, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001573 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001574 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001575 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brown83c09682010-12-23 17:50:18 -08001576 inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001577 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001578#endif
1579
Jeff Brown01ce2e92010-09-26 22:20:12 -07001580 // Make sure we are never called for streaming when splitting across multiple windows.
1581 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1582 assert(! (resumeWithAppendedMotionSample && isSplit));
1583
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001584 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001585 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001586 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb6997262010-10-08 22:31:17 -07001587#if DEBUG_DISPATCH_CYCLE
1588 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001589 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brownb6997262010-10-08 22:31:17 -07001590#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001591 return;
1592 }
1593
Jeff Brown01ce2e92010-09-26 22:20:12 -07001594 // Split a motion event if needed.
1595 if (isSplit) {
1596 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1597
1598 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1599 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1600 MotionEntry* splitMotionEntry = splitMotionEvent(
1601 originalMotionEntry, inputTarget->pointerIds);
1602#if DEBUG_FOCUS
1603 LOGD("channel '%s' ~ Split motion event.",
1604 connection->getInputChannelName());
1605 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1606#endif
1607 eventEntry = splitMotionEntry;
1608 }
1609 }
1610
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001611 // Resume the dispatch cycle with a freshly appended motion sample.
1612 // First we check that the last dispatch entry in the outbound queue is for the same
1613 // motion event to which we appended the motion sample. If we find such a dispatch
1614 // entry, and if it is currently in progress then we try to stream the new sample.
1615 bool wasEmpty = connection->outboundQueue.isEmpty();
1616
1617 if (! wasEmpty && resumeWithAppendedMotionSample) {
1618 DispatchEntry* motionEventDispatchEntry =
1619 connection->findQueuedDispatchEntryForEvent(eventEntry);
1620 if (motionEventDispatchEntry) {
1621 // If the dispatch entry is not in progress, then we must be busy dispatching an
1622 // earlier event. Not a problem, the motion event is on the outbound queue and will
1623 // be dispatched later.
1624 if (! motionEventDispatchEntry->inProgress) {
1625#if DEBUG_BATCHING
1626 LOGD("channel '%s' ~ Not streaming because the motion event has "
1627 "not yet been dispatched. "
1628 "(Waiting for earlier events to be consumed.)",
1629 connection->getInputChannelName());
1630#endif
1631 return;
1632 }
1633
1634 // If the dispatch entry is in progress but it already has a tail of pending
1635 // motion samples, then it must mean that the shared memory buffer filled up.
1636 // Not a problem, when this dispatch cycle is finished, we will eventually start
1637 // a new dispatch cycle to process the tail and that tail includes the newly
1638 // appended motion sample.
1639 if (motionEventDispatchEntry->tailMotionSample) {
1640#if DEBUG_BATCHING
1641 LOGD("channel '%s' ~ Not streaming because no new samples can "
1642 "be appended to the motion event in this dispatch cycle. "
1643 "(Waiting for next dispatch cycle to start.)",
1644 connection->getInputChannelName());
1645#endif
1646 return;
1647 }
1648
1649 // The dispatch entry is in progress and is still potentially open for streaming.
1650 // Try to stream the new motion sample. This might fail if the consumer has already
1651 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001652 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1653 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001654 status_t status = connection->inputPublisher.appendMotionSample(
1655 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1656 if (status == OK) {
1657#if DEBUG_BATCHING
1658 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1659 connection->getInputChannelName());
1660#endif
1661 return;
1662 }
1663
1664#if DEBUG_BATCHING
1665 if (status == NO_MEMORY) {
1666 LOGD("channel '%s' ~ Could not append motion sample to currently "
1667 "dispatched move event because the shared memory buffer is full. "
1668 "(Waiting for next dispatch cycle to start.)",
1669 connection->getInputChannelName());
1670 } else if (status == status_t(FAILED_TRANSACTION)) {
1671 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001672 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001673 "(Waiting for next dispatch cycle to start.)",
1674 connection->getInputChannelName());
1675 } else {
1676 LOGD("channel '%s' ~ Could not append motion sample to currently "
1677 "dispatched move event due to an error, status=%d. "
1678 "(Waiting for next dispatch cycle to start.)",
1679 connection->getInputChannelName(), status);
1680 }
1681#endif
1682 // Failed to stream. Start a new tail of pending motion samples to dispatch
1683 // in the next cycle.
1684 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1685 return;
1686 }
1687 }
1688
1689 // This is a new event.
1690 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001691 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown519e0242010-09-15 15:18:56 -07001692 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1693 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001694 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001695 }
1696
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001697 // Handle the case where we could not stream a new motion sample because the consumer has
1698 // already consumed the motion event (otherwise the corresponding dispatch entry would
1699 // still be in the outbound queue for this connection). We set the head motion sample
1700 // to the list starting with the newly appended motion sample.
1701 if (resumeWithAppendedMotionSample) {
1702#if DEBUG_BATCHING
1703 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1704 "that cannot be streamed because the motion event has already been consumed.",
1705 connection->getInputChannelName());
1706#endif
1707 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1708 dispatchEntry->headMotionSample = appendedMotionSample;
1709 }
1710
1711 // Enqueue the dispatch entry.
1712 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1713
1714 // If the outbound queue was previously empty, start the dispatch cycle going.
1715 if (wasEmpty) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001716 activateConnectionLocked(connection.get());
Jeff Brown519e0242010-09-15 15:18:56 -07001717 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001718 }
1719}
1720
Jeff Brown7fbdc842010-06-17 20:52:56 -07001721void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001722 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001723#if DEBUG_DISPATCH_CYCLE
1724 LOGD("channel '%s' ~ startDispatchCycle",
1725 connection->getInputChannelName());
1726#endif
1727
1728 assert(connection->status == Connection::STATUS_NORMAL);
1729 assert(! connection->outboundQueue.isEmpty());
1730
Jeff Brownb88102f2010-09-08 11:49:43 -07001731 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001732 assert(! dispatchEntry->inProgress);
1733
Jeff Brownb88102f2010-09-08 11:49:43 -07001734 // Mark the dispatch entry as in progress.
1735 dispatchEntry->inProgress = true;
1736
1737 // Update the connection's input state.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001738 EventEntry* eventEntry = dispatchEntry->eventEntry;
1739 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001740
1741#if FILTER_INPUT_EVENTS
1742 // Filter out inconsistent sequences of input events.
1743 // The input system may drop or inject events in a way that could violate implicit
1744 // invariants on input state and potentially cause an application to crash
1745 // or think that a key or pointer is stuck down. Technically we make no guarantees
1746 // of consistency but it would be nice to improve on this where possible.
1747 // XXX: This code is a proof of concept only. Not ready for prime time.
1748 if (consistency == InputState::TOLERABLE) {
1749#if DEBUG_DISPATCH_CYCLE
1750 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1751 "current input state but that is likely to be tolerated by the application.",
1752 connection->getInputChannelName());
1753#endif
1754 } else if (consistency == InputState::BROKEN) {
1755 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1756 "current input state and that is likely to cause the application to crash.",
1757 connection->getInputChannelName());
1758 startNextDispatchCycleLocked(currentTime, connection);
1759 return;
1760 }
1761#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001762
1763 // Publish the event.
1764 status_t status;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001765 switch (eventEntry->type) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001766 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001767 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001768
1769 // Apply target flags.
1770 int32_t action = keyEntry->action;
1771 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001772
1773 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001774 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001775 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1776 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1777 keyEntry->eventTime);
1778
1779 if (status) {
1780 LOGE("channel '%s' ~ Could not publish key event, "
1781 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001782 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001783 return;
1784 }
1785 break;
1786 }
1787
1788 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001789 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001790
1791 // Apply target flags.
1792 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001793 int32_t flags = motionEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001794 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001795 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001796 }
Jeff Brown85a31762010-09-01 17:01:00 -07001797 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1798 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1799 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001800
1801 // If headMotionSample is non-NULL, then it points to the first new sample that we
1802 // were unable to dispatch during the previous cycle so we resume dispatching from
1803 // that point in the list of motion samples.
1804 // Otherwise, we just start from the first sample of the motion event.
1805 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1806 if (! firstMotionSample) {
1807 firstMotionSample = & motionEntry->firstSample;
1808 }
1809
Jeff Brownd3616592010-07-16 17:21:06 -07001810 // Set the X and Y offset depending on the input source.
1811 float xOffset, yOffset;
1812 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1813 xOffset = dispatchEntry->xOffset;
1814 yOffset = dispatchEntry->yOffset;
1815 } else {
1816 xOffset = 0.0f;
1817 yOffset = 0.0f;
1818 }
1819
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001820 // Publish the motion event and the first motion sample.
1821 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07001822 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownd3616592010-07-16 17:21:06 -07001823 xOffset, yOffset,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001824 motionEntry->xPrecision, motionEntry->yPrecision,
1825 motionEntry->downTime, firstMotionSample->eventTime,
1826 motionEntry->pointerCount, motionEntry->pointerIds,
1827 firstMotionSample->pointerCoords);
1828
1829 if (status) {
1830 LOGE("channel '%s' ~ Could not publish motion event, "
1831 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001832 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001833 return;
1834 }
1835
1836 // Append additional motion samples.
1837 MotionSample* nextMotionSample = firstMotionSample->next;
1838 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1839 status = connection->inputPublisher.appendMotionSample(
1840 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1841 if (status == NO_MEMORY) {
1842#if DEBUG_DISPATCH_CYCLE
1843 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1844 "be sent in the next dispatch cycle.",
1845 connection->getInputChannelName());
1846#endif
1847 break;
1848 }
1849 if (status != OK) {
1850 LOGE("channel '%s' ~ Could not append motion sample "
1851 "for a reason other than out of memory, status=%d",
1852 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001853 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001854 return;
1855 }
1856 }
1857
1858 // Remember the next motion sample that we could not dispatch, in case we ran out
1859 // of space in the shared memory buffer.
1860 dispatchEntry->tailMotionSample = nextMotionSample;
1861 break;
1862 }
1863
1864 default: {
1865 assert(false);
1866 }
1867 }
1868
1869 // Send the dispatch signal.
1870 status = connection->inputPublisher.sendDispatchSignal();
1871 if (status) {
1872 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1873 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001874 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001875 return;
1876 }
1877
1878 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001879 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001880 connection->lastDispatchTime = currentTime;
1881
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001882 // Notify other system components.
1883 onDispatchCycleStartedLocked(currentTime, connection);
1884}
1885
Jeff Brown7fbdc842010-06-17 20:52:56 -07001886void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown3915bb82010-11-05 15:02:16 -07001887 const sp<Connection>& connection, bool handled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001888#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001889 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown3915bb82010-11-05 15:02:16 -07001890 "%01.1fms since dispatch, handled=%s",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001891 connection->getInputChannelName(),
1892 connection->getEventLatencyMillis(currentTime),
Jeff Brown3915bb82010-11-05 15:02:16 -07001893 connection->getDispatchLatencyMillis(currentTime),
1894 toString(handled));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001895#endif
1896
Jeff Brown9c3cda02010-06-15 01:31:58 -07001897 if (connection->status == Connection::STATUS_BROKEN
1898 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001899 return;
1900 }
1901
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001902 // Reset the publisher since the event has been consumed.
1903 // We do this now so that the publisher can release some of its internal resources
1904 // while waiting for the next dispatch cycle to begin.
1905 status_t status = connection->inputPublisher.reset();
1906 if (status) {
1907 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1908 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001909 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001910 return;
1911 }
1912
Jeff Brown3915bb82010-11-05 15:02:16 -07001913 // Notify other system components and prepare to start the next dispatch cycle.
1914 onDispatchCycleFinishedLocked(currentTime, connection, handled);
Jeff Brownb88102f2010-09-08 11:49:43 -07001915}
1916
1917void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1918 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001919 // Start the next dispatch cycle for this connection.
1920 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001921 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001922 if (dispatchEntry->inProgress) {
1923 // Finish or resume current event in progress.
1924 if (dispatchEntry->tailMotionSample) {
1925 // We have a tail of undispatched motion samples.
1926 // Reuse the same DispatchEntry and start a new cycle.
1927 dispatchEntry->inProgress = false;
1928 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1929 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07001930 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001931 return;
1932 }
1933 // Finished.
1934 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07001935 if (dispatchEntry->hasForegroundTarget()) {
1936 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001937 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001938 mAllocator.releaseDispatchEntry(dispatchEntry);
1939 } else {
1940 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07001941 // progress event, which means we actually aborted it.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001942 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07001943 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001944 return;
1945 }
1946 }
1947
1948 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07001949 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001950}
1951
Jeff Brownb6997262010-10-08 22:31:17 -07001952void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1953 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001954#if DEBUG_DISPATCH_CYCLE
Jeff Brown83c09682010-12-23 17:50:18 -08001955 LOGD("channel '%s' ~ abortBrokenDispatchCycle",
1956 connection->getInputChannelName());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001957#endif
1958
Jeff Brownb88102f2010-09-08 11:49:43 -07001959 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07001960 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001961
Jeff Brownb6997262010-10-08 22:31:17 -07001962 // The connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07001963 // Ignore already broken or zombie connections.
Jeff Brownb6997262010-10-08 22:31:17 -07001964 if (connection->status == Connection::STATUS_NORMAL) {
1965 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001966
Jeff Brownb6997262010-10-08 22:31:17 -07001967 // Notify other system components.
1968 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001969 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001970}
1971
Jeff Brown519e0242010-09-15 15:18:56 -07001972void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1973 while (! connection->outboundQueue.isEmpty()) {
1974 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1975 if (dispatchEntry->hasForegroundTarget()) {
1976 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001977 }
1978 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001979 }
1980
Jeff Brown519e0242010-09-15 15:18:56 -07001981 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07001982}
1983
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001984int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001985 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1986
1987 { // acquire lock
1988 AutoMutex _l(d->mLock);
1989
1990 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1991 if (connectionIndex < 0) {
1992 LOGE("Received spurious receive callback for unknown input channel. "
1993 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001994 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001995 }
1996
Jeff Brown7fbdc842010-06-17 20:52:56 -07001997 nsecs_t currentTime = now();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001998
1999 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002000 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002001 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
2002 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brownb6997262010-10-08 22:31:17 -07002003 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002004 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002005 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002006 }
2007
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002008 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002009 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
2010 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002011 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002012 }
2013
Jeff Brown3915bb82010-11-05 15:02:16 -07002014 bool handled = false;
Jeff Brown49ed71d2010-12-06 17:13:33 -08002015 status_t status = connection->inputPublisher.receiveFinishedSignal(&handled);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002016 if (status) {
2017 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
2018 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07002019 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002020 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002021 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002022 }
2023
Jeff Brown3915bb82010-11-05 15:02:16 -07002024 d->finishDispatchCycleLocked(currentTime, connection, handled);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002025 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002026 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002027 } // release lock
2028}
2029
Jeff Brownb6997262010-10-08 22:31:17 -07002030void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
2031 InputState::CancelationOptions options, const char* reason) {
2032 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
2033 synthesizeCancelationEventsForConnectionLocked(
2034 mConnectionsByReceiveFd.valueAt(i), options, reason);
2035 }
2036}
2037
2038void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2039 const sp<InputChannel>& channel, InputState::CancelationOptions options,
2040 const char* reason) {
2041 ssize_t index = getConnectionIndexLocked(channel);
2042 if (index >= 0) {
2043 synthesizeCancelationEventsForConnectionLocked(
2044 mConnectionsByReceiveFd.valueAt(index), options, reason);
2045 }
2046}
2047
2048void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2049 const sp<Connection>& connection, InputState::CancelationOptions options,
2050 const char* reason) {
2051 nsecs_t currentTime = now();
2052
2053 mTempCancelationEvents.clear();
2054 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
2055 mTempCancelationEvents, options);
2056
2057 if (! mTempCancelationEvents.isEmpty()
2058 && connection->status != Connection::STATUS_BROKEN) {
2059#if DEBUG_OUTBOUND_EVENT_DETAILS
2060 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
2061 "with reality: %s, options=%d.",
2062 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
2063#endif
2064 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
2065 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
2066 switch (cancelationEventEntry->type) {
2067 case EventEntry::TYPE_KEY:
2068 logOutboundKeyDetailsLocked("cancel - ",
2069 static_cast<KeyEntry*>(cancelationEventEntry));
2070 break;
2071 case EventEntry::TYPE_MOTION:
2072 logOutboundMotionDetailsLocked("cancel - ",
2073 static_cast<MotionEntry*>(cancelationEventEntry));
2074 break;
2075 }
2076
2077 int32_t xOffset, yOffset;
2078 const InputWindow* window = getWindowLocked(connection->inputChannel);
2079 if (window) {
2080 xOffset = -window->frameLeft;
2081 yOffset = -window->frameTop;
2082 } else {
2083 xOffset = 0;
2084 yOffset = 0;
2085 }
2086
2087 DispatchEntry* cancelationDispatchEntry =
2088 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
2089 0, xOffset, yOffset);
2090 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
2091
2092 mAllocator.releaseEventEntry(cancelationEventEntry);
2093 }
2094
2095 if (!connection->outboundQueue.headSentinel.next->inProgress) {
2096 startDispatchCycleLocked(currentTime, connection);
2097 }
2098 }
2099}
2100
Jeff Brown01ce2e92010-09-26 22:20:12 -07002101InputDispatcher::MotionEntry*
2102InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2103 assert(pointerIds.value != 0);
2104
2105 uint32_t splitPointerIndexMap[MAX_POINTERS];
2106 int32_t splitPointerIds[MAX_POINTERS];
2107 PointerCoords splitPointerCoords[MAX_POINTERS];
2108
2109 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2110 uint32_t splitPointerCount = 0;
2111
2112 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2113 originalPointerIndex++) {
2114 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
2115 if (pointerIds.hasBit(pointerId)) {
2116 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2117 splitPointerIds[splitPointerCount] = pointerId;
2118 splitPointerCoords[splitPointerCount] =
2119 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
2120 splitPointerCount += 1;
2121 }
2122 }
2123 assert(splitPointerCount == pointerIds.count());
2124
2125 int32_t action = originalMotionEntry->action;
2126 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2127 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2128 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2129 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2130 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2131 if (pointerIds.hasBit(pointerId)) {
2132 if (pointerIds.count() == 1) {
2133 // The first/last pointer went down/up.
2134 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2135 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07002136 } else {
2137 // A secondary pointer went down/up.
2138 uint32_t splitPointerIndex = 0;
2139 while (pointerId != splitPointerIds[splitPointerIndex]) {
2140 splitPointerIndex += 1;
2141 }
2142 action = maskedAction | (splitPointerIndex
2143 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002144 }
2145 } else {
2146 // An unrelated pointer changed.
2147 action = AMOTION_EVENT_ACTION_MOVE;
2148 }
2149 }
2150
2151 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2152 originalMotionEntry->eventTime,
2153 originalMotionEntry->deviceId,
2154 originalMotionEntry->source,
2155 originalMotionEntry->policyFlags,
2156 action,
2157 originalMotionEntry->flags,
2158 originalMotionEntry->metaState,
2159 originalMotionEntry->edgeFlags,
2160 originalMotionEntry->xPrecision,
2161 originalMotionEntry->yPrecision,
2162 originalMotionEntry->downTime,
2163 splitPointerCount, splitPointerIds, splitPointerCoords);
2164
2165 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2166 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2167 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2168 splitPointerIndex++) {
2169 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2170 splitPointerCoords[splitPointerIndex] =
2171 originalMotionSample->pointerCoords[originalPointerIndex];
2172 }
2173
2174 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2175 splitPointerCoords);
2176 }
2177
2178 return splitMotionEntry;
2179}
2180
Jeff Brown9c3cda02010-06-15 01:31:58 -07002181void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002182#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07002183 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002184#endif
2185
Jeff Brownb88102f2010-09-08 11:49:43 -07002186 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002187 { // acquire lock
2188 AutoMutex _l(mLock);
2189
Jeff Brown7fbdc842010-06-17 20:52:56 -07002190 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07002191 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002192 } // release lock
2193
Jeff Brownb88102f2010-09-08 11:49:43 -07002194 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002195 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002196 }
2197}
2198
Jeff Brownc5ed5912010-07-14 18:48:53 -07002199void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002200 uint32_t policyFlags, int32_t action, int32_t flags,
2201 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2202#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002203 LOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002204 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07002205 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002206 keyCode, scanCode, metaState, downTime);
2207#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002208 if (! validateKeyEvent(action)) {
2209 return;
2210 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002211
Jeff Brown1f245102010-11-18 20:53:46 -08002212 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2213 policyFlags |= POLICY_FLAG_VIRTUAL;
2214 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2215 }
2216
Jeff Browne20c9e02010-10-11 14:20:19 -07002217 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown1f245102010-11-18 20:53:46 -08002218
2219 KeyEvent event;
2220 event.initialize(deviceId, source, action, flags, keyCode, scanCode,
2221 metaState, 0, downTime, eventTime);
2222
2223 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
2224
2225 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2226 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2227 }
Jeff Brownb6997262010-10-08 22:31:17 -07002228
Jeff Brownb88102f2010-09-08 11:49:43 -07002229 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002230 { // acquire lock
2231 AutoMutex _l(mLock);
2232
Jeff Brown7fbdc842010-06-17 20:52:56 -07002233 int32_t repeatCount = 0;
2234 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002235 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002236 metaState, repeatCount, downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002237
Jeff Brownb88102f2010-09-08 11:49:43 -07002238 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002239 } // release lock
2240
Jeff Brownb88102f2010-09-08 11:49:43 -07002241 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002242 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002243 }
2244}
2245
Jeff Brownc5ed5912010-07-14 18:48:53 -07002246void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002247 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002248 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2249 float xPrecision, float yPrecision, nsecs_t downTime) {
2250#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002251 LOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002252 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2253 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2254 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002255 xPrecision, yPrecision, downTime);
2256 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002257 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002258 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002259 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002260 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown8d608662010-08-30 03:02:23 -07002261 pointerCoords[i].pressure, pointerCoords[i].size,
2262 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2263 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2264 pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002265 }
2266#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002267 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2268 return;
2269 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002270
Jeff Browne20c9e02010-10-11 14:20:19 -07002271 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002272 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2273
Jeff Brownb88102f2010-09-08 11:49:43 -07002274 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002275 { // acquire lock
2276 AutoMutex _l(mLock);
2277
2278 // Attempt batching and streaming of move events.
Jeff Brownc5ed5912010-07-14 18:48:53 -07002279 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002280 // BATCHING CASE
2281 //
2282 // Try to append a move sample to the tail of the inbound queue for this device.
2283 // Give up if we encounter a non-move motion event for this device since that
2284 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002285 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2286 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002287 if (entry->type != EventEntry::TYPE_MOTION) {
2288 // Keep looking for motion events.
2289 continue;
2290 }
2291
2292 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2293 if (motionEntry->deviceId != deviceId) {
2294 // Keep looking for this device.
2295 continue;
2296 }
2297
Jeff Brownc5ed5912010-07-14 18:48:53 -07002298 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown7fbdc842010-06-17 20:52:56 -07002299 || motionEntry->pointerCount != pointerCount
2300 || motionEntry->isInjected()) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002301 // Last motion event in the queue for this device is not compatible for
2302 // appending new samples. Stop here.
2303 goto NoBatchingOrStreaming;
2304 }
2305
2306 // The last motion event is a move and is compatible for appending.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002307 // Do the batching magic.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002308 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002309#if DEBUG_BATCHING
2310 LOGD("Appended motion sample onto batch for most recent "
2311 "motion event for this device in the inbound queue.");
2312#endif
Jeff Brown9c3cda02010-06-15 01:31:58 -07002313 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002314 }
2315
2316 // STREAMING CASE
2317 //
2318 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002319 // Search the outbound queue for the current foreground targets to find a dispatched
2320 // motion event that is still in progress. If found, then, appen the new sample to
2321 // that event and push it out to all current targets. The logic in
2322 // prepareDispatchCycleLocked takes care of the case where some targets may
2323 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002324 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002325 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2326 const InputTarget& inputTarget = mCurrentInputTargets[i];
2327 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2328 // Skip non-foreground targets. We only want to stream if there is at
2329 // least one foreground target whose dispatch is still in progress.
2330 continue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002331 }
Jeff Brown519e0242010-09-15 15:18:56 -07002332
2333 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2334 if (connectionIndex < 0) {
2335 // Connection must no longer be valid.
2336 continue;
2337 }
2338
2339 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2340 if (connection->outboundQueue.isEmpty()) {
2341 // This foreground target has an empty outbound queue.
2342 continue;
2343 }
2344
2345 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2346 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002347 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2348 || dispatchEntry->isSplit()) {
2349 // No motion event is being dispatched, or it is being split across
2350 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002351 continue;
2352 }
2353
2354 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2355 dispatchEntry->eventEntry);
2356 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2357 || motionEntry->deviceId != deviceId
2358 || motionEntry->pointerCount != pointerCount
2359 || motionEntry->isInjected()) {
2360 // The motion event is not compatible with this move.
2361 continue;
2362 }
2363
2364 // Hurray! This foreground target is currently dispatching a move event
2365 // that we can stream onto. Append the motion sample and resume dispatch.
2366 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2367#if DEBUG_BATCHING
2368 LOGD("Appended motion sample onto batch for most recently dispatched "
2369 "motion event for this device in the outbound queues. "
2370 "Attempting to stream the motion sample.");
2371#endif
2372 nsecs_t currentTime = now();
2373 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2374 true /*resumeWithAppendedMotionSample*/);
2375
2376 runCommandsLockedInterruptible();
2377 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002378 }
2379 }
2380
2381NoBatchingOrStreaming:;
2382 }
2383
2384 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002385 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002386 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002387 xPrecision, yPrecision, downTime,
2388 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002389
Jeff Brownb88102f2010-09-08 11:49:43 -07002390 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002391 } // release lock
2392
Jeff Brownb88102f2010-09-08 11:49:43 -07002393 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002394 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002395 }
2396}
2397
Jeff Brownb6997262010-10-08 22:31:17 -07002398void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2399 uint32_t policyFlags) {
2400#if DEBUG_INBOUND_EVENT_DETAILS
2401 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2402 switchCode, switchValue, policyFlags);
2403#endif
2404
Jeff Browne20c9e02010-10-11 14:20:19 -07002405 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002406 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2407}
2408
Jeff Brown7fbdc842010-06-17 20:52:56 -07002409int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002410 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002411#if DEBUG_INBOUND_EVENT_DETAILS
2412 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002413 "syncMode=%d, timeoutMillis=%d",
2414 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002415#endif
2416
2417 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Browne20c9e02010-10-11 14:20:19 -07002418
2419 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2420 if (hasInjectionPermission(injectorPid, injectorUid)) {
2421 policyFlags |= POLICY_FLAG_TRUSTED;
2422 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002423
Jeff Brownb6997262010-10-08 22:31:17 -07002424 EventEntry* injectedEntry;
2425 switch (event->getType()) {
2426 case AINPUT_EVENT_TYPE_KEY: {
2427 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2428 int32_t action = keyEvent->getAction();
2429 if (! validateKeyEvent(action)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002430 return INPUT_EVENT_INJECTION_FAILED;
2431 }
2432
Jeff Brownb6997262010-10-08 22:31:17 -07002433 int32_t flags = keyEvent->getFlags();
Jeff Brown1f245102010-11-18 20:53:46 -08002434 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2435 policyFlags |= POLICY_FLAG_VIRTUAL;
2436 }
2437
2438 mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
2439
2440 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2441 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2442 }
Jeff Brown6ec402b2010-07-28 15:48:59 -07002443
Jeff Brownb6997262010-10-08 22:31:17 -07002444 mLock.lock();
Jeff Brown1f245102010-11-18 20:53:46 -08002445 injectedEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
2446 keyEvent->getDeviceId(), keyEvent->getSource(),
2447 policyFlags, action, flags,
2448 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
Jeff Brownb6997262010-10-08 22:31:17 -07002449 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2450 break;
2451 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002452
Jeff Brownb6997262010-10-08 22:31:17 -07002453 case AINPUT_EVENT_TYPE_MOTION: {
2454 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2455 int32_t action = motionEvent->getAction();
2456 size_t pointerCount = motionEvent->getPointerCount();
2457 const int32_t* pointerIds = motionEvent->getPointerIds();
2458 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2459 return INPUT_EVENT_INJECTION_FAILED;
2460 }
2461
2462 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Browne20c9e02010-10-11 14:20:19 -07002463 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002464
2465 mLock.lock();
2466 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2467 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2468 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2469 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2470 action, motionEvent->getFlags(),
2471 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2472 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2473 motionEvent->getDownTime(), uint32_t(pointerCount),
2474 pointerIds, samplePointerCoords);
2475 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2476 sampleEventTimes += 1;
2477 samplePointerCoords += pointerCount;
2478 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2479 }
2480 injectedEntry = motionEntry;
2481 break;
2482 }
2483
2484 default:
2485 LOGW("Cannot inject event of type %d", event->getType());
2486 return INPUT_EVENT_INJECTION_FAILED;
2487 }
2488
2489 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2490 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2491 injectionState->injectionIsAsync = true;
2492 }
2493
2494 injectionState->refCount += 1;
2495 injectedEntry->injectionState = injectionState;
2496
2497 bool needWake = enqueueInboundEventLocked(injectedEntry);
2498 mLock.unlock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002499
Jeff Brownb88102f2010-09-08 11:49:43 -07002500 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002501 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002502 }
2503
2504 int32_t injectionResult;
2505 { // acquire lock
2506 AutoMutex _l(mLock);
2507
Jeff Brown6ec402b2010-07-28 15:48:59 -07002508 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2509 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2510 } else {
2511 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002512 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002513 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2514 break;
2515 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002516
Jeff Brown7fbdc842010-06-17 20:52:56 -07002517 nsecs_t remainingTimeout = endTime - now();
2518 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002519#if DEBUG_INJECTION
2520 LOGD("injectInputEvent - Timed out waiting for injection result "
2521 "to become available.");
2522#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002523 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2524 break;
2525 }
2526
Jeff Brown6ec402b2010-07-28 15:48:59 -07002527 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2528 }
2529
2530 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2531 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002532 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002533#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002534 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002535 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002536#endif
2537 nsecs_t remainingTimeout = endTime - now();
2538 if (remainingTimeout <= 0) {
2539#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002540 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002541 "dispatches to finish.");
2542#endif
2543 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2544 break;
2545 }
2546
2547 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2548 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002549 }
2550 }
2551
Jeff Brown01ce2e92010-09-26 22:20:12 -07002552 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002553 } // release lock
2554
Jeff Brown6ec402b2010-07-28 15:48:59 -07002555#if DEBUG_INJECTION
2556 LOGD("injectInputEvent - Finished with result %d. "
2557 "injectorPid=%d, injectorUid=%d",
2558 injectionResult, injectorPid, injectorUid);
2559#endif
2560
Jeff Brown7fbdc842010-06-17 20:52:56 -07002561 return injectionResult;
2562}
2563
Jeff Brownb6997262010-10-08 22:31:17 -07002564bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2565 return injectorUid == 0
2566 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2567}
2568
Jeff Brown7fbdc842010-06-17 20:52:56 -07002569void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002570 InjectionState* injectionState = entry->injectionState;
2571 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002572#if DEBUG_INJECTION
2573 LOGD("Setting input event injection result to %d. "
2574 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002575 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002576#endif
2577
Jeff Brown01ce2e92010-09-26 22:20:12 -07002578 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002579 // Log the outcome since the injector did not wait for the injection result.
2580 switch (injectionResult) {
2581 case INPUT_EVENT_INJECTION_SUCCEEDED:
2582 LOGV("Asynchronous input event injection succeeded.");
2583 break;
2584 case INPUT_EVENT_INJECTION_FAILED:
2585 LOGW("Asynchronous input event injection failed.");
2586 break;
2587 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2588 LOGW("Asynchronous input event injection permission denied.");
2589 break;
2590 case INPUT_EVENT_INJECTION_TIMED_OUT:
2591 LOGW("Asynchronous input event injection timed out.");
2592 break;
2593 }
2594 }
2595
Jeff Brown01ce2e92010-09-26 22:20:12 -07002596 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002597 mInjectionResultAvailableCondition.broadcast();
2598 }
2599}
2600
Jeff Brown01ce2e92010-09-26 22:20:12 -07002601void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2602 InjectionState* injectionState = entry->injectionState;
2603 if (injectionState) {
2604 injectionState->pendingForegroundDispatches += 1;
2605 }
2606}
2607
Jeff Brown519e0242010-09-15 15:18:56 -07002608void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002609 InjectionState* injectionState = entry->injectionState;
2610 if (injectionState) {
2611 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002612
Jeff Brown01ce2e92010-09-26 22:20:12 -07002613 if (injectionState->pendingForegroundDispatches == 0) {
2614 mInjectionSyncFinishedCondition.broadcast();
2615 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002616 }
2617}
2618
Jeff Brown01ce2e92010-09-26 22:20:12 -07002619const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2620 for (size_t i = 0; i < mWindows.size(); i++) {
2621 const InputWindow* window = & mWindows[i];
2622 if (window->inputChannel == inputChannel) {
2623 return window;
2624 }
2625 }
2626 return NULL;
2627}
2628
Jeff Brownb88102f2010-09-08 11:49:43 -07002629void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2630#if DEBUG_FOCUS
2631 LOGD("setInputWindows");
2632#endif
2633 { // acquire lock
2634 AutoMutex _l(mLock);
2635
Jeff Brown01ce2e92010-09-26 22:20:12 -07002636 // Clear old window pointers.
Jeff Brownb6997262010-10-08 22:31:17 -07002637 sp<InputChannel> oldFocusedWindowChannel;
2638 if (mFocusedWindow) {
2639 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2640 mFocusedWindow = NULL;
2641 }
2642
Jeff Brownb88102f2010-09-08 11:49:43 -07002643 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002644
2645 // Loop over new windows and rebuild the necessary window pointers for
2646 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002647 mWindows.appendVector(inputWindows);
2648
2649 size_t numWindows = mWindows.size();
2650 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002651 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002652 if (window->hasFocus) {
2653 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002654 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002655 }
2656 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002657
Jeff Brownb6997262010-10-08 22:31:17 -07002658 if (oldFocusedWindowChannel != NULL) {
2659 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2660#if DEBUG_FOCUS
2661 LOGD("Focus left window: %s",
2662 oldFocusedWindowChannel->getName().string());
2663#endif
2664 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2665 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2666 oldFocusedWindowChannel.clear();
2667 }
2668 }
2669 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2670#if DEBUG_FOCUS
2671 LOGD("Focus entered window: %s",
2672 mFocusedWindow->inputChannel->getName().string());
2673#endif
2674 }
2675
Jeff Brown01ce2e92010-09-26 22:20:12 -07002676 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2677 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2678 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2679 if (window) {
2680 touchedWindow.window = window;
2681 i += 1;
2682 } else {
Jeff Brownb6997262010-10-08 22:31:17 -07002683#if DEBUG_FOCUS
2684 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2685#endif
Jeff Brownb6997262010-10-08 22:31:17 -07002686 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2687 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownaf48cae2010-10-15 16:20:51 -07002688 mTouchState.windows.removeAt(i);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002689 }
2690 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002691
Jeff Brownb88102f2010-09-08 11:49:43 -07002692#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002693 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002694#endif
2695 } // release lock
2696
2697 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002698 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002699}
2700
2701void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2702#if DEBUG_FOCUS
2703 LOGD("setFocusedApplication");
2704#endif
2705 { // acquire lock
2706 AutoMutex _l(mLock);
2707
2708 releaseFocusedApplicationLocked();
2709
2710 if (inputApplication) {
2711 mFocusedApplicationStorage = *inputApplication;
2712 mFocusedApplication = & mFocusedApplicationStorage;
2713 }
2714
2715#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002716 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002717#endif
2718 } // release lock
2719
2720 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002721 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002722}
2723
2724void InputDispatcher::releaseFocusedApplicationLocked() {
2725 if (mFocusedApplication) {
2726 mFocusedApplication = NULL;
Jeff Brown928e0542011-01-10 11:17:36 -08002727 mFocusedApplicationStorage.inputApplicationHandle.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -07002728 }
2729}
2730
2731void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2732#if DEBUG_FOCUS
2733 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2734#endif
2735
2736 bool changed;
2737 { // acquire lock
2738 AutoMutex _l(mLock);
2739
2740 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brown120a4592010-10-27 18:43:51 -07002741 if (mDispatchFrozen && !frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002742 resetANRTimeoutsLocked();
2743 }
2744
Jeff Brown120a4592010-10-27 18:43:51 -07002745 if (mDispatchEnabled && !enabled) {
2746 resetAndDropEverythingLocked("dispatcher is being disabled");
2747 }
2748
Jeff Brownb88102f2010-09-08 11:49:43 -07002749 mDispatchEnabled = enabled;
2750 mDispatchFrozen = frozen;
2751 changed = true;
2752 } else {
2753 changed = false;
2754 }
2755
2756#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002757 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002758#endif
2759 } // release lock
2760
2761 if (changed) {
2762 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002763 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002764 }
2765}
2766
Jeff Browne6504122010-09-27 14:52:15 -07002767bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2768 const sp<InputChannel>& toChannel) {
2769#if DEBUG_FOCUS
2770 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2771 fromChannel->getName().string(), toChannel->getName().string());
2772#endif
2773 { // acquire lock
2774 AutoMutex _l(mLock);
2775
2776 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2777 const InputWindow* toWindow = getWindowLocked(toChannel);
2778 if (! fromWindow || ! toWindow) {
2779#if DEBUG_FOCUS
2780 LOGD("Cannot transfer focus because from or to window not found.");
2781#endif
2782 return false;
2783 }
2784 if (fromWindow == toWindow) {
2785#if DEBUG_FOCUS
2786 LOGD("Trivial transfer to same window.");
2787#endif
2788 return true;
2789 }
2790
2791 bool found = false;
2792 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2793 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2794 if (touchedWindow.window == fromWindow) {
2795 int32_t oldTargetFlags = touchedWindow.targetFlags;
2796 BitSet32 pointerIds = touchedWindow.pointerIds;
2797
2798 mTouchState.windows.removeAt(i);
2799
Jeff Brown46e75292010-11-10 16:53:45 -08002800 int32_t newTargetFlags = oldTargetFlags
2801 & (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT);
Jeff Browne6504122010-09-27 14:52:15 -07002802 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2803
2804 found = true;
2805 break;
2806 }
2807 }
2808
2809 if (! found) {
2810#if DEBUG_FOCUS
2811 LOGD("Focus transfer failed because from window did not have focus.");
2812#endif
2813 return false;
2814 }
2815
Jeff Brown9c9f1a32010-10-11 18:32:20 -07002816 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2817 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2818 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2819 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2820 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2821
2822 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2823 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2824 InputState::CANCEL_POINTER_EVENTS,
2825 "transferring touch focus from this window to another window");
2826 }
2827
Jeff Browne6504122010-09-27 14:52:15 -07002828#if DEBUG_FOCUS
2829 logDispatchStateLocked();
2830#endif
2831 } // release lock
2832
2833 // Wake up poll loop since it may need to make new input dispatching choices.
2834 mLooper->wake();
2835 return true;
2836}
2837
Jeff Brown120a4592010-10-27 18:43:51 -07002838void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2839#if DEBUG_FOCUS
2840 LOGD("Resetting and dropping all events (%s).", reason);
2841#endif
2842
2843 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2844
2845 resetKeyRepeatLocked();
2846 releasePendingEventLocked();
2847 drainInboundQueueLocked();
2848 resetTargetsLocked();
2849
2850 mTouchState.reset();
2851}
2852
Jeff Brownb88102f2010-09-08 11:49:43 -07002853void InputDispatcher::logDispatchStateLocked() {
2854 String8 dump;
2855 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002856
2857 char* text = dump.lockBuffer(dump.size());
2858 char* start = text;
2859 while (*start != '\0') {
2860 char* end = strchr(start, '\n');
2861 if (*end == '\n') {
2862 *(end++) = '\0';
2863 }
2864 LOGD("%s", start);
2865 start = end;
2866 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002867}
2868
2869void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002870 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2871 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07002872
2873 if (mFocusedApplication) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002874 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002875 mFocusedApplication->name.string(),
2876 mFocusedApplication->dispatchingTimeout / 1000000.0);
2877 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002878 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002879 }
Jeff Brownf2f487182010-10-01 17:46:21 -07002880 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002881 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f487182010-10-01 17:46:21 -07002882
2883 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2884 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
Jeff Brown95712852011-01-04 19:41:59 -08002885 dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
Jeff Brownf2f487182010-10-01 17:46:21 -07002886 if (!mTouchState.windows.isEmpty()) {
2887 dump.append(INDENT "TouchedWindows:\n");
2888 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2889 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2890 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2891 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2892 touchedWindow.targetFlags);
2893 }
2894 } else {
2895 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002896 }
2897
Jeff Brownf2f487182010-10-01 17:46:21 -07002898 if (!mWindows.isEmpty()) {
2899 dump.append(INDENT "Windows:\n");
2900 for (size_t i = 0; i < mWindows.size(); i++) {
2901 const InputWindow& window = mWindows[i];
2902 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2903 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2904 "frame=[%d,%d][%d,%d], "
Jeff Brownfbf09772011-01-16 14:06:57 -08002905 "touchableRegion=",
Jeff Brownf2f487182010-10-01 17:46:21 -07002906 i, window.name.string(),
2907 toString(window.paused),
2908 toString(window.hasFocus),
2909 toString(window.hasWallpaper),
2910 toString(window.visible),
2911 toString(window.canReceiveKeys),
2912 window.layoutParamsFlags, window.layoutParamsType,
2913 window.layer,
2914 window.frameLeft, window.frameTop,
Jeff Brownfbf09772011-01-16 14:06:57 -08002915 window.frameRight, window.frameBottom);
2916 dumpRegion(dump, window.touchableRegion);
2917 dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07002918 window.ownerPid, window.ownerUid,
2919 window.dispatchingTimeout / 1000000.0);
2920 }
2921 } else {
2922 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002923 }
2924
Jeff Brownf2f487182010-10-01 17:46:21 -07002925 if (!mMonitoringChannels.isEmpty()) {
2926 dump.append(INDENT "MonitoringChannels:\n");
2927 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2928 const sp<InputChannel>& channel = mMonitoringChannels[i];
2929 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2930 }
2931 } else {
2932 dump.append(INDENT "MonitoringChannels: <none>\n");
2933 }
Jeff Brown519e0242010-09-15 15:18:56 -07002934
Jeff Brownf2f487182010-10-01 17:46:21 -07002935 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2936
2937 if (!mActiveConnections.isEmpty()) {
2938 dump.append(INDENT "ActiveConnections:\n");
2939 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2940 const Connection* connection = mActiveConnections[i];
Jeff Brown76860e32010-10-25 17:37:46 -07002941 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brownb6997262010-10-08 22:31:17 -07002942 "inputState.isNeutral=%s\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07002943 i, connection->getInputChannelName(), connection->getStatusLabel(),
2944 connection->outboundQueue.count(),
Jeff Brownb6997262010-10-08 22:31:17 -07002945 toString(connection->inputState.isNeutral()));
Jeff Brownf2f487182010-10-01 17:46:21 -07002946 }
2947 } else {
2948 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002949 }
2950
2951 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002952 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002953 (mAppSwitchDueTime - now()) / 1000000.0);
2954 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002955 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002956 }
2957}
2958
Jeff Brown928e0542011-01-10 11:17:36 -08002959status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
2960 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002961#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07002962 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2963 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07002964#endif
2965
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002966 { // acquire lock
2967 AutoMutex _l(mLock);
2968
Jeff Brown519e0242010-09-15 15:18:56 -07002969 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002970 LOGW("Attempted to register already registered input channel '%s'",
2971 inputChannel->getName().string());
2972 return BAD_VALUE;
2973 }
2974
Jeff Brown928e0542011-01-10 11:17:36 -08002975 sp<Connection> connection = new Connection(inputChannel, inputWindowHandle);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002976 status_t status = connection->initialize();
2977 if (status) {
2978 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2979 inputChannel->getName().string(), status);
2980 return status;
2981 }
2982
Jeff Brown2cbecea2010-08-17 15:59:26 -07002983 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002984 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002985
Jeff Brownb88102f2010-09-08 11:49:43 -07002986 if (monitor) {
2987 mMonitoringChannels.push(inputChannel);
2988 }
2989
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002990 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07002991
Jeff Brown9c3cda02010-06-15 01:31:58 -07002992 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002993 } // release lock
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002994 return OK;
2995}
2996
2997status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002998#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07002999 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07003000#endif
3001
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003002 { // acquire lock
3003 AutoMutex _l(mLock);
3004
Jeff Brown519e0242010-09-15 15:18:56 -07003005 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003006 if (connectionIndex < 0) {
3007 LOGW("Attempted to unregister already unregistered input channel '%s'",
3008 inputChannel->getName().string());
3009 return BAD_VALUE;
3010 }
3011
3012 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3013 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
3014
3015 connection->status = Connection::STATUS_ZOMBIE;
3016
Jeff Brownb88102f2010-09-08 11:49:43 -07003017 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3018 if (mMonitoringChannels[i] == inputChannel) {
3019 mMonitoringChannels.removeAt(i);
3020 break;
3021 }
3022 }
3023
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003024 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07003025
Jeff Brown7fbdc842010-06-17 20:52:56 -07003026 nsecs_t currentTime = now();
Jeff Brownb6997262010-10-08 22:31:17 -07003027 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003028
3029 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003030 } // release lock
3031
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003032 // Wake the poll loop because removing the connection may have changed the current
3033 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003034 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003035 return OK;
3036}
3037
Jeff Brown519e0242010-09-15 15:18:56 -07003038ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07003039 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
3040 if (connectionIndex >= 0) {
3041 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3042 if (connection->inputChannel.get() == inputChannel.get()) {
3043 return connectionIndex;
3044 }
3045 }
3046
3047 return -1;
3048}
3049
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003050void InputDispatcher::activateConnectionLocked(Connection* connection) {
3051 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3052 if (mActiveConnections.itemAt(i) == connection) {
3053 return;
3054 }
3055 }
3056 mActiveConnections.add(connection);
3057}
3058
3059void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
3060 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3061 if (mActiveConnections.itemAt(i) == connection) {
3062 mActiveConnections.removeAt(i);
3063 return;
3064 }
3065 }
3066}
3067
Jeff Brown9c3cda02010-06-15 01:31:58 -07003068void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003069 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003070}
3071
Jeff Brown9c3cda02010-06-15 01:31:58 -07003072void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown3915bb82010-11-05 15:02:16 -07003073 nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
3074 CommandEntry* commandEntry = postCommandLocked(
3075 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
3076 commandEntry->connection = connection;
3077 commandEntry->handled = handled;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003078}
3079
Jeff Brown9c3cda02010-06-15 01:31:58 -07003080void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003081 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003082 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3083 connection->getInputChannelName());
3084
Jeff Brown9c3cda02010-06-15 01:31:58 -07003085 CommandEntry* commandEntry = postCommandLocked(
3086 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003087 commandEntry->connection = connection;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003088}
3089
Jeff Brown519e0242010-09-15 15:18:56 -07003090void InputDispatcher::onANRLocked(
3091 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
3092 nsecs_t eventTime, nsecs_t waitStartTime) {
3093 LOGI("Application is not responding: %s. "
3094 "%01.1fms since event, %01.1fms since wait started",
3095 getApplicationWindowLabelLocked(application, window).string(),
3096 (currentTime - eventTime) / 1000000.0,
3097 (currentTime - waitStartTime) / 1000000.0);
3098
3099 CommandEntry* commandEntry = postCommandLocked(
3100 & InputDispatcher::doNotifyANRLockedInterruptible);
3101 if (application) {
Jeff Brown928e0542011-01-10 11:17:36 -08003102 commandEntry->inputApplicationHandle = application->inputApplicationHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003103 }
3104 if (window) {
Jeff Brown928e0542011-01-10 11:17:36 -08003105 commandEntry->inputWindowHandle = window->inputWindowHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003106 commandEntry->inputChannel = window->inputChannel;
3107 }
3108}
3109
Jeff Brownb88102f2010-09-08 11:49:43 -07003110void InputDispatcher::doNotifyConfigurationChangedInterruptible(
3111 CommandEntry* commandEntry) {
3112 mLock.unlock();
3113
3114 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
3115
3116 mLock.lock();
3117}
3118
Jeff Brown9c3cda02010-06-15 01:31:58 -07003119void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
3120 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003121 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07003122
Jeff Brown7fbdc842010-06-17 20:52:56 -07003123 if (connection->status != Connection::STATUS_ZOMBIE) {
3124 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003125
Jeff Brown928e0542011-01-10 11:17:36 -08003126 mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003127
3128 mLock.lock();
3129 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07003130}
3131
Jeff Brown519e0242010-09-15 15:18:56 -07003132void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07003133 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07003134 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003135
Jeff Brown519e0242010-09-15 15:18:56 -07003136 nsecs_t newTimeout = mPolicy->notifyANR(
Jeff Brown928e0542011-01-10 11:17:36 -08003137 commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003138
Jeff Brown519e0242010-09-15 15:18:56 -07003139 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07003140
Jeff Brown519e0242010-09-15 15:18:56 -07003141 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003142}
3143
Jeff Brownb88102f2010-09-08 11:49:43 -07003144void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3145 CommandEntry* commandEntry) {
3146 KeyEntry* entry = commandEntry->keyEntry;
Jeff Brown1f245102010-11-18 20:53:46 -08003147
3148 KeyEvent event;
3149 initializeKeyEvent(&event, entry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003150
3151 mLock.unlock();
3152
Jeff Brown928e0542011-01-10 11:17:36 -08003153 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
Jeff Brown1f245102010-11-18 20:53:46 -08003154 &event, entry->policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -07003155
3156 mLock.lock();
3157
3158 entry->interceptKeyResult = consumed
3159 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
3160 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3161 mAllocator.releaseKeyEntry(entry);
3162}
3163
Jeff Brown3915bb82010-11-05 15:02:16 -07003164void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3165 CommandEntry* commandEntry) {
3166 sp<Connection> connection = commandEntry->connection;
3167 bool handled = commandEntry->handled;
3168
Jeff Brown49ed71d2010-12-06 17:13:33 -08003169 if (!connection->outboundQueue.isEmpty()) {
Jeff Brown3915bb82010-11-05 15:02:16 -07003170 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
3171 if (dispatchEntry->inProgress
3172 && dispatchEntry->hasForegroundTarget()
3173 && dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3174 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003175 if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
3176 if (handled) {
3177 // If the application handled a non-fallback key, then immediately
3178 // cancel all fallback keys previously dispatched to the application.
3179 // This behavior will prevent chording with fallback keys (so they cannot
3180 // be used as modifiers) but it will ensure that fallback keys do not
3181 // get stuck. This takes care of the case where the application does not handle
3182 // the original DOWN so we generate a fallback DOWN but it does handle
3183 // the original UP in which case we would not generate the fallback UP.
3184 synthesizeCancelationEventsForConnectionLocked(connection,
3185 InputState::CANCEL_FALLBACK_EVENTS,
Jeff Brown00045a72010-12-09 18:10:30 -08003186 "application handled a non-fallback event, canceling all fallback events");
Jeff Brown49ed71d2010-12-06 17:13:33 -08003187 } else {
3188 // If the application did not handle a non-fallback key, then ask
3189 // the policy what to do with it. We might generate a fallback key
3190 // event here.
3191 KeyEvent event;
3192 initializeKeyEvent(&event, keyEntry);
Jeff Brown3915bb82010-11-05 15:02:16 -07003193
Jeff Brown49ed71d2010-12-06 17:13:33 -08003194 mLock.unlock();
Jeff Brown3915bb82010-11-05 15:02:16 -07003195
Jeff Brown928e0542011-01-10 11:17:36 -08003196 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003197 &event, keyEntry->policyFlags, &event);
Jeff Brown3915bb82010-11-05 15:02:16 -07003198
Jeff Brown49ed71d2010-12-06 17:13:33 -08003199 mLock.lock();
3200
Jeff Brown00045a72010-12-09 18:10:30 -08003201 if (connection->status != Connection::STATUS_NORMAL) {
3202 return;
3203 }
3204
3205 assert(connection->outboundQueue.headSentinel.next == dispatchEntry);
3206
Jeff Brown49ed71d2010-12-06 17:13:33 -08003207 if (fallback) {
3208 // Restart the dispatch cycle using the fallback key.
3209 keyEntry->eventTime = event.getEventTime();
3210 keyEntry->deviceId = event.getDeviceId();
3211 keyEntry->source = event.getSource();
3212 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
3213 keyEntry->keyCode = event.getKeyCode();
3214 keyEntry->scanCode = event.getScanCode();
3215 keyEntry->metaState = event.getMetaState();
3216 keyEntry->repeatCount = event.getRepeatCount();
3217 keyEntry->downTime = event.getDownTime();
3218 keyEntry->syntheticRepeat = false;
3219
3220 dispatchEntry->inProgress = false;
3221 startDispatchCycleLocked(now(), connection);
3222 return;
3223 }
3224 }
3225 }
Jeff Brown3915bb82010-11-05 15:02:16 -07003226 }
3227 }
3228
3229 startNextDispatchCycleLocked(now(), connection);
3230}
3231
Jeff Brownb88102f2010-09-08 11:49:43 -07003232void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3233 mLock.unlock();
3234
Jeff Brown01ce2e92010-09-26 22:20:12 -07003235 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07003236
3237 mLock.lock();
3238}
3239
Jeff Brown3915bb82010-11-05 15:02:16 -07003240void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
3241 event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3242 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3243 entry->downTime, entry->eventTime);
3244}
3245
Jeff Brown519e0242010-09-15 15:18:56 -07003246void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3247 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3248 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07003249}
3250
3251void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003252 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003253 dumpDispatchStateLocked(dump);
3254}
3255
Jeff Brown9c3cda02010-06-15 01:31:58 -07003256
Jeff Brown519e0242010-09-15 15:18:56 -07003257// --- InputDispatcher::Queue ---
3258
3259template <typename T>
3260uint32_t InputDispatcher::Queue<T>::count() const {
3261 uint32_t result = 0;
3262 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3263 result += 1;
3264 }
3265 return result;
3266}
3267
3268
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003269// --- InputDispatcher::Allocator ---
3270
3271InputDispatcher::Allocator::Allocator() {
3272}
3273
Jeff Brown01ce2e92010-09-26 22:20:12 -07003274InputDispatcher::InjectionState*
3275InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3276 InjectionState* injectionState = mInjectionStatePool.alloc();
3277 injectionState->refCount = 1;
3278 injectionState->injectorPid = injectorPid;
3279 injectionState->injectorUid = injectorUid;
3280 injectionState->injectionIsAsync = false;
3281 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3282 injectionState->pendingForegroundDispatches = 0;
3283 return injectionState;
3284}
3285
Jeff Brown7fbdc842010-06-17 20:52:56 -07003286void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brownb6997262010-10-08 22:31:17 -07003287 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003288 entry->type = type;
3289 entry->refCount = 1;
3290 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07003291 entry->eventTime = eventTime;
Jeff Brownb6997262010-10-08 22:31:17 -07003292 entry->policyFlags = policyFlags;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003293 entry->injectionState = NULL;
3294}
3295
3296void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3297 if (entry->injectionState) {
3298 releaseInjectionState(entry->injectionState);
3299 entry->injectionState = NULL;
3300 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07003301}
3302
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003303InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07003304InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003305 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003306 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003307 return entry;
3308}
3309
Jeff Brown7fbdc842010-06-17 20:52:56 -07003310InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07003311 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003312 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3313 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003314 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003315 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003316
3317 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003318 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003319 entry->action = action;
3320 entry->flags = flags;
3321 entry->keyCode = keyCode;
3322 entry->scanCode = scanCode;
3323 entry->metaState = metaState;
3324 entry->repeatCount = repeatCount;
3325 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003326 entry->syntheticRepeat = false;
3327 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003328 return entry;
3329}
3330
Jeff Brown7fbdc842010-06-17 20:52:56 -07003331InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07003332 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003333 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3334 nsecs_t downTime, uint32_t pointerCount,
3335 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003336 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003337 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003338
3339 entry->eventTime = eventTime;
3340 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003341 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003342 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07003343 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003344 entry->metaState = metaState;
3345 entry->edgeFlags = edgeFlags;
3346 entry->xPrecision = xPrecision;
3347 entry->yPrecision = yPrecision;
3348 entry->downTime = downTime;
3349 entry->pointerCount = pointerCount;
3350 entry->firstSample.eventTime = eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003351 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003352 entry->lastSample = & entry->firstSample;
3353 for (uint32_t i = 0; i < pointerCount; i++) {
3354 entry->pointerIds[i] = pointerIds[i];
3355 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3356 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003357 return entry;
3358}
3359
3360InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07003361 EventEntry* eventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07003362 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003363 DispatchEntry* entry = mDispatchEntryPool.alloc();
3364 entry->eventEntry = eventEntry;
3365 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07003366 entry->targetFlags = targetFlags;
3367 entry->xOffset = xOffset;
3368 entry->yOffset = yOffset;
Jeff Brownb88102f2010-09-08 11:49:43 -07003369 entry->inProgress = false;
3370 entry->headMotionSample = NULL;
3371 entry->tailMotionSample = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003372 return entry;
3373}
3374
Jeff Brown9c3cda02010-06-15 01:31:58 -07003375InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3376 CommandEntry* entry = mCommandEntryPool.alloc();
3377 entry->command = command;
3378 return entry;
3379}
3380
Jeff Brown01ce2e92010-09-26 22:20:12 -07003381void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3382 injectionState->refCount -= 1;
3383 if (injectionState->refCount == 0) {
3384 mInjectionStatePool.free(injectionState);
3385 } else {
3386 assert(injectionState->refCount > 0);
3387 }
3388}
3389
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003390void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3391 switch (entry->type) {
3392 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3393 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3394 break;
3395 case EventEntry::TYPE_KEY:
3396 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3397 break;
3398 case EventEntry::TYPE_MOTION:
3399 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3400 break;
3401 default:
3402 assert(false);
3403 break;
3404 }
3405}
3406
3407void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3408 ConfigurationChangedEntry* entry) {
3409 entry->refCount -= 1;
3410 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003411 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003412 mConfigurationChangeEntryPool.free(entry);
3413 } else {
3414 assert(entry->refCount > 0);
3415 }
3416}
3417
3418void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3419 entry->refCount -= 1;
3420 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003421 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003422 mKeyEntryPool.free(entry);
3423 } else {
3424 assert(entry->refCount > 0);
3425 }
3426}
3427
3428void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3429 entry->refCount -= 1;
3430 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003431 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003432 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3433 MotionSample* next = sample->next;
3434 mMotionSamplePool.free(sample);
3435 sample = next;
3436 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003437 mMotionEntryPool.free(entry);
3438 } else {
3439 assert(entry->refCount > 0);
3440 }
3441}
3442
3443void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3444 releaseEventEntry(entry->eventEntry);
3445 mDispatchEntryPool.free(entry);
3446}
3447
Jeff Brown9c3cda02010-06-15 01:31:58 -07003448void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3449 mCommandEntryPool.free(entry);
3450}
3451
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003452void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003453 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003454 MotionSample* sample = mMotionSamplePool.alloc();
3455 sample->eventTime = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003456 uint32_t pointerCount = motionEntry->pointerCount;
3457 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003458 sample->pointerCoords[i] = pointerCoords[i];
3459 }
3460
3461 sample->next = NULL;
3462 motionEntry->lastSample->next = sample;
3463 motionEntry->lastSample = sample;
3464}
3465
Jeff Brown01ce2e92010-09-26 22:20:12 -07003466void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3467 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003468
Jeff Brown01ce2e92010-09-26 22:20:12 -07003469 keyEntry->dispatchInProgress = false;
3470 keyEntry->syntheticRepeat = false;
3471 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003472}
3473
3474
Jeff Brownae9fc032010-08-18 15:51:08 -07003475// --- InputDispatcher::MotionEntry ---
3476
3477uint32_t InputDispatcher::MotionEntry::countSamples() const {
3478 uint32_t count = 1;
3479 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3480 count += 1;
3481 }
3482 return count;
3483}
3484
Jeff Brownb88102f2010-09-08 11:49:43 -07003485
3486// --- InputDispatcher::InputState ---
3487
Jeff Brownb6997262010-10-08 22:31:17 -07003488InputDispatcher::InputState::InputState() {
Jeff Brownb88102f2010-09-08 11:49:43 -07003489}
3490
3491InputDispatcher::InputState::~InputState() {
3492}
3493
3494bool InputDispatcher::InputState::isNeutral() const {
3495 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3496}
3497
Jeff Brownb88102f2010-09-08 11:49:43 -07003498InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3499 const EventEntry* entry) {
3500 switch (entry->type) {
3501 case EventEntry::TYPE_KEY:
3502 return trackKey(static_cast<const KeyEntry*>(entry));
3503
3504 case EventEntry::TYPE_MOTION:
3505 return trackMotion(static_cast<const MotionEntry*>(entry));
3506
3507 default:
3508 return CONSISTENT;
3509 }
3510}
3511
3512InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3513 const KeyEntry* entry) {
3514 int32_t action = entry->action;
3515 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3516 KeyMemento& memento = mKeyMementos.editItemAt(i);
3517 if (memento.deviceId == entry->deviceId
3518 && memento.source == entry->source
3519 && memento.keyCode == entry->keyCode
3520 && memento.scanCode == entry->scanCode) {
3521 switch (action) {
3522 case AKEY_EVENT_ACTION_UP:
3523 mKeyMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003524 return CONSISTENT;
3525
3526 case AKEY_EVENT_ACTION_DOWN:
3527 return TOLERABLE;
3528
3529 default:
3530 return BROKEN;
3531 }
3532 }
3533 }
3534
3535 switch (action) {
3536 case AKEY_EVENT_ACTION_DOWN: {
3537 mKeyMementos.push();
3538 KeyMemento& memento = mKeyMementos.editTop();
3539 memento.deviceId = entry->deviceId;
3540 memento.source = entry->source;
3541 memento.keyCode = entry->keyCode;
3542 memento.scanCode = entry->scanCode;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003543 memento.flags = entry->flags;
Jeff Brownb88102f2010-09-08 11:49:43 -07003544 memento.downTime = entry->downTime;
3545 return CONSISTENT;
3546 }
3547
3548 default:
3549 return BROKEN;
3550 }
3551}
3552
3553InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3554 const MotionEntry* entry) {
3555 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3556 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3557 MotionMemento& memento = mMotionMementos.editItemAt(i);
3558 if (memento.deviceId == entry->deviceId
3559 && memento.source == entry->source) {
3560 switch (action) {
3561 case AMOTION_EVENT_ACTION_UP:
3562 case AMOTION_EVENT_ACTION_CANCEL:
3563 mMotionMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003564 return CONSISTENT;
3565
3566 case AMOTION_EVENT_ACTION_DOWN:
3567 return TOLERABLE;
3568
3569 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3570 if (entry->pointerCount == memento.pointerCount + 1) {
3571 memento.setPointers(entry);
3572 return CONSISTENT;
3573 }
3574 return BROKEN;
3575
3576 case AMOTION_EVENT_ACTION_POINTER_UP:
3577 if (entry->pointerCount == memento.pointerCount - 1) {
3578 memento.setPointers(entry);
3579 return CONSISTENT;
3580 }
3581 return BROKEN;
3582
3583 case AMOTION_EVENT_ACTION_MOVE:
3584 if (entry->pointerCount == memento.pointerCount) {
3585 return CONSISTENT;
3586 }
3587 return BROKEN;
3588
3589 default:
3590 return BROKEN;
3591 }
3592 }
3593 }
3594
3595 switch (action) {
3596 case AMOTION_EVENT_ACTION_DOWN: {
3597 mMotionMementos.push();
3598 MotionMemento& memento = mMotionMementos.editTop();
3599 memento.deviceId = entry->deviceId;
3600 memento.source = entry->source;
3601 memento.xPrecision = entry->xPrecision;
3602 memento.yPrecision = entry->yPrecision;
3603 memento.downTime = entry->downTime;
3604 memento.setPointers(entry);
3605 return CONSISTENT;
3606 }
3607
3608 default:
3609 return BROKEN;
3610 }
3611}
3612
3613void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3614 pointerCount = entry->pointerCount;
3615 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3616 pointerIds[i] = entry->pointerIds[i];
3617 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3618 }
3619}
3620
Jeff Brownb6997262010-10-08 22:31:17 -07003621void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3622 Allocator* allocator, Vector<EventEntry*>& outEvents,
3623 CancelationOptions options) {
3624 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003625 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003626 if (shouldCancelKey(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003627 outEvents.push(allocator->obtainKeyEntry(currentTime,
3628 memento.deviceId, memento.source, 0,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003629 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
Jeff Brownb6997262010-10-08 22:31:17 -07003630 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3631 mKeyMementos.removeAt(i);
3632 } else {
3633 i += 1;
3634 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003635 }
3636
Jeff Browna1160a72010-10-11 18:22:53 -07003637 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003638 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003639 if (shouldCancelMotion(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003640 outEvents.push(allocator->obtainMotionEntry(currentTime,
3641 memento.deviceId, memento.source, 0,
3642 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3643 memento.xPrecision, memento.yPrecision, memento.downTime,
3644 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3645 mMotionMementos.removeAt(i);
3646 } else {
3647 i += 1;
3648 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003649 }
3650}
3651
3652void InputDispatcher::InputState::clear() {
3653 mKeyMementos.clear();
3654 mMotionMementos.clear();
Jeff Brownb6997262010-10-08 22:31:17 -07003655}
3656
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003657void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3658 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3659 const MotionMemento& memento = mMotionMementos.itemAt(i);
3660 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3661 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3662 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3663 if (memento.deviceId == otherMemento.deviceId
3664 && memento.source == otherMemento.source) {
3665 other.mMotionMementos.removeAt(j);
3666 } else {
3667 j += 1;
3668 }
3669 }
3670 other.mMotionMementos.push(memento);
3671 }
3672 }
3673}
3674
Jeff Brown49ed71d2010-12-06 17:13:33 -08003675bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
Jeff Brownb6997262010-10-08 22:31:17 -07003676 CancelationOptions options) {
3677 switch (options) {
Jeff Brown49ed71d2010-12-06 17:13:33 -08003678 case CANCEL_ALL_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003679 case CANCEL_NON_POINTER_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003680 return true;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003681 case CANCEL_FALLBACK_EVENTS:
3682 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
3683 default:
3684 return false;
3685 }
3686}
3687
3688bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
3689 CancelationOptions options) {
3690 switch (options) {
3691 case CANCEL_ALL_EVENTS:
3692 return true;
3693 case CANCEL_POINTER_EVENTS:
3694 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
3695 case CANCEL_NON_POINTER_EVENTS:
3696 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
3697 default:
3698 return false;
Jeff Brownb6997262010-10-08 22:31:17 -07003699 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003700}
3701
3702
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003703// --- InputDispatcher::Connection ---
3704
Jeff Brown928e0542011-01-10 11:17:36 -08003705InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
3706 const sp<InputWindowHandle>& inputWindowHandle) :
3707 status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
3708 inputPublisher(inputChannel),
Jeff Brown519e0242010-09-15 15:18:56 -07003709 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003710}
3711
3712InputDispatcher::Connection::~Connection() {
3713}
3714
3715status_t InputDispatcher::Connection::initialize() {
3716 return inputPublisher.initialize();
3717}
3718
Jeff Brown9c3cda02010-06-15 01:31:58 -07003719const char* InputDispatcher::Connection::getStatusLabel() const {
3720 switch (status) {
3721 case STATUS_NORMAL:
3722 return "NORMAL";
3723
3724 case STATUS_BROKEN:
3725 return "BROKEN";
3726
Jeff Brown9c3cda02010-06-15 01:31:58 -07003727 case STATUS_ZOMBIE:
3728 return "ZOMBIE";
3729
3730 default:
3731 return "UNKNOWN";
3732 }
3733}
3734
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003735InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3736 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07003737 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3738 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003739 if (dispatchEntry->eventEntry == eventEntry) {
3740 return dispatchEntry;
3741 }
3742 }
3743 return NULL;
3744}
3745
Jeff Brownb88102f2010-09-08 11:49:43 -07003746
Jeff Brown9c3cda02010-06-15 01:31:58 -07003747// --- InputDispatcher::CommandEntry ---
3748
Jeff Brownb88102f2010-09-08 11:49:43 -07003749InputDispatcher::CommandEntry::CommandEntry() :
3750 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003751}
3752
3753InputDispatcher::CommandEntry::~CommandEntry() {
3754}
3755
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003756
Jeff Brown01ce2e92010-09-26 22:20:12 -07003757// --- InputDispatcher::TouchState ---
3758
3759InputDispatcher::TouchState::TouchState() :
Jeff Brown95712852011-01-04 19:41:59 -08003760 down(false), split(false), deviceId(-1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003761}
3762
3763InputDispatcher::TouchState::~TouchState() {
3764}
3765
3766void InputDispatcher::TouchState::reset() {
3767 down = false;
3768 split = false;
Jeff Brown95712852011-01-04 19:41:59 -08003769 deviceId = -1;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003770 windows.clear();
3771}
3772
3773void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3774 down = other.down;
3775 split = other.split;
Jeff Brown95712852011-01-04 19:41:59 -08003776 deviceId = other.deviceId;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003777 windows.clear();
3778 windows.appendVector(other.windows);
3779}
3780
3781void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3782 int32_t targetFlags, BitSet32 pointerIds) {
3783 if (targetFlags & InputTarget::FLAG_SPLIT) {
3784 split = true;
3785 }
3786
3787 for (size_t i = 0; i < windows.size(); i++) {
3788 TouchedWindow& touchedWindow = windows.editItemAt(i);
3789 if (touchedWindow.window == window) {
3790 touchedWindow.targetFlags |= targetFlags;
3791 touchedWindow.pointerIds.value |= pointerIds.value;
3792 return;
3793 }
3794 }
3795
3796 windows.push();
3797
3798 TouchedWindow& touchedWindow = windows.editTop();
3799 touchedWindow.window = window;
3800 touchedWindow.targetFlags = targetFlags;
3801 touchedWindow.pointerIds = pointerIds;
3802 touchedWindow.channel = window->inputChannel;
3803}
3804
3805void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3806 for (size_t i = 0 ; i < windows.size(); ) {
3807 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3808 windows.removeAt(i);
3809 } else {
3810 i += 1;
3811 }
3812 }
3813}
3814
3815const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3816 for (size_t i = 0; i < windows.size(); i++) {
3817 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3818 return windows[i].window;
3819 }
3820 }
3821 return NULL;
3822}
3823
3824
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003825// --- InputDispatcherThread ---
3826
3827InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3828 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3829}
3830
3831InputDispatcherThread::~InputDispatcherThread() {
3832}
3833
3834bool InputDispatcherThread::threadLoop() {
3835 mDispatcher->dispatchOnce();
3836 return true;
3837}
3838
3839} // namespace android