blob: 5bca7ee8ad276c424effb4b763bb4ac183ecd1fc [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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Browna032cc02011-03-07 16:56:21 -080051// Log debug messages about hover events.
52#define DEBUG_HOVER 0
53
Jeff Brownb4ff35d2011-01-02 16:37:43 -080054#include "InputDispatcher.h"
55
Jeff Brown46b9ac02010-04-22 18:58:52 -070056#include <cutils/log.h>
Jeff Brownb88102f2010-09-08 11:49:43 -070057#include <ui/PowerManager.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070058
59#include <stddef.h>
60#include <unistd.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070061#include <errno.h>
62#include <limits.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070063
Jeff Brownf2f48712010-10-01 17:46:21 -070064#define INDENT " "
65#define INDENT2 " "
66
Jeff Brown46b9ac02010-04-22 18:58:52 -070067namespace android {
68
Jeff Brownb88102f2010-09-08 11:49:43 -070069// Default input dispatching timeout if there is no focused application or paused window
70// from which to determine an appropriate dispatching timeout.
71const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
72
73// Amount of time to allow for all pending events to be processed when an app switch
74// key is on the way. This is used to preempt input dispatch and drop input events
75// when an application takes too long to respond and the user has pressed an app switch key.
76const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
77
Jeff Brown928e0542011-01-10 11:17:36 -080078// Amount of time to allow for an event to be dispatched (measured since its eventTime)
79// before considering it stale and dropping it.
80const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
81
Jeff Brown4e91a182011-04-07 11:38:09 -070082// Motion samples that are received within this amount of time are simply coalesced
83// when batched instead of being appended. This is done because some drivers update
84// the location of pointers one at a time instead of all at once.
85// For example, when there are 10 fingers down, the input dispatcher may receive 10
86// samples in quick succession with only one finger's location changed in each sample.
87//
88// This value effectively imposes an upper bound on the touch sampling rate.
89// Touch sensors typically have a 50Hz - 200Hz sampling rate, so we expect distinct
90// samples to become available 5-20ms apart but individual finger reports can trickle
91// in over a period of 2-4ms or so.
92//
93// Empirical testing shows that a 2ms coalescing interval (500Hz) is not enough,
94// a 3ms coalescing interval (333Hz) works well most of the time and doesn't introduce
95// significant quantization noise on current hardware.
96const nsecs_t MOTION_SAMPLE_COALESCE_INTERVAL = 3 * 1000000LL; // 3ms, 333Hz
97
Jeff Brown46b9ac02010-04-22 18:58:52 -070098
Jeff Brown7fbdc842010-06-17 20:52:56 -070099static inline nsecs_t now() {
100 return systemTime(SYSTEM_TIME_MONOTONIC);
101}
102
Jeff Brownb88102f2010-09-08 11:49:43 -0700103static inline const char* toString(bool value) {
104 return value ? "true" : "false";
105}
106
Jeff Brown01ce2e92010-09-26 22:20:12 -0700107static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
108 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
109 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
110}
111
112static bool isValidKeyAction(int32_t action) {
113 switch (action) {
114 case AKEY_EVENT_ACTION_DOWN:
115 case AKEY_EVENT_ACTION_UP:
116 return true;
117 default:
118 return false;
119 }
120}
121
122static bool validateKeyEvent(int32_t action) {
123 if (! isValidKeyAction(action)) {
124 LOGE("Key event has invalid action code 0x%x", action);
125 return false;
126 }
127 return true;
128}
129
Jeff Brownb6997262010-10-08 22:31:17 -0700130static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700131 switch (action & AMOTION_EVENT_ACTION_MASK) {
132 case AMOTION_EVENT_ACTION_DOWN:
133 case AMOTION_EVENT_ACTION_UP:
134 case AMOTION_EVENT_ACTION_CANCEL:
135 case AMOTION_EVENT_ACTION_MOVE:
Jeff Brown01ce2e92010-09-26 22:20:12 -0700136 case AMOTION_EVENT_ACTION_OUTSIDE:
Jeff Browna032cc02011-03-07 16:56:21 -0800137 case AMOTION_EVENT_ACTION_HOVER_ENTER:
Jeff Browncc0c1592011-02-19 05:07:28 -0800138 case AMOTION_EVENT_ACTION_HOVER_MOVE:
Jeff Browna032cc02011-03-07 16:56:21 -0800139 case AMOTION_EVENT_ACTION_HOVER_EXIT:
Jeff Brown33bbfd22011-02-24 20:55:35 -0800140 case AMOTION_EVENT_ACTION_SCROLL:
Jeff Brown01ce2e92010-09-26 22:20:12 -0700141 return true;
Jeff Brownb6997262010-10-08 22:31:17 -0700142 case AMOTION_EVENT_ACTION_POINTER_DOWN:
143 case AMOTION_EVENT_ACTION_POINTER_UP: {
144 int32_t index = getMotionEventActionPointerIndex(action);
145 return index >= 0 && size_t(index) < pointerCount;
146 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700147 default:
148 return false;
149 }
150}
151
152static bool validateMotionEvent(int32_t action, size_t pointerCount,
153 const int32_t* pointerIds) {
Jeff Brownb6997262010-10-08 22:31:17 -0700154 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700155 LOGE("Motion event has invalid action code 0x%x", action);
156 return false;
157 }
158 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
159 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
160 pointerCount, MAX_POINTERS);
161 return false;
162 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700163 BitSet32 pointerIdBits;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700164 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownc3db8582010-10-20 15:33:38 -0700165 int32_t id = pointerIds[i];
166 if (id < 0 || id > MAX_POINTER_ID) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700167 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
Jeff Brownc3db8582010-10-20 15:33:38 -0700168 id, MAX_POINTER_ID);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700169 return false;
170 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700171 if (pointerIdBits.hasBit(id)) {
172 LOGE("Motion event has duplicate pointer id %d", id);
173 return false;
174 }
175 pointerIdBits.markBit(id);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700176 }
177 return true;
178}
179
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400180static void scalePointerCoords(const PointerCoords* inCoords, size_t count, float scaleFactor,
181 PointerCoords* outCoords) {
182 for (size_t i = 0; i < count; i++) {
183 outCoords[i] = inCoords[i];
184 outCoords[i].scale(scaleFactor);
185 }
186}
187
Jeff Brownfbf09772011-01-16 14:06:57 -0800188static void dumpRegion(String8& dump, const SkRegion& region) {
189 if (region.isEmpty()) {
190 dump.append("<empty>");
191 return;
192 }
193
194 bool first = true;
195 for (SkRegion::Iterator it(region); !it.done(); it.next()) {
196 if (first) {
197 first = false;
198 } else {
199 dump.append("|");
200 }
201 const SkIRect& rect = it.rect();
202 dump.appendFormat("[%d,%d][%d,%d]", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
203 }
204}
205
Jeff Brownb88102f2010-09-08 11:49:43 -0700206
Jeff Brown46b9ac02010-04-22 18:58:52 -0700207// --- InputDispatcher ---
208
Jeff Brown9c3cda02010-06-15 01:31:58 -0700209InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Brownb88102f2010-09-08 11:49:43 -0700210 mPolicy(policy),
Jeff Brown928e0542011-01-10 11:17:36 -0800211 mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
212 mNextUnblockedEvent(NULL),
Jeff Brown0029c662011-03-30 02:25:18 -0700213 mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false),
Jeff Brown01ce2e92010-09-26 22:20:12 -0700214 mFocusedWindow(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700215 mFocusedApplication(NULL),
216 mCurrentInputTargetsValid(false),
Jeff Browna032cc02011-03-07 16:56:21 -0800217 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE),
218 mLastHoverWindow(NULL) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700219 mLooper = new Looper(false);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700220
Jeff Brownb88102f2010-09-08 11:49:43 -0700221 mInboundQueue.headSentinel.refCount = -1;
222 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
223 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700224
Jeff Brownb88102f2010-09-08 11:49:43 -0700225 mInboundQueue.tailSentinel.refCount = -1;
226 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
227 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700228
229 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700230
Jeff Brownae9fc032010-08-18 15:51:08 -0700231 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
232 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
233 mThrottleState.lastDeviceId = -1;
234
235#if DEBUG_THROTTLING
236 mThrottleState.originalSampleCount = 0;
237 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
238#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -0700239}
240
241InputDispatcher::~InputDispatcher() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700242 { // acquire lock
243 AutoMutex _l(mLock);
244
245 resetKeyRepeatLocked();
Jeff Brown54a18252010-09-16 14:07:33 -0700246 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700247 drainInboundQueueLocked();
248 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700249
250 while (mConnectionsByReceiveFd.size() != 0) {
251 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
252 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700253}
254
255void InputDispatcher::dispatchOnce() {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700256 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700257 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700258
Jeff Brown46b9ac02010-04-22 18:58:52 -0700259 nsecs_t nextWakeupTime = LONG_LONG_MAX;
260 { // acquire lock
261 AutoMutex _l(mLock);
Jeff Brownb88102f2010-09-08 11:49:43 -0700262 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700263
Jeff Brownb88102f2010-09-08 11:49:43 -0700264 if (runCommandsLockedInterruptible()) {
265 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Brown46b9ac02010-04-22 18:58:52 -0700266 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700267 } // release lock
268
Jeff Brownb88102f2010-09-08 11:49:43 -0700269 // Wait for callback or timeout or wake. (make sure we round up, not down)
270 nsecs_t currentTime = now();
Jeff Brownaa3855d2011-03-17 01:34:19 -0700271 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700272 mLooper->pollOnce(timeoutMillis);
Jeff Brownb88102f2010-09-08 11:49:43 -0700273}
274
275void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
276 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
277 nsecs_t currentTime = now();
278
279 // Reset the key repeat timer whenever we disallow key events, even if the next event
280 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
281 // out of sleep.
282 if (keyRepeatTimeout < 0) {
283 resetKeyRepeatLocked();
284 }
285
Jeff Brownb88102f2010-09-08 11:49:43 -0700286 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
287 if (mDispatchFrozen) {
288#if DEBUG_FOCUS
289 LOGD("Dispatch frozen. Waiting some more.");
290#endif
291 return;
292 }
293
294 // Optimize latency of app switches.
295 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
296 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
297 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
298 if (mAppSwitchDueTime < *nextWakeupTime) {
299 *nextWakeupTime = mAppSwitchDueTime;
300 }
301
Jeff Brownb88102f2010-09-08 11:49:43 -0700302 // Ready to start a new event.
303 // If we don't already have a pending event, go grab one.
304 if (! mPendingEvent) {
305 if (mInboundQueue.isEmpty()) {
306 if (isAppSwitchDue) {
307 // The inbound queue is empty so the app switch key we were waiting
308 // for will never arrive. Stop waiting for it.
309 resetPendingAppSwitchLocked(false);
310 isAppSwitchDue = false;
311 }
312
313 // Synthesize a key repeat if appropriate.
314 if (mKeyRepeatState.lastKeyEntry) {
315 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
316 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
317 } else {
318 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
319 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
320 }
321 }
322 }
323 if (! mPendingEvent) {
324 return;
325 }
326 } else {
327 // Inbound queue has at least one entry.
328 EventEntry* entry = mInboundQueue.headSentinel.next;
329
330 // Throttle the entry if it is a move event and there are no
331 // other events behind it in the queue. Due to movement batching, additional
332 // samples may be appended to this event by the time the throttling timeout
333 // expires.
334 // TODO Make this smarter and consider throttling per device independently.
Jeff Brownb6997262010-10-08 22:31:17 -0700335 if (entry->type == EventEntry::TYPE_MOTION
336 && !isAppSwitchDue
337 && mDispatchEnabled
338 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
339 && !entry->isInjected()) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700340 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
341 int32_t deviceId = motionEntry->deviceId;
342 uint32_t source = motionEntry->source;
343 if (! isAppSwitchDue
344 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
Jeff Browncc0c1592011-02-19 05:07:28 -0800345 && (motionEntry->action == AMOTION_EVENT_ACTION_MOVE
346 || motionEntry->action == AMOTION_EVENT_ACTION_HOVER_MOVE)
Jeff Brownb88102f2010-09-08 11:49:43 -0700347 && deviceId == mThrottleState.lastDeviceId
348 && source == mThrottleState.lastSource) {
349 nsecs_t nextTime = mThrottleState.lastEventTime
350 + mThrottleState.minTimeBetweenEvents;
351 if (currentTime < nextTime) {
352 // Throttle it!
353#if DEBUG_THROTTLING
354 LOGD("Throttling - Delaying motion event for "
Jeff Brown90655042010-12-02 13:50:46 -0800355 "device %d, source 0x%08x by up to %0.3fms.",
Jeff Brownb88102f2010-09-08 11:49:43 -0700356 deviceId, source, (nextTime - currentTime) * 0.000001);
357#endif
358 if (nextTime < *nextWakeupTime) {
359 *nextWakeupTime = nextTime;
360 }
361 if (mThrottleState.originalSampleCount == 0) {
362 mThrottleState.originalSampleCount =
363 motionEntry->countSamples();
364 }
365 return;
366 }
367 }
368
369#if DEBUG_THROTTLING
370 if (mThrottleState.originalSampleCount != 0) {
371 uint32_t count = motionEntry->countSamples();
372 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
373 count - mThrottleState.originalSampleCount,
374 mThrottleState.originalSampleCount, count);
375 mThrottleState.originalSampleCount = 0;
376 }
377#endif
378
makarand.karvekarf634ded2011-03-02 15:41:03 -0600379 mThrottleState.lastEventTime = currentTime;
Jeff Brownb88102f2010-09-08 11:49:43 -0700380 mThrottleState.lastDeviceId = deviceId;
381 mThrottleState.lastSource = source;
382 }
383
384 mInboundQueue.dequeue(entry);
385 mPendingEvent = entry;
386 }
Jeff Browne2fe69e2010-10-18 13:21:23 -0700387
388 // Poke user activity for this event.
389 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
390 pokeUserActivityLocked(mPendingEvent);
391 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700392 }
393
394 // Now we have an event to dispatch.
Jeff Brown928e0542011-01-10 11:17:36 -0800395 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Jeff Brownb6110c22011-04-01 16:15:13 -0700396 LOG_ASSERT(mPendingEvent != NULL);
Jeff Brown54a18252010-09-16 14:07:33 -0700397 bool done = false;
Jeff Brownb6997262010-10-08 22:31:17 -0700398 DropReason dropReason = DROP_REASON_NOT_DROPPED;
399 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
400 dropReason = DROP_REASON_POLICY;
401 } else if (!mDispatchEnabled) {
402 dropReason = DROP_REASON_DISABLED;
403 }
Jeff Brown928e0542011-01-10 11:17:36 -0800404
405 if (mNextUnblockedEvent == mPendingEvent) {
406 mNextUnblockedEvent = NULL;
407 }
408
Jeff Brownb88102f2010-09-08 11:49:43 -0700409 switch (mPendingEvent->type) {
410 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
411 ConfigurationChangedEntry* typedEntry =
412 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700413 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brownb6997262010-10-08 22:31:17 -0700414 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Brownb88102f2010-09-08 11:49:43 -0700415 break;
416 }
417
418 case EventEntry::TYPE_KEY: {
419 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700420 if (isAppSwitchDue) {
421 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700422 resetPendingAppSwitchLocked(true);
Jeff Brownb6997262010-10-08 22:31:17 -0700423 isAppSwitchDue = false;
424 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
425 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700426 }
427 }
Jeff Brown928e0542011-01-10 11:17:36 -0800428 if (dropReason == DROP_REASON_NOT_DROPPED
429 && isStaleEventLocked(currentTime, typedEntry)) {
430 dropReason = DROP_REASON_STALE;
431 }
432 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
433 dropReason = DROP_REASON_BLOCKED;
434 }
Jeff Brownb6997262010-10-08 22:31:17 -0700435 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Browne20c9e02010-10-11 14:20:19 -0700436 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700437 break;
438 }
439
440 case EventEntry::TYPE_MOTION: {
441 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700442 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
443 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700444 }
Jeff Brown928e0542011-01-10 11:17:36 -0800445 if (dropReason == DROP_REASON_NOT_DROPPED
446 && isStaleEventLocked(currentTime, typedEntry)) {
447 dropReason = DROP_REASON_STALE;
448 }
449 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
450 dropReason = DROP_REASON_BLOCKED;
451 }
Jeff Brownb6997262010-10-08 22:31:17 -0700452 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Browne20c9e02010-10-11 14:20:19 -0700453 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700454 break;
455 }
456
457 default:
Jeff Brownb6110c22011-04-01 16:15:13 -0700458 LOG_ASSERT(false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700459 break;
460 }
461
Jeff Brown54a18252010-09-16 14:07:33 -0700462 if (done) {
Jeff Brownb6997262010-10-08 22:31:17 -0700463 if (dropReason != DROP_REASON_NOT_DROPPED) {
464 dropInboundEventLocked(mPendingEvent, dropReason);
465 }
466
Jeff Brown54a18252010-09-16 14:07:33 -0700467 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700468 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
469 }
470}
471
472bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
473 bool needWake = mInboundQueue.isEmpty();
474 mInboundQueue.enqueueAtTail(entry);
475
476 switch (entry->type) {
Jeff Brownb6997262010-10-08 22:31:17 -0700477 case EventEntry::TYPE_KEY: {
Jeff Brown928e0542011-01-10 11:17:36 -0800478 // Optimize app switch latency.
479 // If the application takes too long to catch up then we drop all events preceding
480 // the app switch key.
Jeff Brownb6997262010-10-08 22:31:17 -0700481 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
482 if (isAppSwitchKeyEventLocked(keyEntry)) {
483 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
484 mAppSwitchSawKeyDown = true;
485 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
486 if (mAppSwitchSawKeyDown) {
487#if DEBUG_APP_SWITCH
488 LOGD("App switch is pending!");
489#endif
490 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
491 mAppSwitchSawKeyDown = false;
492 needWake = true;
493 }
494 }
495 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700496 break;
497 }
Jeff Brown928e0542011-01-10 11:17:36 -0800498
499 case EventEntry::TYPE_MOTION: {
500 // Optimize case where the current application is unresponsive and the user
501 // decides to touch a window in a different application.
502 // If the application takes too long to catch up then we drop all events preceding
503 // the touch into the other window.
504 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
Jeff Brown33bbfd22011-02-24 20:55:35 -0800505 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
Jeff Brown928e0542011-01-10 11:17:36 -0800506 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
507 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
508 && mInputTargetWaitApplication != NULL) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800509 int32_t x = int32_t(motionEntry->firstSample.pointerCoords[0].
Jeff Brownebbd5d12011-02-17 13:01:34 -0800510 getAxisValue(AMOTION_EVENT_AXIS_X));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800511 int32_t y = int32_t(motionEntry->firstSample.pointerCoords[0].
Jeff Brownebbd5d12011-02-17 13:01:34 -0800512 getAxisValue(AMOTION_EVENT_AXIS_Y));
Jeff Brown928e0542011-01-10 11:17:36 -0800513 const InputWindow* touchedWindow = findTouchedWindowAtLocked(x, y);
514 if (touchedWindow
515 && touchedWindow->inputWindowHandle != NULL
516 && touchedWindow->inputWindowHandle->getInputApplicationHandle()
517 != mInputTargetWaitApplication) {
518 // User touched a different application than the one we are waiting on.
519 // Flag the event, and start pruning the input queue.
520 mNextUnblockedEvent = motionEntry;
521 needWake = true;
522 }
523 }
524 break;
525 }
Jeff Brownb6997262010-10-08 22:31:17 -0700526 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700527
528 return needWake;
529}
530
Jeff Brown928e0542011-01-10 11:17:36 -0800531const InputWindow* InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
532 // Traverse windows from front to back to find touched window.
533 size_t numWindows = mWindows.size();
534 for (size_t i = 0; i < numWindows; i++) {
535 const InputWindow* window = & mWindows.editItemAt(i);
536 int32_t flags = window->layoutParamsFlags;
537
538 if (window->visible) {
539 if (!(flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
540 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
541 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
Jeff Brownfbf09772011-01-16 14:06:57 -0800542 if (isTouchModal || window->touchableRegionContainsPoint(x, y)) {
Jeff Brown928e0542011-01-10 11:17:36 -0800543 // Found window.
544 return window;
545 }
546 }
547 }
548
549 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
550 // Error window is on top but not visible, so touch is dropped.
551 return NULL;
552 }
553 }
554 return NULL;
555}
556
Jeff Brownb6997262010-10-08 22:31:17 -0700557void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
558 const char* reason;
559 switch (dropReason) {
560 case DROP_REASON_POLICY:
Jeff Browne20c9e02010-10-11 14:20:19 -0700561#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown3122e442010-10-11 23:32:49 -0700562 LOGD("Dropped event because policy consumed it.");
Jeff Browne20c9e02010-10-11 14:20:19 -0700563#endif
Jeff Brown3122e442010-10-11 23:32:49 -0700564 reason = "inbound event was dropped because the policy consumed it";
Jeff Brownb6997262010-10-08 22:31:17 -0700565 break;
566 case DROP_REASON_DISABLED:
567 LOGI("Dropped event because input dispatch is disabled.");
568 reason = "inbound event was dropped because input dispatch is disabled";
569 break;
570 case DROP_REASON_APP_SWITCH:
571 LOGI("Dropped event because of pending overdue app switch.");
572 reason = "inbound event was dropped because of pending overdue app switch";
573 break;
Jeff Brown928e0542011-01-10 11:17:36 -0800574 case DROP_REASON_BLOCKED:
575 LOGI("Dropped event because the current application is not responding and the user "
576 "has started interating with a different application.");
577 reason = "inbound event was dropped because the current application is not responding "
578 "and the user has started interating with a different application";
579 break;
580 case DROP_REASON_STALE:
581 LOGI("Dropped event because it is stale.");
582 reason = "inbound event was dropped because it is stale";
583 break;
Jeff Brownb6997262010-10-08 22:31:17 -0700584 default:
Jeff Brownb6110c22011-04-01 16:15:13 -0700585 LOG_ASSERT(false);
Jeff Brownb6997262010-10-08 22:31:17 -0700586 return;
587 }
588
589 switch (entry->type) {
Jeff Brownda3d5a92011-03-29 15:11:34 -0700590 case EventEntry::TYPE_KEY: {
591 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
592 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Brownb6997262010-10-08 22:31:17 -0700593 break;
Jeff Brownda3d5a92011-03-29 15:11:34 -0700594 }
Jeff Brownb6997262010-10-08 22:31:17 -0700595 case EventEntry::TYPE_MOTION: {
596 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
597 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
Jeff Brownda3d5a92011-03-29 15:11:34 -0700598 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
599 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Brownb6997262010-10-08 22:31:17 -0700600 } else {
Jeff Brownda3d5a92011-03-29 15:11:34 -0700601 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
602 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Brownb6997262010-10-08 22:31:17 -0700603 }
604 break;
605 }
606 }
607}
608
609bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700610 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
611}
612
Jeff Brownb6997262010-10-08 22:31:17 -0700613bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
614 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
615 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Browne20c9e02010-10-11 14:20:19 -0700616 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brownb6997262010-10-08 22:31:17 -0700617 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
618}
619
Jeff Brownb88102f2010-09-08 11:49:43 -0700620bool InputDispatcher::isAppSwitchPendingLocked() {
621 return mAppSwitchDueTime != LONG_LONG_MAX;
622}
623
Jeff Brownb88102f2010-09-08 11:49:43 -0700624void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
625 mAppSwitchDueTime = LONG_LONG_MAX;
626
627#if DEBUG_APP_SWITCH
628 if (handled) {
629 LOGD("App switch has arrived.");
630 } else {
631 LOGD("App switch was abandoned.");
632 }
633#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -0700634}
635
Jeff Brown928e0542011-01-10 11:17:36 -0800636bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
637 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
638}
639
Jeff Brown9c3cda02010-06-15 01:31:58 -0700640bool InputDispatcher::runCommandsLockedInterruptible() {
641 if (mCommandQueue.isEmpty()) {
642 return false;
643 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700644
Jeff Brown9c3cda02010-06-15 01:31:58 -0700645 do {
646 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
647
648 Command command = commandEntry->command;
649 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
650
Jeff Brown7fbdc842010-06-17 20:52:56 -0700651 commandEntry->connection.clear();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700652 mAllocator.releaseCommandEntry(commandEntry);
653 } while (! mCommandQueue.isEmpty());
654 return true;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700655}
656
Jeff Brown9c3cda02010-06-15 01:31:58 -0700657InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
658 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
659 mCommandQueue.enqueueAtTail(commandEntry);
660 return commandEntry;
661}
662
Jeff Brownb88102f2010-09-08 11:49:43 -0700663void InputDispatcher::drainInboundQueueLocked() {
664 while (! mInboundQueue.isEmpty()) {
665 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700666 releaseInboundEventLocked(entry);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700667 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700668}
669
Jeff Brown54a18252010-09-16 14:07:33 -0700670void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700671 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700672 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700673 mPendingEvent = NULL;
674 }
675}
676
Jeff Brown54a18252010-09-16 14:07:33 -0700677void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700678 InjectionState* injectionState = entry->injectionState;
679 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700680#if DEBUG_DISPATCH_CYCLE
Jeff Brown01ce2e92010-09-26 22:20:12 -0700681 LOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700682#endif
683 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
684 }
685 mAllocator.releaseEventEntry(entry);
686}
687
Jeff Brownb88102f2010-09-08 11:49:43 -0700688void InputDispatcher::resetKeyRepeatLocked() {
689 if (mKeyRepeatState.lastKeyEntry) {
690 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
691 mKeyRepeatState.lastKeyEntry = NULL;
692 }
693}
694
695InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brownb21fb102010-09-07 10:44:57 -0700696 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown349703e2010-06-22 01:27:15 -0700697 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
698
Jeff Brown349703e2010-06-22 01:27:15 -0700699 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Browne20c9e02010-10-11 14:20:19 -0700700 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
701 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700702 if (entry->refCount == 1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700703 mAllocator.recycleKeyEntry(entry);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700704 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700705 entry->policyFlags = policyFlags;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700706 entry->repeatCount += 1;
707 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700708 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700709 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700710 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700711 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700712
713 mKeyRepeatState.lastKeyEntry = newEntry;
714 mAllocator.releaseKeyEntry(entry);
715
716 entry = newEntry;
717 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700718 entry->syntheticRepeat = true;
719
720 // Increment reference count since we keep a reference to the event in
721 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
722 entry->refCount += 1;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700723
Jeff Brownb21fb102010-09-07 10:44:57 -0700724 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700725 return entry;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700726}
727
Jeff Brownb88102f2010-09-08 11:49:43 -0700728bool InputDispatcher::dispatchConfigurationChangedLocked(
729 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700730#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownb88102f2010-09-08 11:49:43 -0700731 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
732#endif
733
734 // Reset key repeating in case a keyboard device was added or removed or something.
735 resetKeyRepeatLocked();
736
737 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
738 CommandEntry* commandEntry = postCommandLocked(
739 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
740 commandEntry->eventTime = entry->eventTime;
741 return true;
742}
743
744bool InputDispatcher::dispatchKeyLocked(
745 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Browne20c9e02010-10-11 14:20:19 -0700746 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700747 // Preprocessing.
748 if (! entry->dispatchInProgress) {
749 if (entry->repeatCount == 0
750 && entry->action == AKEY_EVENT_ACTION_DOWN
751 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brown0029c662011-03-30 02:25:18 -0700752 && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700753 if (mKeyRepeatState.lastKeyEntry
754 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
755 // We have seen two identical key downs in a row which indicates that the device
756 // driver is automatically generating key repeats itself. We take note of the
757 // repeat here, but we disable our own next key repeat timer since it is clear that
758 // we will not need to synthesize key repeats ourselves.
759 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
760 resetKeyRepeatLocked();
761 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
762 } else {
763 // Not a repeat. Save key down state in case we do see a repeat later.
764 resetKeyRepeatLocked();
765 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
766 }
767 mKeyRepeatState.lastKeyEntry = entry;
768 entry->refCount += 1;
769 } else if (! entry->syntheticRepeat) {
770 resetKeyRepeatLocked();
771 }
772
Jeff Browne2e01262011-03-02 20:34:30 -0800773 if (entry->repeatCount == 1) {
774 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
775 } else {
776 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
777 }
778
Jeff Browne46a0a42010-11-02 17:58:22 -0700779 entry->dispatchInProgress = true;
780 resetTargetsLocked();
781
782 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
783 }
784
Jeff Brown54a18252010-09-16 14:07:33 -0700785 // Give the policy a chance to intercept the key.
786 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700787 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brown54a18252010-09-16 14:07:33 -0700788 CommandEntry* commandEntry = postCommandLocked(
789 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Browne20c9e02010-10-11 14:20:19 -0700790 if (mFocusedWindow) {
Jeff Brown928e0542011-01-10 11:17:36 -0800791 commandEntry->inputWindowHandle = mFocusedWindow->inputWindowHandle;
Jeff Brown54a18252010-09-16 14:07:33 -0700792 }
793 commandEntry->keyEntry = entry;
794 entry->refCount += 1;
795 return false; // wait for the command to run
796 } else {
797 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
798 }
799 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700800 if (*dropReason == DROP_REASON_NOT_DROPPED) {
801 *dropReason = DROP_REASON_POLICY;
802 }
Jeff Brown54a18252010-09-16 14:07:33 -0700803 }
804
805 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700806 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700807 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700808 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
809 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700810 return true;
811 }
812
Jeff Brownb88102f2010-09-08 11:49:43 -0700813 // Identify targets.
814 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700815 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
816 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700817 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
818 return false;
819 }
820
821 setInjectionResultLocked(entry, injectionResult);
822 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
823 return true;
824 }
825
826 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700827 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700828 }
829
830 // Dispatch the key.
831 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700832 return true;
833}
834
835void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
836#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800837 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brownb88102f2010-09-08 11:49:43 -0700838 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
Jeff Browne46a0a42010-11-02 17:58:22 -0700839 "repeatCount=%d, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700840 prefix,
841 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
842 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Jeff Browne46a0a42010-11-02 17:58:22 -0700843 entry->repeatCount, entry->downTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700844#endif
845}
846
847bool InputDispatcher::dispatchMotionLocked(
Jeff Browne20c9e02010-10-11 14:20:19 -0700848 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700849 // Preprocessing.
850 if (! entry->dispatchInProgress) {
851 entry->dispatchInProgress = true;
852 resetTargetsLocked();
853
854 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
855 }
856
Jeff Brown54a18252010-09-16 14:07:33 -0700857 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700858 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700859 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700860 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
861 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700862 return true;
863 }
864
Jeff Brownb88102f2010-09-08 11:49:43 -0700865 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
866
867 // Identify targets.
Jeff Browncc0c1592011-02-19 05:07:28 -0800868 bool conflictingPointerActions = false;
Jeff Brownb88102f2010-09-08 11:49:43 -0700869 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700870 int32_t injectionResult;
Jeff Browna032cc02011-03-07 16:56:21 -0800871 const MotionSample* splitBatchAfterSample = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -0700872 if (isPointerEvent) {
873 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700874 injectionResult = findTouchedWindowTargetsLocked(currentTime,
Jeff Browna032cc02011-03-07 16:56:21 -0800875 entry, nextWakeupTime, &conflictingPointerActions, &splitBatchAfterSample);
Jeff Brownb88102f2010-09-08 11:49:43 -0700876 } else {
877 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700878 injectionResult = findFocusedWindowTargetsLocked(currentTime,
879 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700880 }
881 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
882 return false;
883 }
884
885 setInjectionResultLocked(entry, injectionResult);
886 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
887 return true;
888 }
889
890 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700891 commitTargetsLocked();
Jeff Browna032cc02011-03-07 16:56:21 -0800892
893 // Unbatch the event if necessary by splitting it into two parts after the
894 // motion sample indicated by splitBatchAfterSample.
895 if (splitBatchAfterSample && splitBatchAfterSample->next) {
896#if DEBUG_BATCHING
897 uint32_t originalSampleCount = entry->countSamples();
898#endif
899 MotionSample* nextSample = splitBatchAfterSample->next;
900 MotionEntry* nextEntry = mAllocator.obtainMotionEntry(nextSample->eventTime,
901 entry->deviceId, entry->source, entry->policyFlags,
902 entry->action, entry->flags, entry->metaState, entry->edgeFlags,
903 entry->xPrecision, entry->yPrecision, entry->downTime,
904 entry->pointerCount, entry->pointerIds, nextSample->pointerCoords);
905 if (nextSample != entry->lastSample) {
906 nextEntry->firstSample.next = nextSample->next;
907 nextEntry->lastSample = entry->lastSample;
908 }
909 mAllocator.freeMotionSample(nextSample);
910
911 entry->lastSample = const_cast<MotionSample*>(splitBatchAfterSample);
912 entry->lastSample->next = NULL;
913
914 if (entry->injectionState) {
915 nextEntry->injectionState = entry->injectionState;
916 entry->injectionState->refCount += 1;
917 }
918
919#if DEBUG_BATCHING
920 LOGD("Split batch of %d samples into two parts, first part has %d samples, "
921 "second part has %d samples.", originalSampleCount,
922 entry->countSamples(), nextEntry->countSamples());
923#endif
924
925 mInboundQueue.enqueueAtHead(nextEntry);
926 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700927 }
928
929 // Dispatch the motion.
Jeff Browncc0c1592011-02-19 05:07:28 -0800930 if (conflictingPointerActions) {
Jeff Brownda3d5a92011-03-29 15:11:34 -0700931 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
932 "conflicting pointer actions");
933 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Browncc0c1592011-02-19 05:07:28 -0800934 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700935 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700936 return true;
937}
938
939
940void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
941#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800942 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700943 "action=0x%x, flags=0x%x, "
Jeff Brown46b9ac02010-04-22 18:58:52 -0700944 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700945 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700946 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
947 entry->action, entry->flags,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700948 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
949 entry->downTime);
950
951 // Print the most recent sample that we have available, this may change due to batching.
952 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700953 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700954 for (; sample->next != NULL; sample = sample->next) {
955 sampleCount += 1;
956 }
957 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -0700958 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700959 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700960 "orientation=%f",
Jeff Brown46b9ac02010-04-22 18:58:52 -0700961 i, entry->pointerIds[i],
Jeff Brownebbd5d12011-02-17 13:01:34 -0800962 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
963 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
964 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
965 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
966 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
967 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
968 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
969 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
970 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Jeff Brown46b9ac02010-04-22 18:58:52 -0700971 }
972
973 // Keep in mind that due to batching, it is possible for the number of samples actually
974 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700975 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700976 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
977 }
978#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -0700979}
980
981void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
982 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
983#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -0700984 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac02010-04-22 18:58:52 -0700985 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700986 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac02010-04-22 18:58:52 -0700987#endif
988
Jeff Brownb6110c22011-04-01 16:15:13 -0700989 LOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
Jeff Brown9c3cda02010-06-15 01:31:58 -0700990
Jeff Browne2fe69e2010-10-18 13:21:23 -0700991 pokeUserActivityLocked(eventEntry);
992
Jeff Brown46b9ac02010-04-22 18:58:52 -0700993 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
994 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
995
Jeff Brown519e0242010-09-15 15:18:56 -0700996 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700997 if (connectionIndex >= 0) {
998 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700999 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001000 resumeWithAppendedMotionSample);
1001 } else {
Jeff Brownb6997262010-10-08 22:31:17 -07001002#if DEBUG_FOCUS
1003 LOGD("Dropping event delivery to target with channel '%s' because it "
1004 "is no longer registered with the input dispatcher.",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001005 inputTarget.inputChannel->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -07001006#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -07001007 }
1008 }
1009}
1010
Jeff Brown54a18252010-09-16 14:07:33 -07001011void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -07001012 mCurrentInputTargetsValid = false;
1013 mCurrentInputTargets.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -07001014 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Jeff Brown928e0542011-01-10 11:17:36 -08001015 mInputTargetWaitApplication.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -07001016}
1017
Jeff Brown01ce2e92010-09-26 22:20:12 -07001018void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -07001019 mCurrentInputTargetsValid = true;
1020}
1021
1022int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
1023 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
1024 nsecs_t* nextWakeupTime) {
1025 if (application == NULL && window == NULL) {
1026 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
1027#if DEBUG_FOCUS
1028 LOGD("Waiting for system to become ready for input.");
1029#endif
1030 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1031 mInputTargetWaitStartTime = currentTime;
1032 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1033 mInputTargetWaitTimeoutExpired = false;
Jeff Brown928e0542011-01-10 11:17:36 -08001034 mInputTargetWaitApplication.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -07001035 }
1036 } else {
1037 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1038#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -07001039 LOGD("Waiting for application to become ready for input: %s",
1040 getApplicationWindowLabelLocked(application, window).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001041#endif
1042 nsecs_t timeout = window ? window->dispatchingTimeout :
1043 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1044
1045 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1046 mInputTargetWaitStartTime = currentTime;
1047 mInputTargetWaitTimeoutTime = currentTime + timeout;
1048 mInputTargetWaitTimeoutExpired = false;
Jeff Brown928e0542011-01-10 11:17:36 -08001049 mInputTargetWaitApplication.clear();
1050
1051 if (window && window->inputWindowHandle != NULL) {
1052 mInputTargetWaitApplication =
1053 window->inputWindowHandle->getInputApplicationHandle();
1054 }
1055 if (mInputTargetWaitApplication == NULL && application) {
1056 mInputTargetWaitApplication = application->inputApplicationHandle;
1057 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001058 }
1059 }
1060
1061 if (mInputTargetWaitTimeoutExpired) {
1062 return INPUT_EVENT_INJECTION_TIMED_OUT;
1063 }
1064
1065 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown519e0242010-09-15 15:18:56 -07001066 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001067
1068 // Force poll loop to wake up immediately on next iteration once we get the
1069 // ANR response back from the policy.
1070 *nextWakeupTime = LONG_LONG_MIN;
1071 return INPUT_EVENT_INJECTION_PENDING;
1072 } else {
1073 // Force poll loop to wake up when timeout is due.
1074 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1075 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1076 }
1077 return INPUT_EVENT_INJECTION_PENDING;
1078 }
1079}
1080
Jeff Brown519e0242010-09-15 15:18:56 -07001081void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1082 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001083 if (newTimeout > 0) {
1084 // Extend the timeout.
1085 mInputTargetWaitTimeoutTime = now() + newTimeout;
1086 } else {
1087 // Give up.
1088 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -07001089
Jeff Brown01ce2e92010-09-26 22:20:12 -07001090 // Release the touch targets.
1091 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07001092
Jeff Brown519e0242010-09-15 15:18:56 -07001093 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -07001094 if (inputChannel.get()) {
1095 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1096 if (connectionIndex >= 0) {
1097 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown00045a72010-12-09 18:10:30 -08001098 if (connection->status == Connection::STATUS_NORMAL) {
Jeff Brownda3d5a92011-03-29 15:11:34 -07001099 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
Jeff Brown00045a72010-12-09 18:10:30 -08001100 "application not responding");
Jeff Brownda3d5a92011-03-29 15:11:34 -07001101 synthesizeCancelationEventsForConnectionLocked(connection, options);
Jeff Brown00045a72010-12-09 18:10:30 -08001102 }
Jeff Browndc3e0052010-09-16 11:02:16 -07001103 }
Jeff Brown519e0242010-09-15 15:18:56 -07001104 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001105 }
1106}
1107
Jeff Brown519e0242010-09-15 15:18:56 -07001108nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -07001109 nsecs_t currentTime) {
1110 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1111 return currentTime - mInputTargetWaitStartTime;
1112 }
1113 return 0;
1114}
1115
1116void InputDispatcher::resetANRTimeoutsLocked() {
1117#if DEBUG_FOCUS
1118 LOGD("Resetting ANR timeouts.");
1119#endif
1120
Jeff Brownb88102f2010-09-08 11:49:43 -07001121 // Reset input target wait timeout.
1122 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
1123}
1124
Jeff Brown01ce2e92010-09-26 22:20:12 -07001125int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
1126 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001127 mCurrentInputTargets.clear();
1128
1129 int32_t injectionResult;
1130
1131 // If there is no currently focused window and no focused application
1132 // then drop the event.
1133 if (! mFocusedWindow) {
1134 if (mFocusedApplication) {
1135#if DEBUG_FOCUS
1136 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001137 "focused application that may eventually add a window: %s.",
1138 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001139#endif
1140 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1141 mFocusedApplication, NULL, nextWakeupTime);
1142 goto Unresponsive;
1143 }
1144
1145 LOGI("Dropping event because there is no focused window or focused application.");
1146 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1147 goto Failed;
1148 }
1149
1150 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001151 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001152 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1153 goto Failed;
1154 }
1155
1156 // If the currently focused window is paused then keep waiting.
1157 if (mFocusedWindow->paused) {
1158#if DEBUG_FOCUS
1159 LOGD("Waiting because focused window is paused.");
1160#endif
1161 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1162 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1163 goto Unresponsive;
1164 }
1165
Jeff Brown519e0242010-09-15 15:18:56 -07001166 // If the currently focused window is still working on previous events then keep waiting.
1167 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
1168#if DEBUG_FOCUS
1169 LOGD("Waiting because focused window still processing previous input.");
1170#endif
1171 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1172 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1173 goto Unresponsive;
1174 }
1175
Jeff Brownb88102f2010-09-08 11:49:43 -07001176 // Success! Output targets.
1177 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Browna032cc02011-03-07 16:56:21 -08001178 addWindowTargetLocked(mFocusedWindow,
1179 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001180
1181 // Done.
1182Failed:
1183Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001184 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1185 updateDispatchStatisticsLocked(currentTime, entry,
1186 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001187#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -07001188 LOGD("findFocusedWindow finished: injectionResult=%d, "
1189 "timeSpendWaitingForApplication=%0.1fms",
1190 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001191#endif
1192 return injectionResult;
1193}
1194
Jeff Brown01ce2e92010-09-26 22:20:12 -07001195int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Jeff Browna032cc02011-03-07 16:56:21 -08001196 const MotionEntry* entry, nsecs_t* nextWakeupTime, bool* outConflictingPointerActions,
1197 const MotionSample** outSplitBatchAfterSample) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001198 enum InjectionPermission {
1199 INJECTION_PERMISSION_UNKNOWN,
1200 INJECTION_PERMISSION_GRANTED,
1201 INJECTION_PERMISSION_DENIED
1202 };
1203
Jeff Brownb88102f2010-09-08 11:49:43 -07001204 mCurrentInputTargets.clear();
1205
1206 nsecs_t startTime = now();
1207
1208 // For security reasons, we defer updating the touch state until we are sure that
1209 // event injection will be allowed.
1210 //
1211 // FIXME In the original code, screenWasOff could never be set to true.
1212 // The reason is that the POLICY_FLAG_WOKE_HERE
1213 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1214 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1215 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1216 // events upon which no preprocessing took place. So policyFlags was always 0.
1217 // In the new native input dispatcher we're a bit more careful about event
1218 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1219 // Unfortunately we obtain undesirable behavior.
1220 //
1221 // Here's what happens:
1222 //
1223 // When the device dims in anticipation of going to sleep, touches
1224 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1225 // the device to brighten and reset the user activity timer.
1226 // Touches on other windows (such as the launcher window)
1227 // are dropped. Then after a moment, the device goes to sleep. Oops.
1228 //
1229 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1230 // instead of POLICY_FLAG_WOKE_HERE...
1231 //
1232 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1233
1234 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001235 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001236
1237 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001238 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1239 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Jeff Browna032cc02011-03-07 16:56:21 -08001240 const InputWindow* newHoverWindow = NULL;
Jeff Browncc0c1592011-02-19 05:07:28 -08001241
1242 bool isSplit = mTouchState.split;
1243 bool wrongDevice = mTouchState.down
1244 && (mTouchState.deviceId != entry->deviceId
1245 || mTouchState.source != entry->source);
Jeff Browna032cc02011-03-07 16:56:21 -08001246 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1247 || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1248 || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1249 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
1250 || maskedAction == AMOTION_EVENT_ACTION_SCROLL
1251 || isHoverAction);
1252 if (newGesture) {
Jeff Browncc0c1592011-02-19 05:07:28 -08001253 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
1254 if (wrongDevice && !down) {
1255 mTempTouchState.copyFrom(mTouchState);
1256 } else {
1257 mTempTouchState.reset();
1258 mTempTouchState.down = down;
1259 mTempTouchState.deviceId = entry->deviceId;
1260 mTempTouchState.source = entry->source;
1261 isSplit = false;
1262 wrongDevice = false;
1263 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001264 } else {
1265 mTempTouchState.copyFrom(mTouchState);
Jeff Browncc0c1592011-02-19 05:07:28 -08001266 }
1267 if (wrongDevice) {
Jeff Browna2cc28d2011-03-25 11:58:46 -07001268#if DEBUG_FOCUS
Jeff Browncc0c1592011-02-19 05:07:28 -08001269 LOGD("Dropping event because a pointer for a different device is already down.");
Jeff Brown95712852011-01-04 19:41:59 -08001270#endif
Jeff Browncc0c1592011-02-19 05:07:28 -08001271 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1272 goto Failed;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001273 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001274
Jeff Browna032cc02011-03-07 16:56:21 -08001275 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
Jeff Brown33bbfd22011-02-24 20:55:35 -08001276 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001277
Jeff Browna032cc02011-03-07 16:56:21 -08001278 const MotionSample* sample = &entry->firstSample;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001279 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Jeff Browna032cc02011-03-07 16:56:21 -08001280 int32_t x = int32_t(sample->pointerCoords[pointerIndex].
Jeff Brownebbd5d12011-02-17 13:01:34 -08001281 getAxisValue(AMOTION_EVENT_AXIS_X));
Jeff Browna032cc02011-03-07 16:56:21 -08001282 int32_t y = int32_t(sample->pointerCoords[pointerIndex].
Jeff Brownebbd5d12011-02-17 13:01:34 -08001283 getAxisValue(AMOTION_EVENT_AXIS_Y));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001284 const InputWindow* newTouchedWindow = NULL;
1285 const InputWindow* topErrorWindow = NULL;
Jeff Browna032cc02011-03-07 16:56:21 -08001286 bool isTouchModal = false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001287
1288 // Traverse windows from front to back to find touched window and outside targets.
1289 size_t numWindows = mWindows.size();
1290 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001291 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001292 int32_t flags = window->layoutParamsFlags;
1293
1294 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1295 if (! topErrorWindow) {
1296 topErrorWindow = window;
1297 }
1298 }
1299
1300 if (window->visible) {
1301 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
Jeff Browna032cc02011-03-07 16:56:21 -08001302 isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
Jeff Brownb88102f2010-09-08 11:49:43 -07001303 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
Jeff Brownfbf09772011-01-16 14:06:57 -08001304 if (isTouchModal || window->touchableRegionContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001305 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1306 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001307 }
1308 break; // found touched window, exit window loop
1309 }
1310 }
1311
Jeff Brown01ce2e92010-09-26 22:20:12 -07001312 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1313 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Browna032cc02011-03-07 16:56:21 -08001314 int32_t outsideTargetFlags = InputTarget::FLAG_DISPATCH_AS_OUTSIDE;
Jeff Brown19dfc832010-10-05 12:26:23 -07001315 if (isWindowObscuredAtPointLocked(window, x, y)) {
1316 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1317 }
1318
1319 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001320 }
1321 }
1322 }
1323
1324 // If there is an error window but it is not taking focus (typically because
1325 // it is invisible) then wait for it. Any other focused window may in
1326 // fact be in ANR state.
1327 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1328#if DEBUG_FOCUS
1329 LOGD("Waiting because system error window is pending.");
1330#endif
1331 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1332 NULL, NULL, nextWakeupTime);
1333 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1334 goto Unresponsive;
1335 }
1336
Jeff Brown01ce2e92010-09-26 22:20:12 -07001337 // Figure out whether splitting will be allowed for this window.
Jeff Brown46e75292010-11-10 16:53:45 -08001338 if (newTouchedWindow && newTouchedWindow->supportsSplitTouch()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001339 // New window supports splitting.
1340 isSplit = true;
1341 } else if (isSplit) {
1342 // New window does not support splitting but we have already split events.
1343 // Assign the pointer to the first foreground window we find.
1344 // (May be NULL which is why we put this code block before the next check.)
1345 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1346 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001347
Jeff Brownb88102f2010-09-08 11:49:43 -07001348 // If we did not find a touched window then fail.
1349 if (! newTouchedWindow) {
1350 if (mFocusedApplication) {
1351#if DEBUG_FOCUS
1352 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001353 "focused application that may eventually add a new window: %s.",
1354 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001355#endif
1356 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1357 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001358 goto Unresponsive;
1359 }
1360
1361 LOGI("Dropping event because there is no touched window or focused application.");
1362 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001363 goto Failed;
1364 }
1365
Jeff Brown19dfc832010-10-05 12:26:23 -07001366 // Set target flags.
Jeff Browna032cc02011-03-07 16:56:21 -08001367 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
Jeff Brown19dfc832010-10-05 12:26:23 -07001368 if (isSplit) {
1369 targetFlags |= InputTarget::FLAG_SPLIT;
1370 }
1371 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1372 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1373 }
1374
Jeff Browna032cc02011-03-07 16:56:21 -08001375 // Update hover state.
1376 if (isHoverAction) {
1377 newHoverWindow = newTouchedWindow;
1378
1379 // Ensure all subsequent motion samples are also within the touched window.
1380 // Set *outSplitBatchAfterSample to the sample before the first one that is not
1381 // within the touched window.
1382 if (!isTouchModal) {
1383 while (sample->next) {
1384 if (!newHoverWindow->touchableRegionContainsPoint(
1385 sample->next->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X),
1386 sample->next->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y))) {
1387 *outSplitBatchAfterSample = sample;
1388 break;
1389 }
1390 sample = sample->next;
1391 }
1392 }
1393 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1394 newHoverWindow = mLastHoverWindow;
1395 }
1396
Jeff Brown01ce2e92010-09-26 22:20:12 -07001397 // Update the temporary touch state.
1398 BitSet32 pointerIds;
1399 if (isSplit) {
1400 uint32_t pointerId = entry->pointerIds[pointerIndex];
1401 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001402 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001403 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001404 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001405 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001406
1407 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001408 if (! mTempTouchState.down) {
Jeff Browna2cc28d2011-03-25 11:58:46 -07001409#if DEBUG_FOCUS
Jeff Brown76860e32010-10-25 17:37:46 -07001410 LOGD("Dropping event because the pointer is not down or we previously "
1411 "dropped the pointer down event.");
1412#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001413 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001414 goto Failed;
1415 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001416 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001417
Jeff Browna032cc02011-03-07 16:56:21 -08001418 if (newHoverWindow != mLastHoverWindow) {
1419 // Split the batch here so we send exactly one sample as part of ENTER or EXIT.
1420 *outSplitBatchAfterSample = &entry->firstSample;
1421
1422 // Let the previous window know that the hover sequence is over.
1423 if (mLastHoverWindow) {
1424#if DEBUG_HOVER
1425 LOGD("Sending hover exit event to window %s.", mLastHoverWindow->name.string());
1426#endif
1427 mTempTouchState.addOrUpdateWindow(mLastHoverWindow,
1428 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
1429 }
1430
1431 // Let the new window know that the hover sequence is starting.
1432 if (newHoverWindow) {
1433#if DEBUG_HOVER
1434 LOGD("Sending hover enter event to window %s.", newHoverWindow->name.string());
1435#endif
1436 mTempTouchState.addOrUpdateWindow(newHoverWindow,
1437 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
1438 }
1439 }
1440
Jeff Brown01ce2e92010-09-26 22:20:12 -07001441 // Check permission to inject into all touched foreground windows and ensure there
1442 // is at least one touched foreground window.
1443 {
1444 bool haveForegroundWindow = false;
1445 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1446 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1447 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1448 haveForegroundWindow = true;
1449 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1450 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1451 injectionPermission = INJECTION_PERMISSION_DENIED;
1452 goto Failed;
1453 }
1454 }
1455 }
1456 if (! haveForegroundWindow) {
Jeff Browna2cc28d2011-03-25 11:58:46 -07001457#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001458 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001459#endif
1460 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001461 goto Failed;
1462 }
1463
Jeff Brown01ce2e92010-09-26 22:20:12 -07001464 // Permission granted to injection into all touched foreground windows.
1465 injectionPermission = INJECTION_PERMISSION_GRANTED;
1466 }
Jeff Brown519e0242010-09-15 15:18:56 -07001467
Jeff Brown01ce2e92010-09-26 22:20:12 -07001468 // Ensure all touched foreground windows are ready for new input.
1469 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1470 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1471 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1472 // If the touched window is paused then keep waiting.
1473 if (touchedWindow.window->paused) {
Jeff Browna2cc28d2011-03-25 11:58:46 -07001474#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001475 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001476#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001477 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1478 NULL, touchedWindow.window, nextWakeupTime);
1479 goto Unresponsive;
1480 }
1481
1482 // If the touched window is still working on previous events then keep waiting.
1483 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1484#if DEBUG_FOCUS
1485 LOGD("Waiting because touched window still processing previous input.");
1486#endif
1487 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1488 NULL, touchedWindow.window, nextWakeupTime);
1489 goto Unresponsive;
1490 }
1491 }
1492 }
1493
1494 // If this is the first pointer going down and the touched window has a wallpaper
1495 // then also add the touched wallpaper windows so they are locked in for the duration
1496 // of the touch gesture.
Jeff Brown33bbfd22011-02-24 20:55:35 -08001497 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1498 // engine only supports touch events. We would need to add a mechanism similar
1499 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1500 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001501 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1502 if (foregroundWindow->hasWallpaper) {
1503 for (size_t i = 0; i < mWindows.size(); i++) {
1504 const InputWindow* window = & mWindows[i];
1505 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001506 mTempTouchState.addOrUpdateWindow(window,
Jeff Browna032cc02011-03-07 16:56:21 -08001507 InputTarget::FLAG_WINDOW_IS_OBSCURED
1508 | InputTarget::FLAG_DISPATCH_AS_IS,
1509 BitSet32(0));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001510 }
1511 }
1512 }
1513 }
1514
Jeff Brownb88102f2010-09-08 11:49:43 -07001515 // Success! Output targets.
1516 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001517
Jeff Brown01ce2e92010-09-26 22:20:12 -07001518 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1519 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1520 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1521 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001522 }
1523
Jeff Browna032cc02011-03-07 16:56:21 -08001524 // Drop the outside or hover touch windows since we will not care about them
1525 // in the next iteration.
1526 mTempTouchState.filterNonAsIsTouchWindows();
Jeff Brown01ce2e92010-09-26 22:20:12 -07001527
Jeff Brownb88102f2010-09-08 11:49:43 -07001528Failed:
1529 // Check injection permission once and for all.
1530 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001531 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001532 injectionPermission = INJECTION_PERMISSION_GRANTED;
1533 } else {
1534 injectionPermission = INJECTION_PERMISSION_DENIED;
1535 }
1536 }
1537
1538 // Update final pieces of touch state if the injector had permission.
1539 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown95712852011-01-04 19:41:59 -08001540 if (!wrongDevice) {
1541 if (maskedAction == AMOTION_EVENT_ACTION_UP
Jeff Browncc0c1592011-02-19 05:07:28 -08001542 || maskedAction == AMOTION_EVENT_ACTION_CANCEL
Jeff Browna032cc02011-03-07 16:56:21 -08001543 || isHoverAction) {
Jeff Brown95712852011-01-04 19:41:59 -08001544 // All pointers up or canceled.
Jeff Brown33bbfd22011-02-24 20:55:35 -08001545 mTouchState.reset();
Jeff Brown95712852011-01-04 19:41:59 -08001546 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1547 // First pointer went down.
1548 if (mTouchState.down) {
Jeff Browncc0c1592011-02-19 05:07:28 -08001549 *outConflictingPointerActions = true;
Jeff Brownb6997262010-10-08 22:31:17 -07001550#if DEBUG_FOCUS
Jeff Brown95712852011-01-04 19:41:59 -08001551 LOGD("Pointer down received while already down.");
Jeff Brownb6997262010-10-08 22:31:17 -07001552#endif
Jeff Brown95712852011-01-04 19:41:59 -08001553 }
Jeff Brown33bbfd22011-02-24 20:55:35 -08001554 mTouchState.copyFrom(mTempTouchState);
Jeff Brown95712852011-01-04 19:41:59 -08001555 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1556 // One pointer went up.
1557 if (isSplit) {
1558 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1559 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001560
Jeff Brown95712852011-01-04 19:41:59 -08001561 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1562 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1563 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1564 touchedWindow.pointerIds.clearBit(pointerId);
1565 if (touchedWindow.pointerIds.isEmpty()) {
1566 mTempTouchState.windows.removeAt(i);
1567 continue;
1568 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001569 }
Jeff Brown95712852011-01-04 19:41:59 -08001570 i += 1;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001571 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001572 }
Jeff Brown33bbfd22011-02-24 20:55:35 -08001573 mTouchState.copyFrom(mTempTouchState);
1574 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1575 // Discard temporary touch state since it was only valid for this action.
1576 } else {
1577 // Save changes to touch state as-is for all other actions.
1578 mTouchState.copyFrom(mTempTouchState);
Jeff Brownb88102f2010-09-08 11:49:43 -07001579 }
Jeff Browna032cc02011-03-07 16:56:21 -08001580
1581 // Update hover state.
1582 mLastHoverWindow = newHoverWindow;
Jeff Brown95712852011-01-04 19:41:59 -08001583 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001584 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001585#if DEBUG_FOCUS
1586 LOGD("Not updating touch focus because injection was denied.");
1587#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001588 }
1589
1590Unresponsive:
Jeff Brown120a4592010-10-27 18:43:51 -07001591 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1592 mTempTouchState.reset();
1593
Jeff Brown519e0242010-09-15 15:18:56 -07001594 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1595 updateDispatchStatisticsLocked(currentTime, entry,
1596 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001597#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001598 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1599 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001600 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001601#endif
1602 return injectionResult;
1603}
1604
Jeff Brown01ce2e92010-09-26 22:20:12 -07001605void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1606 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001607 mCurrentInputTargets.push();
1608
1609 InputTarget& target = mCurrentInputTargets.editTop();
1610 target.inputChannel = window->inputChannel;
1611 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001612 target.xOffset = - window->frameLeft;
1613 target.yOffset = - window->frameTop;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001614 target.scaleFactor = window->scaleFactor;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001615 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001616}
1617
1618void InputDispatcher::addMonitoringTargetsLocked() {
1619 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1620 mCurrentInputTargets.push();
1621
1622 InputTarget& target = mCurrentInputTargets.editTop();
1623 target.inputChannel = mMonitoringChannels[i];
Jeff Brownb6110c22011-04-01 16:15:13 -07001624 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Jeff Brownb88102f2010-09-08 11:49:43 -07001625 target.xOffset = 0;
1626 target.yOffset = 0;
Jeff Brownb6110c22011-04-01 16:15:13 -07001627 target.pointerIds.clear();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001628 target.scaleFactor = 1.0f;
Jeff Brownb88102f2010-09-08 11:49:43 -07001629 }
1630}
1631
1632bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001633 const InjectionState* injectionState) {
1634 if (injectionState
Jeff Brownb6997262010-10-08 22:31:17 -07001635 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1636 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1637 if (window) {
1638 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1639 "with input channel %s owned by uid %d",
1640 injectionState->injectorPid, injectionState->injectorUid,
1641 window->inputChannel->getName().string(),
1642 window->ownerUid);
1643 } else {
1644 LOGW("Permission denied: injecting event from pid %d uid %d",
1645 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001646 }
Jeff Brownb6997262010-10-08 22:31:17 -07001647 return false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001648 }
1649 return true;
1650}
1651
Jeff Brown19dfc832010-10-05 12:26:23 -07001652bool InputDispatcher::isWindowObscuredAtPointLocked(
1653 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07001654 size_t numWindows = mWindows.size();
1655 for (size_t i = 0; i < numWindows; i++) {
1656 const InputWindow* other = & mWindows.itemAt(i);
1657 if (other == window) {
1658 break;
1659 }
Jeff Brown19dfc832010-10-05 12:26:23 -07001660 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001661 return true;
1662 }
1663 }
1664 return false;
1665}
1666
Jeff Brown519e0242010-09-15 15:18:56 -07001667bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1668 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1669 if (connectionIndex >= 0) {
1670 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1671 return connection->outboundQueue.isEmpty();
1672 } else {
1673 return true;
1674 }
1675}
1676
1677String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1678 const InputWindow* window) {
1679 if (application) {
1680 if (window) {
1681 String8 label(application->name);
1682 label.append(" - ");
1683 label.append(window->name);
1684 return label;
1685 } else {
1686 return application->name;
1687 }
1688 } else if (window) {
1689 return window->name;
1690 } else {
1691 return String8("<unknown application or window>");
1692 }
1693}
1694
Jeff Browne2fe69e2010-10-18 13:21:23 -07001695void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
Jeff Brown56194eb2011-03-02 19:23:13 -08001696 int32_t eventType = POWER_MANAGER_OTHER_EVENT;
Jeff Brown4d396052010-10-29 21:50:21 -07001697 switch (eventEntry->type) {
1698 case EventEntry::TYPE_MOTION: {
Jeff Browne2fe69e2010-10-18 13:21:23 -07001699 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Brown4d396052010-10-29 21:50:21 -07001700 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1701 return;
1702 }
1703
Jeff Brown56194eb2011-03-02 19:23:13 -08001704 if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
Joe Onorato1a542c72010-11-08 09:48:20 -08001705 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001706 }
Jeff Brown4d396052010-10-29 21:50:21 -07001707 break;
1708 }
1709 case EventEntry::TYPE_KEY: {
1710 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1711 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1712 return;
1713 }
Jeff Brown56194eb2011-03-02 19:23:13 -08001714 eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brown4d396052010-10-29 21:50:21 -07001715 break;
1716 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001717 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001718
Jeff Brownb88102f2010-09-08 11:49:43 -07001719 CommandEntry* commandEntry = postCommandLocked(
1720 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Browne2fe69e2010-10-18 13:21:23 -07001721 commandEntry->eventTime = eventEntry->eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001722 commandEntry->userActivityEventType = eventType;
1723}
1724
Jeff Brown7fbdc842010-06-17 20:52:56 -07001725void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1726 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001727 bool resumeWithAppendedMotionSample) {
1728#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001729 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001730 "xOffset=%f, yOffset=%f, scaleFactor=%f"
Jeff Brown83c09682010-12-23 17:50:18 -08001731 "pointerIds=0x%x, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001732 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001733 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001734 inputTarget->xOffset, inputTarget->yOffset,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001735 inputTarget->scaleFactor, inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001736 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac02010-04-22 18:58:52 -07001737#endif
1738
Jeff Brown01ce2e92010-09-26 22:20:12 -07001739 // Make sure we are never called for streaming when splitting across multiple windows.
1740 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
Jeff Brownb6110c22011-04-01 16:15:13 -07001741 LOG_ASSERT(! (resumeWithAppendedMotionSample && isSplit));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001742
Jeff Brown46b9ac02010-04-22 18:58:52 -07001743 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001744 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac02010-04-22 18:58:52 -07001745 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb6997262010-10-08 22:31:17 -07001746#if DEBUG_DISPATCH_CYCLE
1747 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001748 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brownb6997262010-10-08 22:31:17 -07001749#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -07001750 return;
1751 }
1752
Jeff Brown01ce2e92010-09-26 22:20:12 -07001753 // Split a motion event if needed.
1754 if (isSplit) {
Jeff Brownb6110c22011-04-01 16:15:13 -07001755 LOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
Jeff Brown01ce2e92010-09-26 22:20:12 -07001756
1757 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1758 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1759 MotionEntry* splitMotionEntry = splitMotionEvent(
1760 originalMotionEntry, inputTarget->pointerIds);
Jeff Brown58a2da82011-01-25 16:02:22 -08001761 if (!splitMotionEntry) {
1762 return; // split event was dropped
1763 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001764#if DEBUG_FOCUS
1765 LOGD("channel '%s' ~ Split motion event.",
1766 connection->getInputChannelName());
1767 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1768#endif
1769 eventEntry = splitMotionEntry;
1770 }
1771 }
1772
Jeff Brown46b9ac02010-04-22 18:58:52 -07001773 // Resume the dispatch cycle with a freshly appended motion sample.
1774 // First we check that the last dispatch entry in the outbound queue is for the same
1775 // motion event to which we appended the motion sample. If we find such a dispatch
1776 // entry, and if it is currently in progress then we try to stream the new sample.
1777 bool wasEmpty = connection->outboundQueue.isEmpty();
1778
1779 if (! wasEmpty && resumeWithAppendedMotionSample) {
1780 DispatchEntry* motionEventDispatchEntry =
1781 connection->findQueuedDispatchEntryForEvent(eventEntry);
1782 if (motionEventDispatchEntry) {
1783 // If the dispatch entry is not in progress, then we must be busy dispatching an
1784 // earlier event. Not a problem, the motion event is on the outbound queue and will
1785 // be dispatched later.
1786 if (! motionEventDispatchEntry->inProgress) {
1787#if DEBUG_BATCHING
1788 LOGD("channel '%s' ~ Not streaming because the motion event has "
1789 "not yet been dispatched. "
1790 "(Waiting for earlier events to be consumed.)",
1791 connection->getInputChannelName());
1792#endif
1793 return;
1794 }
1795
1796 // If the dispatch entry is in progress but it already has a tail of pending
1797 // motion samples, then it must mean that the shared memory buffer filled up.
1798 // Not a problem, when this dispatch cycle is finished, we will eventually start
1799 // a new dispatch cycle to process the tail and that tail includes the newly
1800 // appended motion sample.
1801 if (motionEventDispatchEntry->tailMotionSample) {
1802#if DEBUG_BATCHING
1803 LOGD("channel '%s' ~ Not streaming because no new samples can "
1804 "be appended to the motion event in this dispatch cycle. "
1805 "(Waiting for next dispatch cycle to start.)",
1806 connection->getInputChannelName());
1807#endif
1808 return;
1809 }
1810
1811 // The dispatch entry is in progress and is still potentially open for streaming.
1812 // Try to stream the new motion sample. This might fail if the consumer has already
1813 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001814 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1815 MotionSample* appendedMotionSample = motionEntry->lastSample;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001816 status_t status;
1817 if (motionEventDispatchEntry->scaleFactor == 1.0f) {
1818 status = connection->inputPublisher.appendMotionSample(
1819 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1820 } else {
1821 PointerCoords scaledCoords[MAX_POINTERS];
1822 for (size_t i = 0; i < motionEntry->pointerCount; i++) {
1823 scaledCoords[i] = appendedMotionSample->pointerCoords[i];
1824 scaledCoords[i].scale(motionEventDispatchEntry->scaleFactor);
1825 }
1826 status = connection->inputPublisher.appendMotionSample(
1827 appendedMotionSample->eventTime, scaledCoords);
1828 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001829 if (status == OK) {
1830#if DEBUG_BATCHING
1831 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1832 connection->getInputChannelName());
1833#endif
1834 return;
1835 }
1836
1837#if DEBUG_BATCHING
1838 if (status == NO_MEMORY) {
1839 LOGD("channel '%s' ~ Could not append motion sample to currently "
1840 "dispatched move event because the shared memory buffer is full. "
1841 "(Waiting for next dispatch cycle to start.)",
1842 connection->getInputChannelName());
1843 } else if (status == status_t(FAILED_TRANSACTION)) {
1844 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001845 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac02010-04-22 18:58:52 -07001846 "(Waiting for next dispatch cycle to start.)",
1847 connection->getInputChannelName());
1848 } else {
1849 LOGD("channel '%s' ~ Could not append motion sample to currently "
1850 "dispatched move event due to an error, status=%d. "
1851 "(Waiting for next dispatch cycle to start.)",
1852 connection->getInputChannelName(), status);
1853 }
1854#endif
1855 // Failed to stream. Start a new tail of pending motion samples to dispatch
1856 // in the next cycle.
1857 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1858 return;
1859 }
1860 }
1861
Jeff Browna032cc02011-03-07 16:56:21 -08001862 // Enqueue dispatch entries for the requested modes.
1863 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1864 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
1865 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1866 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
1867 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1868 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
1869 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1870 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_IS);
1871
1872 // If the outbound queue was previously empty, start the dispatch cycle going.
Jeff Brownb6110c22011-04-01 16:15:13 -07001873 if (wasEmpty && !connection->outboundQueue.isEmpty()) {
Jeff Browna032cc02011-03-07 16:56:21 -08001874 activateConnectionLocked(connection.get());
1875 startDispatchCycleLocked(currentTime, connection);
1876 }
1877}
1878
1879void InputDispatcher::enqueueDispatchEntryLocked(
1880 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
1881 bool resumeWithAppendedMotionSample, int32_t dispatchMode) {
1882 int32_t inputTargetFlags = inputTarget->flags;
1883 if (!(inputTargetFlags & dispatchMode)) {
1884 return;
1885 }
1886 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
1887
Jeff Brown46b9ac02010-04-22 18:58:52 -07001888 // This is a new event.
1889 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001890 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07001891 inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001892 inputTarget->scaleFactor);
Jeff Brown519e0242010-09-15 15:18:56 -07001893 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001894 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001895 }
1896
Jeff Brown46b9ac02010-04-22 18:58:52 -07001897 // Handle the case where we could not stream a new motion sample because the consumer has
1898 // already consumed the motion event (otherwise the corresponding dispatch entry would
1899 // still be in the outbound queue for this connection). We set the head motion sample
1900 // to the list starting with the newly appended motion sample.
1901 if (resumeWithAppendedMotionSample) {
1902#if DEBUG_BATCHING
1903 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1904 "that cannot be streamed because the motion event has already been consumed.",
1905 connection->getInputChannelName());
1906#endif
1907 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1908 dispatchEntry->headMotionSample = appendedMotionSample;
1909 }
1910
1911 // Enqueue the dispatch entry.
1912 connection->outboundQueue.enqueueAtTail(dispatchEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001913}
1914
Jeff Brown7fbdc842010-06-17 20:52:56 -07001915void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001916 const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001917#if DEBUG_DISPATCH_CYCLE
1918 LOGD("channel '%s' ~ startDispatchCycle",
1919 connection->getInputChannelName());
1920#endif
1921
Jeff Brownb6110c22011-04-01 16:15:13 -07001922 LOG_ASSERT(connection->status == Connection::STATUS_NORMAL);
1923 LOG_ASSERT(! connection->outboundQueue.isEmpty());
Jeff Brown46b9ac02010-04-22 18:58:52 -07001924
Jeff Brownb88102f2010-09-08 11:49:43 -07001925 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brownb6110c22011-04-01 16:15:13 -07001926 LOG_ASSERT(! dispatchEntry->inProgress);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001927
Jeff Brownb88102f2010-09-08 11:49:43 -07001928 // Mark the dispatch entry as in progress.
1929 dispatchEntry->inProgress = true;
1930
Jeff Brown46b9ac02010-04-22 18:58:52 -07001931 // Publish the event.
1932 status_t status;
Jeff Browna032cc02011-03-07 16:56:21 -08001933 EventEntry* eventEntry = dispatchEntry->eventEntry;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001934 switch (eventEntry->type) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001935 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001936 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001937
1938 // Apply target flags.
1939 int32_t action = keyEntry->action;
1940 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001941
Jeff Browna032cc02011-03-07 16:56:21 -08001942 // Update the connection's input state.
1943 connection->inputState.trackKey(keyEntry, action);
1944
Jeff Brown46b9ac02010-04-22 18:58:52 -07001945 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001946 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001947 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1948 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1949 keyEntry->eventTime);
1950
1951 if (status) {
1952 LOGE("channel '%s' ~ Could not publish key event, "
1953 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001954 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001955 return;
1956 }
1957 break;
1958 }
1959
1960 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001961 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001962
1963 // Apply target flags.
1964 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001965 int32_t flags = motionEntry->flags;
Jeff Browna032cc02011-03-07 16:56:21 -08001966 if (dispatchEntry->targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001967 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browna032cc02011-03-07 16:56:21 -08001968 } else if (dispatchEntry->targetFlags & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
1969 action = AMOTION_EVENT_ACTION_HOVER_EXIT;
1970 } else if (dispatchEntry->targetFlags & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
1971 action = AMOTION_EVENT_ACTION_HOVER_ENTER;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001972 }
Jeff Brown85a31762010-09-01 17:01:00 -07001973 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1974 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1975 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001976
1977 // If headMotionSample is non-NULL, then it points to the first new sample that we
1978 // were unable to dispatch during the previous cycle so we resume dispatching from
1979 // that point in the list of motion samples.
1980 // Otherwise, we just start from the first sample of the motion event.
1981 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1982 if (! firstMotionSample) {
1983 firstMotionSample = & motionEntry->firstSample;
1984 }
1985
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001986 PointerCoords scaledCoords[MAX_POINTERS];
1987 const PointerCoords* usingCoords = firstMotionSample->pointerCoords;
1988
Jeff Brownd3616592010-07-16 17:21:06 -07001989 // Set the X and Y offset depending on the input source.
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001990 float xOffset, yOffset, scaleFactor;
Jeff Brownd3616592010-07-16 17:21:06 -07001991 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001992 scaleFactor = dispatchEntry->scaleFactor;
1993 xOffset = dispatchEntry->xOffset * scaleFactor;
1994 yOffset = dispatchEntry->yOffset * scaleFactor;
1995 if (scaleFactor != 1.0f) {
1996 for (size_t i = 0; i < motionEntry->pointerCount; i++) {
1997 scaledCoords[i] = firstMotionSample->pointerCoords[i];
1998 scaledCoords[i].scale(scaleFactor);
1999 }
2000 usingCoords = scaledCoords;
2001 }
Jeff Brownd3616592010-07-16 17:21:06 -07002002 } else {
2003 xOffset = 0.0f;
2004 yOffset = 0.0f;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002005 scaleFactor = 1.0f;
Jeff Brownd3616592010-07-16 17:21:06 -07002006 }
2007
Jeff Browna032cc02011-03-07 16:56:21 -08002008 // Update the connection's input state.
2009 connection->inputState.trackMotion(motionEntry, action);
2010
Jeff Brown46b9ac02010-04-22 18:58:52 -07002011 // Publish the motion event and the first motion sample.
2012 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07002013 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002014 xOffset, yOffset, motionEntry->xPrecision, motionEntry->yPrecision,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002015 motionEntry->downTime, firstMotionSample->eventTime,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002016 motionEntry->pointerCount, motionEntry->pointerIds, usingCoords);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002017
2018 if (status) {
2019 LOGE("channel '%s' ~ Could not publish motion event, "
2020 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07002021 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002022 return;
2023 }
2024
Jeff Browna032cc02011-03-07 16:56:21 -08002025 if (action == AMOTION_EVENT_ACTION_MOVE
2026 || action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2027 // Append additional motion samples.
2028 MotionSample* nextMotionSample = firstMotionSample->next;
2029 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
Dianne Hackborn2ba3e802011-05-11 10:59:54 -07002030 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) != 0 && scaleFactor != 1.0f) {
2031 for (size_t i = 0; i < motionEntry->pointerCount; i++) {
2032 scaledCoords[i] = nextMotionSample->pointerCoords[i];
2033 scaledCoords[i].scale(scaleFactor);
2034 }
2035 } else {
2036 usingCoords = nextMotionSample->pointerCoords;
Dianne Hackborne7d25b72011-05-09 21:19:26 -07002037 }
Jeff Browna032cc02011-03-07 16:56:21 -08002038 status = connection->inputPublisher.appendMotionSample(
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07002039 nextMotionSample->eventTime, usingCoords);
Jeff Browna032cc02011-03-07 16:56:21 -08002040 if (status == NO_MEMORY) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002041#if DEBUG_DISPATCH_CYCLE
2042 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
2043 "be sent in the next dispatch cycle.",
2044 connection->getInputChannelName());
2045#endif
Jeff Browna032cc02011-03-07 16:56:21 -08002046 break;
2047 }
2048 if (status != OK) {
2049 LOGE("channel '%s' ~ Could not append motion sample "
2050 "for a reason other than out of memory, status=%d",
2051 connection->getInputChannelName(), status);
2052 abortBrokenDispatchCycleLocked(currentTime, connection);
2053 return;
2054 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002055 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002056
Jeff Browna032cc02011-03-07 16:56:21 -08002057 // Remember the next motion sample that we could not dispatch, in case we ran out
2058 // of space in the shared memory buffer.
2059 dispatchEntry->tailMotionSample = nextMotionSample;
2060 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002061 break;
2062 }
2063
2064 default: {
Jeff Brownb6110c22011-04-01 16:15:13 -07002065 LOG_ASSERT(false);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002066 }
2067 }
2068
2069 // Send the dispatch signal.
2070 status = connection->inputPublisher.sendDispatchSignal();
2071 if (status) {
2072 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
2073 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07002074 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002075 return;
2076 }
2077
2078 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07002079 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002080 connection->lastDispatchTime = currentTime;
2081
Jeff Brown46b9ac02010-04-22 18:58:52 -07002082 // Notify other system components.
2083 onDispatchCycleStartedLocked(currentTime, connection);
2084}
2085
Jeff Brown7fbdc842010-06-17 20:52:56 -07002086void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown3915bb82010-11-05 15:02:16 -07002087 const sp<Connection>& connection, bool handled) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002088#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07002089 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown3915bb82010-11-05 15:02:16 -07002090 "%01.1fms since dispatch, handled=%s",
Jeff Brown46b9ac02010-04-22 18:58:52 -07002091 connection->getInputChannelName(),
2092 connection->getEventLatencyMillis(currentTime),
Jeff Brown3915bb82010-11-05 15:02:16 -07002093 connection->getDispatchLatencyMillis(currentTime),
2094 toString(handled));
Jeff Brown46b9ac02010-04-22 18:58:52 -07002095#endif
2096
Jeff Brown9c3cda02010-06-15 01:31:58 -07002097 if (connection->status == Connection::STATUS_BROKEN
2098 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002099 return;
2100 }
2101
Jeff Brown46b9ac02010-04-22 18:58:52 -07002102 // Reset the publisher since the event has been consumed.
2103 // We do this now so that the publisher can release some of its internal resources
2104 // while waiting for the next dispatch cycle to begin.
2105 status_t status = connection->inputPublisher.reset();
2106 if (status) {
2107 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
2108 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07002109 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002110 return;
2111 }
2112
Jeff Brown3915bb82010-11-05 15:02:16 -07002113 // Notify other system components and prepare to start the next dispatch cycle.
2114 onDispatchCycleFinishedLocked(currentTime, connection, handled);
Jeff Brownb88102f2010-09-08 11:49:43 -07002115}
2116
2117void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
2118 const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002119 // Start the next dispatch cycle for this connection.
2120 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002121 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002122 if (dispatchEntry->inProgress) {
2123 // Finish or resume current event in progress.
2124 if (dispatchEntry->tailMotionSample) {
2125 // We have a tail of undispatched motion samples.
2126 // Reuse the same DispatchEntry and start a new cycle.
2127 dispatchEntry->inProgress = false;
2128 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
2129 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07002130 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002131 return;
2132 }
2133 // Finished.
2134 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07002135 if (dispatchEntry->hasForegroundTarget()) {
2136 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002137 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002138 mAllocator.releaseDispatchEntry(dispatchEntry);
2139 } else {
2140 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07002141 // progress event, which means we actually aborted it.
Jeff Brown46b9ac02010-04-22 18:58:52 -07002142 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07002143 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002144 return;
2145 }
2146 }
2147
2148 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002149 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac02010-04-22 18:58:52 -07002150}
2151
Jeff Brownb6997262010-10-08 22:31:17 -07002152void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
2153 const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002154#if DEBUG_DISPATCH_CYCLE
Jeff Brown83c09682010-12-23 17:50:18 -08002155 LOGD("channel '%s' ~ abortBrokenDispatchCycle",
2156 connection->getInputChannelName());
Jeff Brown46b9ac02010-04-22 18:58:52 -07002157#endif
2158
Jeff Brownb88102f2010-09-08 11:49:43 -07002159 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002160 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac02010-04-22 18:58:52 -07002161
Jeff Brownb6997262010-10-08 22:31:17 -07002162 // The connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002163 // Ignore already broken or zombie connections.
Jeff Brownb6997262010-10-08 22:31:17 -07002164 if (connection->status == Connection::STATUS_NORMAL) {
2165 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002166
Jeff Brownb6997262010-10-08 22:31:17 -07002167 // Notify other system components.
2168 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002169 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002170}
2171
Jeff Brown519e0242010-09-15 15:18:56 -07002172void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
2173 while (! connection->outboundQueue.isEmpty()) {
2174 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
2175 if (dispatchEntry->hasForegroundTarget()) {
2176 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07002177 }
2178 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07002179 }
2180
Jeff Brown519e0242010-09-15 15:18:56 -07002181 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07002182}
2183
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002184int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002185 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2186
2187 { // acquire lock
2188 AutoMutex _l(d->mLock);
2189
2190 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
2191 if (connectionIndex < 0) {
2192 LOGE("Received spurious receive callback for unknown input channel. "
2193 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002194 return 0; // remove the callback
Jeff Brown46b9ac02010-04-22 18:58:52 -07002195 }
2196
Jeff Brown7fbdc842010-06-17 20:52:56 -07002197 nsecs_t currentTime = now();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002198
2199 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002200 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002201 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
2202 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brownb6997262010-10-08 22:31:17 -07002203 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002204 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002205 return 0; // remove the callback
Jeff Brown46b9ac02010-04-22 18:58:52 -07002206 }
2207
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002208 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002209 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
2210 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002211 return 1;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002212 }
2213
Jeff Brown3915bb82010-11-05 15:02:16 -07002214 bool handled = false;
Jeff Brown49ed71d2010-12-06 17:13:33 -08002215 status_t status = connection->inputPublisher.receiveFinishedSignal(&handled);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002216 if (status) {
2217 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
2218 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07002219 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002220 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002221 return 0; // remove the callback
Jeff Brown46b9ac02010-04-22 18:58:52 -07002222 }
2223
Jeff Brown3915bb82010-11-05 15:02:16 -07002224 d->finishDispatchCycleLocked(currentTime, connection, handled);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002225 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002226 return 1;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002227 } // release lock
2228}
2229
Jeff Brownb6997262010-10-08 22:31:17 -07002230void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Jeff Brownda3d5a92011-03-29 15:11:34 -07002231 const CancelationOptions& options) {
Jeff Brownb6997262010-10-08 22:31:17 -07002232 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
2233 synthesizeCancelationEventsForConnectionLocked(
Jeff Brownda3d5a92011-03-29 15:11:34 -07002234 mConnectionsByReceiveFd.valueAt(i), options);
Jeff Brownb6997262010-10-08 22:31:17 -07002235 }
2236}
2237
2238void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Jeff Brownda3d5a92011-03-29 15:11:34 -07002239 const sp<InputChannel>& channel, const CancelationOptions& options) {
Jeff Brownb6997262010-10-08 22:31:17 -07002240 ssize_t index = getConnectionIndexLocked(channel);
2241 if (index >= 0) {
2242 synthesizeCancelationEventsForConnectionLocked(
Jeff Brownda3d5a92011-03-29 15:11:34 -07002243 mConnectionsByReceiveFd.valueAt(index), options);
Jeff Brownb6997262010-10-08 22:31:17 -07002244 }
2245}
2246
2247void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
Jeff Brownda3d5a92011-03-29 15:11:34 -07002248 const sp<Connection>& connection, const CancelationOptions& options) {
Jeff Brownb6997262010-10-08 22:31:17 -07002249 nsecs_t currentTime = now();
2250
2251 mTempCancelationEvents.clear();
2252 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
2253 mTempCancelationEvents, options);
2254
2255 if (! mTempCancelationEvents.isEmpty()
2256 && connection->status != Connection::STATUS_BROKEN) {
2257#if DEBUG_OUTBOUND_EVENT_DETAILS
2258 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
Jeff Brownda3d5a92011-03-29 15:11:34 -07002259 "with reality: %s, mode=%d.",
2260 connection->getInputChannelName(), mTempCancelationEvents.size(),
2261 options.reason, options.mode);
Jeff Brownb6997262010-10-08 22:31:17 -07002262#endif
2263 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
2264 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
2265 switch (cancelationEventEntry->type) {
2266 case EventEntry::TYPE_KEY:
2267 logOutboundKeyDetailsLocked("cancel - ",
2268 static_cast<KeyEntry*>(cancelationEventEntry));
2269 break;
2270 case EventEntry::TYPE_MOTION:
2271 logOutboundMotionDetailsLocked("cancel - ",
2272 static_cast<MotionEntry*>(cancelationEventEntry));
2273 break;
2274 }
2275
2276 int32_t xOffset, yOffset;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002277 float scaleFactor;
Jeff Brownb6997262010-10-08 22:31:17 -07002278 const InputWindow* window = getWindowLocked(connection->inputChannel);
2279 if (window) {
2280 xOffset = -window->frameLeft;
2281 yOffset = -window->frameTop;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002282 scaleFactor = window->scaleFactor;
Jeff Brownb6997262010-10-08 22:31:17 -07002283 } else {
2284 xOffset = 0;
2285 yOffset = 0;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002286 scaleFactor = 1.0f;
Jeff Brownb6997262010-10-08 22:31:17 -07002287 }
2288
2289 DispatchEntry* cancelationDispatchEntry =
2290 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002291 0, xOffset, yOffset, scaleFactor);
Jeff Brownb6997262010-10-08 22:31:17 -07002292 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
2293
2294 mAllocator.releaseEventEntry(cancelationEventEntry);
2295 }
2296
2297 if (!connection->outboundQueue.headSentinel.next->inProgress) {
2298 startDispatchCycleLocked(currentTime, connection);
2299 }
2300 }
2301}
2302
Jeff Brown01ce2e92010-09-26 22:20:12 -07002303InputDispatcher::MotionEntry*
2304InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
Jeff Brownb6110c22011-04-01 16:15:13 -07002305 LOG_ASSERT(pointerIds.value != 0);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002306
2307 uint32_t splitPointerIndexMap[MAX_POINTERS];
2308 int32_t splitPointerIds[MAX_POINTERS];
2309 PointerCoords splitPointerCoords[MAX_POINTERS];
2310
2311 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2312 uint32_t splitPointerCount = 0;
2313
2314 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2315 originalPointerIndex++) {
2316 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
2317 if (pointerIds.hasBit(pointerId)) {
2318 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2319 splitPointerIds[splitPointerCount] = pointerId;
Jeff Brownace13b12011-03-09 17:39:48 -08002320 splitPointerCoords[splitPointerCount].copyFrom(
2321 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex]);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002322 splitPointerCount += 1;
2323 }
2324 }
Jeff Brown58a2da82011-01-25 16:02:22 -08002325
2326 if (splitPointerCount != pointerIds.count()) {
2327 // This is bad. We are missing some of the pointers that we expected to deliver.
2328 // Most likely this indicates that we received an ACTION_MOVE events that has
2329 // different pointer ids than we expected based on the previous ACTION_DOWN
2330 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2331 // in this way.
2332 LOGW("Dropping split motion event because the pointer count is %d but "
2333 "we expected there to be %d pointers. This probably means we received "
2334 "a broken sequence of pointer ids from the input device.",
2335 splitPointerCount, pointerIds.count());
2336 return NULL;
2337 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002338
2339 int32_t action = originalMotionEntry->action;
2340 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2341 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2342 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2343 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2344 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2345 if (pointerIds.hasBit(pointerId)) {
2346 if (pointerIds.count() == 1) {
2347 // The first/last pointer went down/up.
2348 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2349 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07002350 } else {
2351 // A secondary pointer went down/up.
2352 uint32_t splitPointerIndex = 0;
2353 while (pointerId != splitPointerIds[splitPointerIndex]) {
2354 splitPointerIndex += 1;
2355 }
2356 action = maskedAction | (splitPointerIndex
2357 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002358 }
2359 } else {
2360 // An unrelated pointer changed.
2361 action = AMOTION_EVENT_ACTION_MOVE;
2362 }
2363 }
2364
2365 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2366 originalMotionEntry->eventTime,
2367 originalMotionEntry->deviceId,
2368 originalMotionEntry->source,
2369 originalMotionEntry->policyFlags,
2370 action,
2371 originalMotionEntry->flags,
2372 originalMotionEntry->metaState,
2373 originalMotionEntry->edgeFlags,
2374 originalMotionEntry->xPrecision,
2375 originalMotionEntry->yPrecision,
2376 originalMotionEntry->downTime,
2377 splitPointerCount, splitPointerIds, splitPointerCoords);
2378
2379 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2380 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2381 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2382 splitPointerIndex++) {
2383 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
Jeff Brownace13b12011-03-09 17:39:48 -08002384 splitPointerCoords[splitPointerIndex].copyFrom(
2385 originalMotionSample->pointerCoords[originalPointerIndex]);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002386 }
2387
2388 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2389 splitPointerCoords);
2390 }
2391
Jeff Browna032cc02011-03-07 16:56:21 -08002392 if (originalMotionEntry->injectionState) {
2393 splitMotionEntry->injectionState = originalMotionEntry->injectionState;
2394 splitMotionEntry->injectionState->refCount += 1;
2395 }
2396
Jeff Brown01ce2e92010-09-26 22:20:12 -07002397 return splitMotionEntry;
2398}
2399
Jeff Brown9c3cda02010-06-15 01:31:58 -07002400void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002401#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07002402 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002403#endif
2404
Jeff Brownb88102f2010-09-08 11:49:43 -07002405 bool needWake;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002406 { // acquire lock
2407 AutoMutex _l(mLock);
2408
Jeff Brown7fbdc842010-06-17 20:52:56 -07002409 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07002410 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002411 } // release lock
2412
Jeff Brownb88102f2010-09-08 11:49:43 -07002413 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002414 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002415 }
2416}
2417
Jeff Brown58a2da82011-01-25 16:02:22 -08002418void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002419 uint32_t policyFlags, int32_t action, int32_t flags,
2420 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2421#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002422 LOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac02010-04-22 18:58:52 -07002423 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07002424 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002425 keyCode, scanCode, metaState, downTime);
2426#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002427 if (! validateKeyEvent(action)) {
2428 return;
2429 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002430
Jeff Brown1f245102010-11-18 20:53:46 -08002431 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2432 policyFlags |= POLICY_FLAG_VIRTUAL;
2433 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2434 }
Jeff Brown924c4d42011-03-07 16:40:47 -08002435 if (policyFlags & POLICY_FLAG_ALT) {
2436 metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON;
2437 }
2438 if (policyFlags & POLICY_FLAG_ALT_GR) {
2439 metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON;
2440 }
2441 if (policyFlags & POLICY_FLAG_SHIFT) {
2442 metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON;
2443 }
2444 if (policyFlags & POLICY_FLAG_CAPS_LOCK) {
2445 metaState |= AMETA_CAPS_LOCK_ON;
2446 }
2447 if (policyFlags & POLICY_FLAG_FUNCTION) {
2448 metaState |= AMETA_FUNCTION_ON;
2449 }
Jeff Brown1f245102010-11-18 20:53:46 -08002450
Jeff Browne20c9e02010-10-11 14:20:19 -07002451 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown1f245102010-11-18 20:53:46 -08002452
2453 KeyEvent event;
2454 event.initialize(deviceId, source, action, flags, keyCode, scanCode,
2455 metaState, 0, downTime, eventTime);
2456
2457 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
2458
2459 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2460 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2461 }
Jeff Brownb6997262010-10-08 22:31:17 -07002462
Jeff Brownb88102f2010-09-08 11:49:43 -07002463 bool needWake;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002464 { // acquire lock
Jeff Brown0029c662011-03-30 02:25:18 -07002465 mLock.lock();
2466
2467 if (mInputFilterEnabled) {
2468 mLock.unlock();
2469
2470 policyFlags |= POLICY_FLAG_FILTERED;
2471 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2472 return; // event was consumed by the filter
2473 }
2474
2475 mLock.lock();
2476 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002477
Jeff Brown7fbdc842010-06-17 20:52:56 -07002478 int32_t repeatCount = 0;
2479 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002480 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002481 metaState, repeatCount, downTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002482
Jeff Brownb88102f2010-09-08 11:49:43 -07002483 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown0029c662011-03-30 02:25:18 -07002484 mLock.unlock();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002485 } // release lock
2486
Jeff Brownb88102f2010-09-08 11:49:43 -07002487 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002488 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002489 }
2490}
2491
Jeff Brown58a2da82011-01-25 16:02:22 -08002492void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002493 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002494 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2495 float xPrecision, float yPrecision, nsecs_t downTime) {
2496#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002497 LOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002498 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2499 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2500 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002501 xPrecision, yPrecision, downTime);
2502 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002503 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002504 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002505 "orientation=%f",
Jeff Brown91c69ab2011-02-14 17:03:18 -08002506 i, pointerIds[i],
Jeff Brownebbd5d12011-02-17 13:01:34 -08002507 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2508 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2509 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2510 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2511 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2512 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2513 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2514 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2515 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Jeff Brown46b9ac02010-04-22 18:58:52 -07002516 }
2517#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002518 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2519 return;
2520 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002521
Jeff Browne20c9e02010-10-11 14:20:19 -07002522 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown56194eb2011-03-02 19:23:13 -08002523 mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002524
Jeff Brownb88102f2010-09-08 11:49:43 -07002525 bool needWake;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002526 { // acquire lock
Jeff Brown0029c662011-03-30 02:25:18 -07002527 mLock.lock();
2528
2529 if (mInputFilterEnabled) {
2530 mLock.unlock();
2531
2532 MotionEvent event;
2533 event.initialize(deviceId, source, action, flags, edgeFlags, metaState, 0, 0,
2534 xPrecision, yPrecision, downTime, eventTime,
2535 pointerCount, pointerIds, pointerCoords);
2536
2537 policyFlags |= POLICY_FLAG_FILTERED;
2538 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2539 return; // event was consumed by the filter
2540 }
2541
2542 mLock.lock();
2543 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002544
2545 // Attempt batching and streaming of move events.
Jeff Browncc0c1592011-02-19 05:07:28 -08002546 if (action == AMOTION_EVENT_ACTION_MOVE
2547 || action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002548 // BATCHING CASE
2549 //
2550 // Try to append a move sample to the tail of the inbound queue for this device.
2551 // Give up if we encounter a non-move motion event for this device since that
2552 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002553 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2554 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002555 if (entry->type != EventEntry::TYPE_MOTION) {
2556 // Keep looking for motion events.
2557 continue;
2558 }
2559
2560 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
Jeff Brownefd32662011-03-08 15:13:06 -08002561 if (motionEntry->deviceId != deviceId
2562 || motionEntry->source != source) {
2563 // Keep looking for this device and source.
Jeff Brown46b9ac02010-04-22 18:58:52 -07002564 continue;
2565 }
2566
Jeff Brown4e91a182011-04-07 11:38:09 -07002567 if (!motionEntry->canAppendSamples(action, pointerCount, pointerIds)) {
Jeff Brownefd32662011-03-08 15:13:06 -08002568 // Last motion event in the queue for this device and source is
2569 // not compatible for appending new samples. Stop here.
Jeff Brown46b9ac02010-04-22 18:58:52 -07002570 goto NoBatchingOrStreaming;
2571 }
2572
Jeff Brown9c3cda02010-06-15 01:31:58 -07002573 // Do the batching magic.
Jeff Brown4e91a182011-04-07 11:38:09 -07002574 batchMotionLocked(motionEntry, eventTime, metaState, pointerCoords,
2575 "most recent motion event for this device and source in the inbound queue");
Jeff Brown0029c662011-03-30 02:25:18 -07002576 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002577 return; // done!
Jeff Brown46b9ac02010-04-22 18:58:52 -07002578 }
2579
Jeff Brownf6989da2011-04-06 17:19:48 -07002580 // BATCHING ONTO PENDING EVENT CASE
2581 //
2582 // Try to append a move sample to the currently pending event, if there is one.
2583 // We can do this as long as we are still waiting to find the targets for the
2584 // event. Once the targets are locked-in we can only do streaming.
2585 if (mPendingEvent
2586 && (!mPendingEvent->dispatchInProgress || !mCurrentInputTargetsValid)
2587 && mPendingEvent->type == EventEntry::TYPE_MOTION) {
2588 MotionEntry* motionEntry = static_cast<MotionEntry*>(mPendingEvent);
2589 if (motionEntry->deviceId == deviceId && motionEntry->source == source) {
Jeff Brown4e91a182011-04-07 11:38:09 -07002590 if (!motionEntry->canAppendSamples(action, pointerCount, pointerIds)) {
2591 // Pending motion event is for this device and source but it is
2592 // not compatible for appending new samples. Stop here.
Jeff Brownf6989da2011-04-06 17:19:48 -07002593 goto NoBatchingOrStreaming;
2594 }
2595
Jeff Brownf6989da2011-04-06 17:19:48 -07002596 // Do the batching magic.
Jeff Brown4e91a182011-04-07 11:38:09 -07002597 batchMotionLocked(motionEntry, eventTime, metaState, pointerCoords,
2598 "pending motion event");
Jeff Brownf6989da2011-04-06 17:19:48 -07002599 mLock.unlock();
2600 return; // done!
2601 }
2602 }
2603
Jeff Brown46b9ac02010-04-22 18:58:52 -07002604 // STREAMING CASE
2605 //
2606 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002607 // Search the outbound queue for the current foreground targets to find a dispatched
2608 // motion event that is still in progress. If found, then, appen the new sample to
2609 // that event and push it out to all current targets. The logic in
2610 // prepareDispatchCycleLocked takes care of the case where some targets may
2611 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002612 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002613 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2614 const InputTarget& inputTarget = mCurrentInputTargets[i];
2615 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2616 // Skip non-foreground targets. We only want to stream if there is at
2617 // least one foreground target whose dispatch is still in progress.
2618 continue;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002619 }
Jeff Brown519e0242010-09-15 15:18:56 -07002620
2621 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2622 if (connectionIndex < 0) {
2623 // Connection must no longer be valid.
2624 continue;
2625 }
2626
2627 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2628 if (connection->outboundQueue.isEmpty()) {
2629 // This foreground target has an empty outbound queue.
2630 continue;
2631 }
2632
2633 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2634 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002635 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2636 || dispatchEntry->isSplit()) {
2637 // No motion event is being dispatched, or it is being split across
2638 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002639 continue;
2640 }
2641
2642 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2643 dispatchEntry->eventEntry);
Jeff Browncc0c1592011-02-19 05:07:28 -08002644 if (motionEntry->action != action
Jeff Brown519e0242010-09-15 15:18:56 -07002645 || motionEntry->deviceId != deviceId
Jeff Brown58a2da82011-01-25 16:02:22 -08002646 || motionEntry->source != source
Jeff Brown519e0242010-09-15 15:18:56 -07002647 || motionEntry->pointerCount != pointerCount
2648 || motionEntry->isInjected()) {
2649 // The motion event is not compatible with this move.
2650 continue;
2651 }
2652
Jeff Browna032cc02011-03-07 16:56:21 -08002653 if (action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2654 if (!mLastHoverWindow) {
2655#if DEBUG_BATCHING
2656 LOGD("Not streaming hover move because there is no "
2657 "last hovered window.");
2658#endif
2659 goto NoBatchingOrStreaming;
2660 }
2661
2662 const InputWindow* hoverWindow = findTouchedWindowAtLocked(
2663 pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X),
2664 pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2665 if (mLastHoverWindow != hoverWindow) {
2666#if DEBUG_BATCHING
2667 LOGD("Not streaming hover move because the last hovered window "
2668 "is '%s' but the currently hovered window is '%s'.",
2669 mLastHoverWindow->name.string(),
2670 hoverWindow ? hoverWindow->name.string() : "<null>");
2671#endif
2672 goto NoBatchingOrStreaming;
2673 }
2674 }
2675
Jeff Brown519e0242010-09-15 15:18:56 -07002676 // Hurray! This foreground target is currently dispatching a move event
2677 // that we can stream onto. Append the motion sample and resume dispatch.
2678 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2679#if DEBUG_BATCHING
2680 LOGD("Appended motion sample onto batch for most recently dispatched "
Jeff Brown4e91a182011-04-07 11:38:09 -07002681 "motion event for this device and source in the outbound queues. "
Jeff Brown519e0242010-09-15 15:18:56 -07002682 "Attempting to stream the motion sample.");
2683#endif
2684 nsecs_t currentTime = now();
2685 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2686 true /*resumeWithAppendedMotionSample*/);
2687
2688 runCommandsLockedInterruptible();
Jeff Brown0029c662011-03-30 02:25:18 -07002689 mLock.unlock();
Jeff Brown519e0242010-09-15 15:18:56 -07002690 return; // done!
Jeff Brown46b9ac02010-04-22 18:58:52 -07002691 }
2692 }
2693
2694NoBatchingOrStreaming:;
2695 }
2696
2697 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002698 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002699 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002700 xPrecision, yPrecision, downTime,
2701 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002702
Jeff Brownb88102f2010-09-08 11:49:43 -07002703 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown0029c662011-03-30 02:25:18 -07002704 mLock.unlock();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002705 } // release lock
2706
Jeff Brownb88102f2010-09-08 11:49:43 -07002707 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002708 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002709 }
2710}
2711
Jeff Brown4e91a182011-04-07 11:38:09 -07002712void InputDispatcher::batchMotionLocked(MotionEntry* entry, nsecs_t eventTime,
2713 int32_t metaState, const PointerCoords* pointerCoords, const char* eventDescription) {
2714 // Combine meta states.
2715 entry->metaState |= metaState;
2716
2717 // Coalesce this sample if not enough time has elapsed since the last sample was
2718 // initially appended to the batch.
2719 MotionSample* lastSample = entry->lastSample;
2720 long interval = eventTime - lastSample->eventTimeBeforeCoalescing;
2721 if (interval <= MOTION_SAMPLE_COALESCE_INTERVAL) {
2722 uint32_t pointerCount = entry->pointerCount;
2723 for (uint32_t i = 0; i < pointerCount; i++) {
2724 lastSample->pointerCoords[i].copyFrom(pointerCoords[i]);
2725 }
2726 lastSample->eventTime = eventTime;
2727#if DEBUG_BATCHING
2728 LOGD("Coalesced motion into last sample of batch for %s, events were %0.3f ms apart",
2729 eventDescription, interval * 0.000001f);
2730#endif
2731 return;
2732 }
2733
2734 // Append the sample.
2735 mAllocator.appendMotionSample(entry, eventTime, pointerCoords);
2736#if DEBUG_BATCHING
2737 LOGD("Appended motion sample onto batch for %s, events were %0.3f ms apart",
2738 eventDescription, interval * 0.000001f);
2739#endif
2740}
2741
Jeff Brownb6997262010-10-08 22:31:17 -07002742void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2743 uint32_t policyFlags) {
2744#if DEBUG_INBOUND_EVENT_DETAILS
2745 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2746 switchCode, switchValue, policyFlags);
2747#endif
2748
Jeff Browne20c9e02010-10-11 14:20:19 -07002749 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002750 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2751}
2752
Jeff Brown7fbdc842010-06-17 20:52:56 -07002753int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown0029c662011-03-30 02:25:18 -07002754 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
2755 uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002756#if DEBUG_INBOUND_EVENT_DETAILS
2757 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown0029c662011-03-30 02:25:18 -07002758 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
2759 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002760#endif
2761
2762 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Browne20c9e02010-10-11 14:20:19 -07002763
Jeff Brown0029c662011-03-30 02:25:18 -07002764 policyFlags |= POLICY_FLAG_INJECTED;
Jeff Browne20c9e02010-10-11 14:20:19 -07002765 if (hasInjectionPermission(injectorPid, injectorUid)) {
2766 policyFlags |= POLICY_FLAG_TRUSTED;
2767 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002768
Jeff Brownb6997262010-10-08 22:31:17 -07002769 EventEntry* injectedEntry;
2770 switch (event->getType()) {
2771 case AINPUT_EVENT_TYPE_KEY: {
2772 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2773 int32_t action = keyEvent->getAction();
2774 if (! validateKeyEvent(action)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002775 return INPUT_EVENT_INJECTION_FAILED;
2776 }
2777
Jeff Brownb6997262010-10-08 22:31:17 -07002778 int32_t flags = keyEvent->getFlags();
Jeff Brown1f245102010-11-18 20:53:46 -08002779 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2780 policyFlags |= POLICY_FLAG_VIRTUAL;
2781 }
2782
Jeff Brown0029c662011-03-30 02:25:18 -07002783 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2784 mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
2785 }
Jeff Brown1f245102010-11-18 20:53:46 -08002786
2787 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2788 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2789 }
Jeff Brown6ec402b2010-07-28 15:48:59 -07002790
Jeff Brownb6997262010-10-08 22:31:17 -07002791 mLock.lock();
Jeff Brown1f245102010-11-18 20:53:46 -08002792 injectedEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
2793 keyEvent->getDeviceId(), keyEvent->getSource(),
2794 policyFlags, action, flags,
2795 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
Jeff Brownb6997262010-10-08 22:31:17 -07002796 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2797 break;
2798 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002799
Jeff Brownb6997262010-10-08 22:31:17 -07002800 case AINPUT_EVENT_TYPE_MOTION: {
2801 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2802 int32_t action = motionEvent->getAction();
2803 size_t pointerCount = motionEvent->getPointerCount();
2804 const int32_t* pointerIds = motionEvent->getPointerIds();
2805 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2806 return INPUT_EVENT_INJECTION_FAILED;
2807 }
2808
Jeff Brown0029c662011-03-30 02:25:18 -07002809 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2810 nsecs_t eventTime = motionEvent->getEventTime();
2811 mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
2812 }
Jeff Brownb6997262010-10-08 22:31:17 -07002813
2814 mLock.lock();
2815 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2816 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2817 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2818 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2819 action, motionEvent->getFlags(),
2820 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2821 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2822 motionEvent->getDownTime(), uint32_t(pointerCount),
2823 pointerIds, samplePointerCoords);
2824 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2825 sampleEventTimes += 1;
2826 samplePointerCoords += pointerCount;
2827 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2828 }
2829 injectedEntry = motionEntry;
2830 break;
2831 }
2832
2833 default:
2834 LOGW("Cannot inject event of type %d", event->getType());
2835 return INPUT_EVENT_INJECTION_FAILED;
2836 }
2837
2838 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2839 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2840 injectionState->injectionIsAsync = true;
2841 }
2842
2843 injectionState->refCount += 1;
2844 injectedEntry->injectionState = injectionState;
2845
2846 bool needWake = enqueueInboundEventLocked(injectedEntry);
2847 mLock.unlock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002848
Jeff Brownb88102f2010-09-08 11:49:43 -07002849 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002850 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002851 }
2852
2853 int32_t injectionResult;
2854 { // acquire lock
2855 AutoMutex _l(mLock);
2856
Jeff Brown6ec402b2010-07-28 15:48:59 -07002857 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2858 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2859 } else {
2860 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002861 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002862 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2863 break;
2864 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002865
Jeff Brown7fbdc842010-06-17 20:52:56 -07002866 nsecs_t remainingTimeout = endTime - now();
2867 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002868#if DEBUG_INJECTION
2869 LOGD("injectInputEvent - Timed out waiting for injection result "
2870 "to become available.");
2871#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002872 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2873 break;
2874 }
2875
Jeff Brown6ec402b2010-07-28 15:48:59 -07002876 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2877 }
2878
2879 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2880 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002881 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002882#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002883 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002884 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002885#endif
2886 nsecs_t remainingTimeout = endTime - now();
2887 if (remainingTimeout <= 0) {
2888#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002889 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002890 "dispatches to finish.");
2891#endif
2892 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2893 break;
2894 }
2895
2896 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2897 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002898 }
2899 }
2900
Jeff Brown01ce2e92010-09-26 22:20:12 -07002901 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002902 } // release lock
2903
Jeff Brown6ec402b2010-07-28 15:48:59 -07002904#if DEBUG_INJECTION
2905 LOGD("injectInputEvent - Finished with result %d. "
2906 "injectorPid=%d, injectorUid=%d",
2907 injectionResult, injectorPid, injectorUid);
2908#endif
2909
Jeff Brown7fbdc842010-06-17 20:52:56 -07002910 return injectionResult;
2911}
2912
Jeff Brownb6997262010-10-08 22:31:17 -07002913bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2914 return injectorUid == 0
2915 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2916}
2917
Jeff Brown7fbdc842010-06-17 20:52:56 -07002918void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002919 InjectionState* injectionState = entry->injectionState;
2920 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002921#if DEBUG_INJECTION
2922 LOGD("Setting input event injection result to %d. "
2923 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002924 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002925#endif
2926
Jeff Brown0029c662011-03-30 02:25:18 -07002927 if (injectionState->injectionIsAsync
2928 && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002929 // Log the outcome since the injector did not wait for the injection result.
2930 switch (injectionResult) {
2931 case INPUT_EVENT_INJECTION_SUCCEEDED:
2932 LOGV("Asynchronous input event injection succeeded.");
2933 break;
2934 case INPUT_EVENT_INJECTION_FAILED:
2935 LOGW("Asynchronous input event injection failed.");
2936 break;
2937 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2938 LOGW("Asynchronous input event injection permission denied.");
2939 break;
2940 case INPUT_EVENT_INJECTION_TIMED_OUT:
2941 LOGW("Asynchronous input event injection timed out.");
2942 break;
2943 }
2944 }
2945
Jeff Brown01ce2e92010-09-26 22:20:12 -07002946 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002947 mInjectionResultAvailableCondition.broadcast();
2948 }
2949}
2950
Jeff Brown01ce2e92010-09-26 22:20:12 -07002951void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2952 InjectionState* injectionState = entry->injectionState;
2953 if (injectionState) {
2954 injectionState->pendingForegroundDispatches += 1;
2955 }
2956}
2957
Jeff Brown519e0242010-09-15 15:18:56 -07002958void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002959 InjectionState* injectionState = entry->injectionState;
2960 if (injectionState) {
2961 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002962
Jeff Brown01ce2e92010-09-26 22:20:12 -07002963 if (injectionState->pendingForegroundDispatches == 0) {
2964 mInjectionSyncFinishedCondition.broadcast();
2965 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002966 }
2967}
2968
Jeff Brown01ce2e92010-09-26 22:20:12 -07002969const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2970 for (size_t i = 0; i < mWindows.size(); i++) {
2971 const InputWindow* window = & mWindows[i];
2972 if (window->inputChannel == inputChannel) {
2973 return window;
2974 }
2975 }
2976 return NULL;
2977}
2978
Jeff Brownb88102f2010-09-08 11:49:43 -07002979void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2980#if DEBUG_FOCUS
2981 LOGD("setInputWindows");
2982#endif
2983 { // acquire lock
2984 AutoMutex _l(mLock);
2985
Jeff Brown01ce2e92010-09-26 22:20:12 -07002986 // Clear old window pointers.
Jeff Brownb6997262010-10-08 22:31:17 -07002987 sp<InputChannel> oldFocusedWindowChannel;
2988 if (mFocusedWindow) {
2989 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2990 mFocusedWindow = NULL;
2991 }
Jeff Browna032cc02011-03-07 16:56:21 -08002992 sp<InputChannel> oldLastHoverWindowChannel;
2993 if (mLastHoverWindow) {
2994 oldLastHoverWindowChannel = mLastHoverWindow->inputChannel;
2995 mLastHoverWindow = NULL;
2996 }
Jeff Brownb6997262010-10-08 22:31:17 -07002997
Jeff Brownb88102f2010-09-08 11:49:43 -07002998 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002999
3000 // Loop over new windows and rebuild the necessary window pointers for
3001 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07003002 mWindows.appendVector(inputWindows);
3003
3004 size_t numWindows = mWindows.size();
3005 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003006 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003007 if (window->hasFocus) {
3008 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003009 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07003010 }
3011 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07003012
Jeff Brownb6997262010-10-08 22:31:17 -07003013 if (oldFocusedWindowChannel != NULL) {
3014 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
3015#if DEBUG_FOCUS
3016 LOGD("Focus left window: %s",
3017 oldFocusedWindowChannel->getName().string());
3018#endif
Jeff Brownda3d5a92011-03-29 15:11:34 -07003019 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3020 "focus left window");
3021 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel, options);
Jeff Brownb6997262010-10-08 22:31:17 -07003022 oldFocusedWindowChannel.clear();
3023 }
3024 }
3025 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
3026#if DEBUG_FOCUS
3027 LOGD("Focus entered window: %s",
3028 mFocusedWindow->inputChannel->getName().string());
3029#endif
3030 }
3031
Jeff Brown01ce2e92010-09-26 22:20:12 -07003032 for (size_t i = 0; i < mTouchState.windows.size(); ) {
3033 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
3034 const InputWindow* window = getWindowLocked(touchedWindow.channel);
3035 if (window) {
3036 touchedWindow.window = window;
3037 i += 1;
3038 } else {
Jeff Brownb6997262010-10-08 22:31:17 -07003039#if DEBUG_FOCUS
3040 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
3041#endif
Jeff Brownda3d5a92011-03-29 15:11:34 -07003042 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3043 "touched window was removed");
3044 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel, options);
Jeff Brownaf48cae2010-10-15 16:20:51 -07003045 mTouchState.windows.removeAt(i);
Jeff Brown01ce2e92010-09-26 22:20:12 -07003046 }
3047 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003048
Jeff Browna032cc02011-03-07 16:56:21 -08003049 // Recover the last hovered window.
3050 if (oldLastHoverWindowChannel != NULL) {
3051 mLastHoverWindow = getWindowLocked(oldLastHoverWindowChannel);
3052 oldLastHoverWindowChannel.clear();
3053 }
3054
Jeff Brownb88102f2010-09-08 11:49:43 -07003055#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07003056 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07003057#endif
3058 } // release lock
3059
3060 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003061 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07003062}
3063
3064void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
3065#if DEBUG_FOCUS
3066 LOGD("setFocusedApplication");
3067#endif
3068 { // acquire lock
3069 AutoMutex _l(mLock);
3070
3071 releaseFocusedApplicationLocked();
3072
3073 if (inputApplication) {
3074 mFocusedApplicationStorage = *inputApplication;
3075 mFocusedApplication = & mFocusedApplicationStorage;
3076 }
3077
3078#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07003079 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07003080#endif
3081 } // release lock
3082
3083 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003084 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07003085}
3086
3087void InputDispatcher::releaseFocusedApplicationLocked() {
3088 if (mFocusedApplication) {
3089 mFocusedApplication = NULL;
Jeff Brown928e0542011-01-10 11:17:36 -08003090 mFocusedApplicationStorage.inputApplicationHandle.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -07003091 }
3092}
3093
3094void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
3095#if DEBUG_FOCUS
3096 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3097#endif
3098
3099 bool changed;
3100 { // acquire lock
3101 AutoMutex _l(mLock);
3102
3103 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brown120a4592010-10-27 18:43:51 -07003104 if (mDispatchFrozen && !frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003105 resetANRTimeoutsLocked();
3106 }
3107
Jeff Brown120a4592010-10-27 18:43:51 -07003108 if (mDispatchEnabled && !enabled) {
3109 resetAndDropEverythingLocked("dispatcher is being disabled");
3110 }
3111
Jeff Brownb88102f2010-09-08 11:49:43 -07003112 mDispatchEnabled = enabled;
3113 mDispatchFrozen = frozen;
3114 changed = true;
3115 } else {
3116 changed = false;
3117 }
3118
3119#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07003120 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07003121#endif
3122 } // release lock
3123
3124 if (changed) {
3125 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003126 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07003127 }
3128}
3129
Jeff Brown0029c662011-03-30 02:25:18 -07003130void InputDispatcher::setInputFilterEnabled(bool enabled) {
3131#if DEBUG_FOCUS
3132 LOGD("setInputFilterEnabled: enabled=%d", enabled);
3133#endif
3134
3135 { // acquire lock
3136 AutoMutex _l(mLock);
3137
3138 if (mInputFilterEnabled == enabled) {
3139 return;
3140 }
3141
3142 mInputFilterEnabled = enabled;
3143 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3144 } // release lock
3145
3146 // Wake up poll loop since there might be work to do to drop everything.
3147 mLooper->wake();
3148}
3149
Jeff Browne6504122010-09-27 14:52:15 -07003150bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
3151 const sp<InputChannel>& toChannel) {
3152#if DEBUG_FOCUS
3153 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
3154 fromChannel->getName().string(), toChannel->getName().string());
3155#endif
3156 { // acquire lock
3157 AutoMutex _l(mLock);
3158
3159 const InputWindow* fromWindow = getWindowLocked(fromChannel);
3160 const InputWindow* toWindow = getWindowLocked(toChannel);
3161 if (! fromWindow || ! toWindow) {
3162#if DEBUG_FOCUS
3163 LOGD("Cannot transfer focus because from or to window not found.");
3164#endif
3165 return false;
3166 }
3167 if (fromWindow == toWindow) {
3168#if DEBUG_FOCUS
3169 LOGD("Trivial transfer to same window.");
3170#endif
3171 return true;
3172 }
3173
3174 bool found = false;
3175 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
3176 const TouchedWindow& touchedWindow = mTouchState.windows[i];
3177 if (touchedWindow.window == fromWindow) {
3178 int32_t oldTargetFlags = touchedWindow.targetFlags;
3179 BitSet32 pointerIds = touchedWindow.pointerIds;
3180
3181 mTouchState.windows.removeAt(i);
3182
Jeff Brown46e75292010-11-10 16:53:45 -08003183 int32_t newTargetFlags = oldTargetFlags
Jeff Browna032cc02011-03-07 16:56:21 -08003184 & (InputTarget::FLAG_FOREGROUND
3185 | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Browne6504122010-09-27 14:52:15 -07003186 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
3187
3188 found = true;
3189 break;
3190 }
3191 }
3192
3193 if (! found) {
3194#if DEBUG_FOCUS
3195 LOGD("Focus transfer failed because from window did not have focus.");
3196#endif
3197 return false;
3198 }
3199
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003200 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
3201 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
3202 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
3203 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
3204 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
3205
3206 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
Jeff Brownda3d5a92011-03-29 15:11:34 -07003207 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003208 "transferring touch focus from this window to another window");
Jeff Brownda3d5a92011-03-29 15:11:34 -07003209 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003210 }
3211
Jeff Browne6504122010-09-27 14:52:15 -07003212#if DEBUG_FOCUS
3213 logDispatchStateLocked();
3214#endif
3215 } // release lock
3216
3217 // Wake up poll loop since it may need to make new input dispatching choices.
3218 mLooper->wake();
3219 return true;
3220}
3221
Jeff Brown120a4592010-10-27 18:43:51 -07003222void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
3223#if DEBUG_FOCUS
3224 LOGD("Resetting and dropping all events (%s).", reason);
3225#endif
3226
Jeff Brownda3d5a92011-03-29 15:11:34 -07003227 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3228 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Brown120a4592010-10-27 18:43:51 -07003229
3230 resetKeyRepeatLocked();
3231 releasePendingEventLocked();
3232 drainInboundQueueLocked();
3233 resetTargetsLocked();
3234
3235 mTouchState.reset();
3236}
3237
Jeff Brownb88102f2010-09-08 11:49:43 -07003238void InputDispatcher::logDispatchStateLocked() {
3239 String8 dump;
3240 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07003241
3242 char* text = dump.lockBuffer(dump.size());
3243 char* start = text;
3244 while (*start != '\0') {
3245 char* end = strchr(start, '\n');
3246 if (*end == '\n') {
3247 *(end++) = '\0';
3248 }
3249 LOGD("%s", start);
3250 start = end;
3251 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003252}
3253
3254void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f48712010-10-01 17:46:21 -07003255 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
3256 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07003257
3258 if (mFocusedApplication) {
Jeff Brownf2f48712010-10-01 17:46:21 -07003259 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07003260 mFocusedApplication->name.string(),
3261 mFocusedApplication->dispatchingTimeout / 1000000.0);
3262 } else {
Jeff Brownf2f48712010-10-01 17:46:21 -07003263 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003264 }
Jeff Brownf2f48712010-10-01 17:46:21 -07003265 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07003266 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f48712010-10-01 17:46:21 -07003267
3268 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
3269 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
Jeff Brown95712852011-01-04 19:41:59 -08003270 dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
Jeff Brown58a2da82011-01-25 16:02:22 -08003271 dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
Jeff Brownf2f48712010-10-01 17:46:21 -07003272 if (!mTouchState.windows.isEmpty()) {
3273 dump.append(INDENT "TouchedWindows:\n");
3274 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
3275 const TouchedWindow& touchedWindow = mTouchState.windows[i];
3276 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3277 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
3278 touchedWindow.targetFlags);
3279 }
3280 } else {
3281 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003282 }
3283
Jeff Brownf2f48712010-10-01 17:46:21 -07003284 if (!mWindows.isEmpty()) {
3285 dump.append(INDENT "Windows:\n");
3286 for (size_t i = 0; i < mWindows.size(); i++) {
3287 const InputWindow& window = mWindows[i];
3288 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
3289 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003290 "frame=[%d,%d][%d,%d], scale=%f, "
Jeff Brownfbf09772011-01-16 14:06:57 -08003291 "touchableRegion=",
Jeff Brownf2f48712010-10-01 17:46:21 -07003292 i, window.name.string(),
3293 toString(window.paused),
3294 toString(window.hasFocus),
3295 toString(window.hasWallpaper),
3296 toString(window.visible),
3297 toString(window.canReceiveKeys),
3298 window.layoutParamsFlags, window.layoutParamsType,
3299 window.layer,
3300 window.frameLeft, window.frameTop,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003301 window.frameRight, window.frameBottom,
3302 window.scaleFactor);
Jeff Brownfbf09772011-01-16 14:06:57 -08003303 dumpRegion(dump, window.touchableRegion);
3304 dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Jeff Brownf2f48712010-10-01 17:46:21 -07003305 window.ownerPid, window.ownerUid,
3306 window.dispatchingTimeout / 1000000.0);
3307 }
3308 } else {
3309 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003310 }
3311
Jeff Brownf2f48712010-10-01 17:46:21 -07003312 if (!mMonitoringChannels.isEmpty()) {
3313 dump.append(INDENT "MonitoringChannels:\n");
3314 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3315 const sp<InputChannel>& channel = mMonitoringChannels[i];
3316 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
3317 }
3318 } else {
3319 dump.append(INDENT "MonitoringChannels: <none>\n");
3320 }
Jeff Brown519e0242010-09-15 15:18:56 -07003321
Jeff Brownf2f48712010-10-01 17:46:21 -07003322 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
3323
3324 if (!mActiveConnections.isEmpty()) {
3325 dump.append(INDENT "ActiveConnections:\n");
3326 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3327 const Connection* connection = mActiveConnections[i];
Jeff Brown76860e32010-10-25 17:37:46 -07003328 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brownb6997262010-10-08 22:31:17 -07003329 "inputState.isNeutral=%s\n",
Jeff Brownf2f48712010-10-01 17:46:21 -07003330 i, connection->getInputChannelName(), connection->getStatusLabel(),
3331 connection->outboundQueue.count(),
Jeff Brownb6997262010-10-08 22:31:17 -07003332 toString(connection->inputState.isNeutral()));
Jeff Brownf2f48712010-10-01 17:46:21 -07003333 }
3334 } else {
3335 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003336 }
3337
3338 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f48712010-10-01 17:46:21 -07003339 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07003340 (mAppSwitchDueTime - now()) / 1000000.0);
3341 } else {
Jeff Brownf2f48712010-10-01 17:46:21 -07003342 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003343 }
3344}
3345
Jeff Brown928e0542011-01-10 11:17:36 -08003346status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
3347 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003348#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07003349 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
3350 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07003351#endif
3352
Jeff Brown46b9ac02010-04-22 18:58:52 -07003353 { // acquire lock
3354 AutoMutex _l(mLock);
3355
Jeff Brown519e0242010-09-15 15:18:56 -07003356 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003357 LOGW("Attempted to register already registered input channel '%s'",
3358 inputChannel->getName().string());
3359 return BAD_VALUE;
3360 }
3361
Jeff Brown928e0542011-01-10 11:17:36 -08003362 sp<Connection> connection = new Connection(inputChannel, inputWindowHandle);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003363 status_t status = connection->initialize();
3364 if (status) {
3365 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
3366 inputChannel->getName().string(), status);
3367 return status;
3368 }
3369
Jeff Brown2cbecea2010-08-17 15:59:26 -07003370 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac02010-04-22 18:58:52 -07003371 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003372
Jeff Brownb88102f2010-09-08 11:49:43 -07003373 if (monitor) {
3374 mMonitoringChannels.push(inputChannel);
3375 }
3376
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003377 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07003378
Jeff Brown9c3cda02010-06-15 01:31:58 -07003379 runCommandsLockedInterruptible();
Jeff Brown46b9ac02010-04-22 18:58:52 -07003380 } // release lock
Jeff Brown46b9ac02010-04-22 18:58:52 -07003381 return OK;
3382}
3383
3384status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003385#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07003386 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07003387#endif
3388
Jeff Brown46b9ac02010-04-22 18:58:52 -07003389 { // acquire lock
3390 AutoMutex _l(mLock);
3391
Jeff Brown519e0242010-09-15 15:18:56 -07003392 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003393 if (connectionIndex < 0) {
3394 LOGW("Attempted to unregister already unregistered input channel '%s'",
3395 inputChannel->getName().string());
3396 return BAD_VALUE;
3397 }
3398
3399 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3400 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
3401
3402 connection->status = Connection::STATUS_ZOMBIE;
3403
Jeff Brownb88102f2010-09-08 11:49:43 -07003404 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3405 if (mMonitoringChannels[i] == inputChannel) {
3406 mMonitoringChannels.removeAt(i);
3407 break;
3408 }
3409 }
3410
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003411 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07003412
Jeff Brown7fbdc842010-06-17 20:52:56 -07003413 nsecs_t currentTime = now();
Jeff Brownb6997262010-10-08 22:31:17 -07003414 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003415
3416 runCommandsLockedInterruptible();
Jeff Brown46b9ac02010-04-22 18:58:52 -07003417 } // release lock
3418
Jeff Brown46b9ac02010-04-22 18:58:52 -07003419 // Wake the poll loop because removing the connection may have changed the current
3420 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003421 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07003422 return OK;
3423}
3424
Jeff Brown519e0242010-09-15 15:18:56 -07003425ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07003426 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
3427 if (connectionIndex >= 0) {
3428 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3429 if (connection->inputChannel.get() == inputChannel.get()) {
3430 return connectionIndex;
3431 }
3432 }
3433
3434 return -1;
3435}
3436
Jeff Brown46b9ac02010-04-22 18:58:52 -07003437void InputDispatcher::activateConnectionLocked(Connection* connection) {
3438 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3439 if (mActiveConnections.itemAt(i) == connection) {
3440 return;
3441 }
3442 }
3443 mActiveConnections.add(connection);
3444}
3445
3446void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
3447 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3448 if (mActiveConnections.itemAt(i) == connection) {
3449 mActiveConnections.removeAt(i);
3450 return;
3451 }
3452 }
3453}
3454
Jeff Brown9c3cda02010-06-15 01:31:58 -07003455void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003456 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003457}
3458
Jeff Brown9c3cda02010-06-15 01:31:58 -07003459void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown3915bb82010-11-05 15:02:16 -07003460 nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
3461 CommandEntry* commandEntry = postCommandLocked(
3462 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
3463 commandEntry->connection = connection;
3464 commandEntry->handled = handled;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003465}
3466
Jeff Brown9c3cda02010-06-15 01:31:58 -07003467void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003468 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003469 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3470 connection->getInputChannelName());
3471
Jeff Brown9c3cda02010-06-15 01:31:58 -07003472 CommandEntry* commandEntry = postCommandLocked(
3473 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003474 commandEntry->connection = connection;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003475}
3476
Jeff Brown519e0242010-09-15 15:18:56 -07003477void InputDispatcher::onANRLocked(
3478 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
3479 nsecs_t eventTime, nsecs_t waitStartTime) {
3480 LOGI("Application is not responding: %s. "
3481 "%01.1fms since event, %01.1fms since wait started",
3482 getApplicationWindowLabelLocked(application, window).string(),
3483 (currentTime - eventTime) / 1000000.0,
3484 (currentTime - waitStartTime) / 1000000.0);
3485
3486 CommandEntry* commandEntry = postCommandLocked(
3487 & InputDispatcher::doNotifyANRLockedInterruptible);
3488 if (application) {
Jeff Brown928e0542011-01-10 11:17:36 -08003489 commandEntry->inputApplicationHandle = application->inputApplicationHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003490 }
3491 if (window) {
Jeff Brown928e0542011-01-10 11:17:36 -08003492 commandEntry->inputWindowHandle = window->inputWindowHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003493 commandEntry->inputChannel = window->inputChannel;
3494 }
3495}
3496
Jeff Brownb88102f2010-09-08 11:49:43 -07003497void InputDispatcher::doNotifyConfigurationChangedInterruptible(
3498 CommandEntry* commandEntry) {
3499 mLock.unlock();
3500
3501 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
3502
3503 mLock.lock();
3504}
3505
Jeff Brown9c3cda02010-06-15 01:31:58 -07003506void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
3507 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003508 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07003509
Jeff Brown7fbdc842010-06-17 20:52:56 -07003510 if (connection->status != Connection::STATUS_ZOMBIE) {
3511 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003512
Jeff Brown928e0542011-01-10 11:17:36 -08003513 mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003514
3515 mLock.lock();
3516 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07003517}
3518
Jeff Brown519e0242010-09-15 15:18:56 -07003519void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07003520 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07003521 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003522
Jeff Brown519e0242010-09-15 15:18:56 -07003523 nsecs_t newTimeout = mPolicy->notifyANR(
Jeff Brown928e0542011-01-10 11:17:36 -08003524 commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003525
Jeff Brown519e0242010-09-15 15:18:56 -07003526 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07003527
Jeff Brown519e0242010-09-15 15:18:56 -07003528 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003529}
3530
Jeff Brownb88102f2010-09-08 11:49:43 -07003531void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3532 CommandEntry* commandEntry) {
3533 KeyEntry* entry = commandEntry->keyEntry;
Jeff Brown1f245102010-11-18 20:53:46 -08003534
3535 KeyEvent event;
3536 initializeKeyEvent(&event, entry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003537
3538 mLock.unlock();
3539
Jeff Brown928e0542011-01-10 11:17:36 -08003540 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
Jeff Brown1f245102010-11-18 20:53:46 -08003541 &event, entry->policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -07003542
3543 mLock.lock();
3544
3545 entry->interceptKeyResult = consumed
3546 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
3547 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3548 mAllocator.releaseKeyEntry(entry);
3549}
3550
Jeff Brown3915bb82010-11-05 15:02:16 -07003551void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3552 CommandEntry* commandEntry) {
3553 sp<Connection> connection = commandEntry->connection;
3554 bool handled = commandEntry->handled;
3555
Jeff Brown49ed71d2010-12-06 17:13:33 -08003556 if (!connection->outboundQueue.isEmpty()) {
Jeff Brown3915bb82010-11-05 15:02:16 -07003557 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
3558 if (dispatchEntry->inProgress
Jeff Brown3915bb82010-11-05 15:02:16 -07003559 && dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3560 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003561 if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
Jeff Brownda3d5a92011-03-29 15:11:34 -07003562 // Get the fallback key state.
3563 // Clear it out after dispatching the UP.
3564 int32_t originalKeyCode = keyEntry->keyCode;
3565 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
3566 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
3567 connection->inputState.removeFallbackKey(originalKeyCode);
3568 }
3569
3570 if (handled || !dispatchEntry->hasForegroundTarget()) {
3571 // If the application handles the original key for which we previously
3572 // generated a fallback or if the window is not a foreground window,
3573 // then cancel the associated fallback key, if any.
3574 if (fallbackKeyCode != -1) {
3575 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
3576 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
3577 "application handled the original non-fallback key "
3578 "or is no longer a foreground target, "
3579 "canceling previously dispatched fallback key");
3580 options.keyCode = fallbackKeyCode;
3581 synthesizeCancelationEventsForConnectionLocked(connection, options);
3582 }
3583 connection->inputState.removeFallbackKey(originalKeyCode);
3584 }
Jeff Brown49ed71d2010-12-06 17:13:33 -08003585 } else {
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003586 // If the application did not handle a non-fallback key, first check
Jeff Brownda3d5a92011-03-29 15:11:34 -07003587 // that we are in a good state to perform unhandled key event processing
3588 // Then ask the policy what to do with it.
3589 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
3590 && keyEntry->repeatCount == 0;
3591 if (fallbackKeyCode == -1 && !initialDown) {
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003592#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownda3d5a92011-03-29 15:11:34 -07003593 LOGD("Unhandled key event: Skipping unhandled key event processing "
3594 "since this is not an initial down. "
3595 "keyCode=%d, action=%d, repeatCount=%d",
3596 originalKeyCode, keyEntry->action, keyEntry->repeatCount);
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003597#endif
Jeff Brownda3d5a92011-03-29 15:11:34 -07003598 goto SkipFallback;
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003599 }
3600
Jeff Brownda3d5a92011-03-29 15:11:34 -07003601 // Dispatch the unhandled key to the policy.
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003602#if DEBUG_OUTBOUND_EVENT_DETAILS
3603 LOGD("Unhandled key event: Asking policy to perform fallback action. "
3604 "keyCode=%d, action=%d, repeatCount=%d",
3605 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount);
3606#endif
Jeff Brown49ed71d2010-12-06 17:13:33 -08003607 KeyEvent event;
3608 initializeKeyEvent(&event, keyEntry);
Jeff Brown3915bb82010-11-05 15:02:16 -07003609
Jeff Brown49ed71d2010-12-06 17:13:33 -08003610 mLock.unlock();
Jeff Brown3915bb82010-11-05 15:02:16 -07003611
Jeff Brown928e0542011-01-10 11:17:36 -08003612 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003613 &event, keyEntry->policyFlags, &event);
Jeff Brown3915bb82010-11-05 15:02:16 -07003614
Jeff Brown49ed71d2010-12-06 17:13:33 -08003615 mLock.lock();
3616
Jeff Brown00045a72010-12-09 18:10:30 -08003617 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownda3d5a92011-03-29 15:11:34 -07003618 connection->inputState.removeFallbackKey(originalKeyCode);
Jeff Brown00045a72010-12-09 18:10:30 -08003619 return;
3620 }
3621
Jeff Brownb6110c22011-04-01 16:15:13 -07003622 LOG_ASSERT(connection->outboundQueue.headSentinel.next == dispatchEntry);
Jeff Brown00045a72010-12-09 18:10:30 -08003623
Jeff Brownda3d5a92011-03-29 15:11:34 -07003624 // Latch the fallback keycode for this key on an initial down.
3625 // The fallback keycode cannot change at any other point in the lifecycle.
3626 if (initialDown) {
3627 if (fallback) {
3628 fallbackKeyCode = event.getKeyCode();
3629 } else {
3630 fallbackKeyCode = AKEYCODE_UNKNOWN;
3631 }
3632 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
3633 }
3634
Jeff Brownb6110c22011-04-01 16:15:13 -07003635 LOG_ASSERT(fallbackKeyCode != -1);
Jeff Brownda3d5a92011-03-29 15:11:34 -07003636
3637 // Cancel the fallback key if the policy decides not to send it anymore.
3638 // We will continue to dispatch the key to the policy but we will no
3639 // longer dispatch a fallback key to the application.
3640 if (fallbackKeyCode != AKEYCODE_UNKNOWN
3641 && (!fallback || fallbackKeyCode != event.getKeyCode())) {
3642#if DEBUG_OUTBOUND_EVENT_DETAILS
3643 if (fallback) {
3644 LOGD("Unhandled key event: Policy requested to send key %d"
3645 "as a fallback for %d, but on the DOWN it had requested "
3646 "to send %d instead. Fallback canceled.",
3647 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
3648 } else {
3649 LOGD("Unhandled key event: Policy did not request fallback for %d,"
3650 "but on the DOWN it had requested to send %d. "
3651 "Fallback canceled.",
3652 originalKeyCode, fallbackKeyCode);
3653 }
3654#endif
3655
3656 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
3657 "canceling fallback, policy no longer desires it");
3658 options.keyCode = fallbackKeyCode;
3659 synthesizeCancelationEventsForConnectionLocked(connection, options);
3660
3661 fallback = false;
3662 fallbackKeyCode = AKEYCODE_UNKNOWN;
3663 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
3664 connection->inputState.setFallbackKey(originalKeyCode,
3665 fallbackKeyCode);
3666 }
3667 }
3668
3669#if DEBUG_OUTBOUND_EVENT_DETAILS
3670 {
3671 String8 msg;
3672 const KeyedVector<int32_t, int32_t>& fallbackKeys =
3673 connection->inputState.getFallbackKeys();
3674 for (size_t i = 0; i < fallbackKeys.size(); i++) {
3675 msg.appendFormat(", %d->%d", fallbackKeys.keyAt(i),
3676 fallbackKeys.valueAt(i));
3677 }
3678 LOGD("Unhandled key event: %d currently tracked fallback keys%s.",
3679 fallbackKeys.size(), msg.string());
3680 }
3681#endif
3682
Jeff Brown49ed71d2010-12-06 17:13:33 -08003683 if (fallback) {
3684 // Restart the dispatch cycle using the fallback key.
3685 keyEntry->eventTime = event.getEventTime();
3686 keyEntry->deviceId = event.getDeviceId();
3687 keyEntry->source = event.getSource();
3688 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
Jeff Brownda3d5a92011-03-29 15:11:34 -07003689 keyEntry->keyCode = fallbackKeyCode;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003690 keyEntry->scanCode = event.getScanCode();
3691 keyEntry->metaState = event.getMetaState();
3692 keyEntry->repeatCount = event.getRepeatCount();
3693 keyEntry->downTime = event.getDownTime();
3694 keyEntry->syntheticRepeat = false;
3695
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003696#if DEBUG_OUTBOUND_EVENT_DETAILS
3697 LOGD("Unhandled key event: Dispatching fallback key. "
Jeff Brownda3d5a92011-03-29 15:11:34 -07003698 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
3699 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003700#endif
3701
Jeff Brown49ed71d2010-12-06 17:13:33 -08003702 dispatchEntry->inProgress = false;
3703 startDispatchCycleLocked(now(), connection);
3704 return;
Jeff Brownda3d5a92011-03-29 15:11:34 -07003705 } else {
3706#if DEBUG_OUTBOUND_EVENT_DETAILS
3707 LOGD("Unhandled key event: No fallback key.");
3708#endif
Jeff Brown49ed71d2010-12-06 17:13:33 -08003709 }
3710 }
3711 }
Jeff Brown3915bb82010-11-05 15:02:16 -07003712 }
3713 }
3714
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003715SkipFallback:
Jeff Brown3915bb82010-11-05 15:02:16 -07003716 startNextDispatchCycleLocked(now(), connection);
3717}
3718
Jeff Brownb88102f2010-09-08 11:49:43 -07003719void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3720 mLock.unlock();
3721
Jeff Brown01ce2e92010-09-26 22:20:12 -07003722 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07003723
3724 mLock.lock();
3725}
3726
Jeff Brown3915bb82010-11-05 15:02:16 -07003727void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
3728 event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3729 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3730 entry->downTime, entry->eventTime);
3731}
3732
Jeff Brown519e0242010-09-15 15:18:56 -07003733void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3734 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3735 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07003736}
3737
3738void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f48712010-10-01 17:46:21 -07003739 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003740 dumpDispatchStateLocked(dump);
3741}
3742
Jeff Brown9c3cda02010-06-15 01:31:58 -07003743
Jeff Brown519e0242010-09-15 15:18:56 -07003744// --- InputDispatcher::Queue ---
3745
3746template <typename T>
3747uint32_t InputDispatcher::Queue<T>::count() const {
3748 uint32_t result = 0;
3749 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3750 result += 1;
3751 }
3752 return result;
3753}
3754
3755
Jeff Brown46b9ac02010-04-22 18:58:52 -07003756// --- InputDispatcher::Allocator ---
3757
3758InputDispatcher::Allocator::Allocator() {
3759}
3760
Jeff Brown01ce2e92010-09-26 22:20:12 -07003761InputDispatcher::InjectionState*
3762InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3763 InjectionState* injectionState = mInjectionStatePool.alloc();
3764 injectionState->refCount = 1;
3765 injectionState->injectorPid = injectorPid;
3766 injectionState->injectorUid = injectorUid;
3767 injectionState->injectionIsAsync = false;
3768 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3769 injectionState->pendingForegroundDispatches = 0;
3770 return injectionState;
3771}
3772
Jeff Brown7fbdc842010-06-17 20:52:56 -07003773void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brownb6997262010-10-08 22:31:17 -07003774 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003775 entry->type = type;
3776 entry->refCount = 1;
3777 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07003778 entry->eventTime = eventTime;
Jeff Brownb6997262010-10-08 22:31:17 -07003779 entry->policyFlags = policyFlags;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003780 entry->injectionState = NULL;
3781}
3782
3783void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3784 if (entry->injectionState) {
3785 releaseInjectionState(entry->injectionState);
3786 entry->injectionState = NULL;
3787 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07003788}
3789
Jeff Brown46b9ac02010-04-22 18:58:52 -07003790InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07003791InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003792 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003793 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003794 return entry;
3795}
3796
Jeff Brown7fbdc842010-06-17 20:52:56 -07003797InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown58a2da82011-01-25 16:02:22 -08003798 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003799 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3800 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003801 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003802 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003803
3804 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003805 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003806 entry->action = action;
3807 entry->flags = flags;
3808 entry->keyCode = keyCode;
3809 entry->scanCode = scanCode;
3810 entry->metaState = metaState;
3811 entry->repeatCount = repeatCount;
3812 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003813 entry->syntheticRepeat = false;
3814 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003815 return entry;
3816}
3817
Jeff Brown7fbdc842010-06-17 20:52:56 -07003818InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown58a2da82011-01-25 16:02:22 -08003819 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003820 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3821 nsecs_t downTime, uint32_t pointerCount,
3822 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003823 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003824 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003825
3826 entry->eventTime = eventTime;
3827 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003828 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003829 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07003830 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003831 entry->metaState = metaState;
3832 entry->edgeFlags = edgeFlags;
3833 entry->xPrecision = xPrecision;
3834 entry->yPrecision = yPrecision;
3835 entry->downTime = downTime;
3836 entry->pointerCount = pointerCount;
3837 entry->firstSample.eventTime = eventTime;
Jeff Brown4e91a182011-04-07 11:38:09 -07003838 entry->firstSample.eventTimeBeforeCoalescing = eventTime;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003839 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003840 entry->lastSample = & entry->firstSample;
3841 for (uint32_t i = 0; i < pointerCount; i++) {
3842 entry->pointerIds[i] = pointerIds[i];
Jeff Brownace13b12011-03-09 17:39:48 -08003843 entry->firstSample.pointerCoords[i].copyFrom(pointerCoords[i]);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003844 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07003845 return entry;
3846}
3847
3848InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07003849 EventEntry* eventEntry,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003850 int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003851 DispatchEntry* entry = mDispatchEntryPool.alloc();
3852 entry->eventEntry = eventEntry;
3853 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07003854 entry->targetFlags = targetFlags;
3855 entry->xOffset = xOffset;
3856 entry->yOffset = yOffset;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003857 entry->scaleFactor = scaleFactor;
Jeff Brownb88102f2010-09-08 11:49:43 -07003858 entry->inProgress = false;
3859 entry->headMotionSample = NULL;
3860 entry->tailMotionSample = NULL;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003861 return entry;
3862}
3863
Jeff Brown9c3cda02010-06-15 01:31:58 -07003864InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3865 CommandEntry* entry = mCommandEntryPool.alloc();
3866 entry->command = command;
3867 return entry;
3868}
3869
Jeff Brown01ce2e92010-09-26 22:20:12 -07003870void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3871 injectionState->refCount -= 1;
3872 if (injectionState->refCount == 0) {
3873 mInjectionStatePool.free(injectionState);
3874 } else {
Jeff Brownb6110c22011-04-01 16:15:13 -07003875 LOG_ASSERT(injectionState->refCount > 0);
Jeff Brown01ce2e92010-09-26 22:20:12 -07003876 }
3877}
3878
Jeff Brown46b9ac02010-04-22 18:58:52 -07003879void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3880 switch (entry->type) {
3881 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3882 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3883 break;
3884 case EventEntry::TYPE_KEY:
3885 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3886 break;
3887 case EventEntry::TYPE_MOTION:
3888 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3889 break;
3890 default:
Jeff Brownb6110c22011-04-01 16:15:13 -07003891 LOG_ASSERT(false);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003892 break;
3893 }
3894}
3895
3896void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3897 ConfigurationChangedEntry* entry) {
3898 entry->refCount -= 1;
3899 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003900 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003901 mConfigurationChangeEntryPool.free(entry);
3902 } else {
Jeff Brownb6110c22011-04-01 16:15:13 -07003903 LOG_ASSERT(entry->refCount > 0);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003904 }
3905}
3906
3907void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3908 entry->refCount -= 1;
3909 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003910 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003911 mKeyEntryPool.free(entry);
3912 } else {
Jeff Brownb6110c22011-04-01 16:15:13 -07003913 LOG_ASSERT(entry->refCount > 0);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003914 }
3915}
3916
3917void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3918 entry->refCount -= 1;
3919 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003920 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003921 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3922 MotionSample* next = sample->next;
3923 mMotionSamplePool.free(sample);
3924 sample = next;
3925 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07003926 mMotionEntryPool.free(entry);
3927 } else {
Jeff Brownb6110c22011-04-01 16:15:13 -07003928 LOG_ASSERT(entry->refCount > 0);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003929 }
3930}
3931
Jeff Browna032cc02011-03-07 16:56:21 -08003932void InputDispatcher::Allocator::freeMotionSample(MotionSample* sample) {
3933 mMotionSamplePool.free(sample);
3934}
3935
Jeff Brown46b9ac02010-04-22 18:58:52 -07003936void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3937 releaseEventEntry(entry->eventEntry);
3938 mDispatchEntryPool.free(entry);
3939}
3940
Jeff Brown9c3cda02010-06-15 01:31:58 -07003941void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3942 mCommandEntryPool.free(entry);
3943}
3944
Jeff Brown46b9ac02010-04-22 18:58:52 -07003945void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003946 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003947 MotionSample* sample = mMotionSamplePool.alloc();
3948 sample->eventTime = eventTime;
Jeff Brown4e91a182011-04-07 11:38:09 -07003949 sample->eventTimeBeforeCoalescing = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003950 uint32_t pointerCount = motionEntry->pointerCount;
3951 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brownace13b12011-03-09 17:39:48 -08003952 sample->pointerCoords[i].copyFrom(pointerCoords[i]);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003953 }
3954
3955 sample->next = NULL;
3956 motionEntry->lastSample->next = sample;
3957 motionEntry->lastSample = sample;
3958}
3959
Jeff Brown01ce2e92010-09-26 22:20:12 -07003960void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3961 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003962
Jeff Brown01ce2e92010-09-26 22:20:12 -07003963 keyEntry->dispatchInProgress = false;
3964 keyEntry->syntheticRepeat = false;
3965 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003966}
3967
3968
Jeff Brownae9fc032010-08-18 15:51:08 -07003969// --- InputDispatcher::MotionEntry ---
3970
3971uint32_t InputDispatcher::MotionEntry::countSamples() const {
3972 uint32_t count = 1;
3973 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3974 count += 1;
3975 }
3976 return count;
3977}
3978
Jeff Brown4e91a182011-04-07 11:38:09 -07003979bool InputDispatcher::MotionEntry::canAppendSamples(int32_t action, uint32_t pointerCount,
3980 const int32_t* pointerIds) const {
3981 if (this->action != action
3982 || this->pointerCount != pointerCount
3983 || this->isInjected()) {
3984 return false;
3985 }
3986 for (uint32_t i = 0; i < pointerCount; i++) {
3987 if (this->pointerIds[i] != pointerIds[i]) {
3988 return false;
3989 }
3990 }
3991 return true;
3992}
3993
Jeff Brownb88102f2010-09-08 11:49:43 -07003994
3995// --- InputDispatcher::InputState ---
3996
Jeff Brownb6997262010-10-08 22:31:17 -07003997InputDispatcher::InputState::InputState() {
Jeff Brownb88102f2010-09-08 11:49:43 -07003998}
3999
4000InputDispatcher::InputState::~InputState() {
4001}
4002
4003bool InputDispatcher::InputState::isNeutral() const {
4004 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
4005}
4006
Jeff Browna032cc02011-03-07 16:56:21 -08004007void InputDispatcher::InputState::trackEvent(const EventEntry* entry, int32_t action) {
Jeff Brownb88102f2010-09-08 11:49:43 -07004008 switch (entry->type) {
4009 case EventEntry::TYPE_KEY:
Jeff Browna032cc02011-03-07 16:56:21 -08004010 trackKey(static_cast<const KeyEntry*>(entry), action);
Jeff Browncc0c1592011-02-19 05:07:28 -08004011 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07004012
4013 case EventEntry::TYPE_MOTION:
Jeff Browna032cc02011-03-07 16:56:21 -08004014 trackMotion(static_cast<const MotionEntry*>(entry), action);
Jeff Browncc0c1592011-02-19 05:07:28 -08004015 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07004016 }
4017}
4018
Jeff Browna032cc02011-03-07 16:56:21 -08004019void InputDispatcher::InputState::trackKey(const KeyEntry* entry, int32_t action) {
Jeff Brownda3d5a92011-03-29 15:11:34 -07004020 if (action == AKEY_EVENT_ACTION_UP
4021 && (entry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
4022 for (size_t i = 0; i < mFallbackKeys.size(); ) {
4023 if (mFallbackKeys.valueAt(i) == entry->keyCode) {
4024 mFallbackKeys.removeItemsAt(i);
4025 } else {
4026 i += 1;
4027 }
4028 }
4029 }
4030
Jeff Brownb88102f2010-09-08 11:49:43 -07004031 for (size_t i = 0; i < mKeyMementos.size(); i++) {
4032 KeyMemento& memento = mKeyMementos.editItemAt(i);
4033 if (memento.deviceId == entry->deviceId
4034 && memento.source == entry->source
4035 && memento.keyCode == entry->keyCode
4036 && memento.scanCode == entry->scanCode) {
4037 switch (action) {
4038 case AKEY_EVENT_ACTION_UP:
4039 mKeyMementos.removeAt(i);
Jeff Browncc0c1592011-02-19 05:07:28 -08004040 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07004041
4042 case AKEY_EVENT_ACTION_DOWN:
Jeff Browncc0c1592011-02-19 05:07:28 -08004043 mKeyMementos.removeAt(i);
4044 goto Found;
Jeff Brownb88102f2010-09-08 11:49:43 -07004045
4046 default:
Jeff Browncc0c1592011-02-19 05:07:28 -08004047 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07004048 }
4049 }
4050 }
4051
Jeff Browncc0c1592011-02-19 05:07:28 -08004052Found:
4053 if (action == AKEY_EVENT_ACTION_DOWN) {
Jeff Brownb88102f2010-09-08 11:49:43 -07004054 mKeyMementos.push();
4055 KeyMemento& memento = mKeyMementos.editTop();
4056 memento.deviceId = entry->deviceId;
4057 memento.source = entry->source;
4058 memento.keyCode = entry->keyCode;
4059 memento.scanCode = entry->scanCode;
Jeff Brown49ed71d2010-12-06 17:13:33 -08004060 memento.flags = entry->flags;
Jeff Brownb88102f2010-09-08 11:49:43 -07004061 memento.downTime = entry->downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07004062 }
4063}
4064
Jeff Browna032cc02011-03-07 16:56:21 -08004065void InputDispatcher::InputState::trackMotion(const MotionEntry* entry, int32_t action) {
4066 int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07004067 for (size_t i = 0; i < mMotionMementos.size(); i++) {
4068 MotionMemento& memento = mMotionMementos.editItemAt(i);
4069 if (memento.deviceId == entry->deviceId
4070 && memento.source == entry->source) {
Jeff Browna032cc02011-03-07 16:56:21 -08004071 switch (actionMasked) {
Jeff Brownb88102f2010-09-08 11:49:43 -07004072 case AMOTION_EVENT_ACTION_UP:
4073 case AMOTION_EVENT_ACTION_CANCEL:
Jeff Browna032cc02011-03-07 16:56:21 -08004074 case AMOTION_EVENT_ACTION_HOVER_ENTER:
Jeff Browncc0c1592011-02-19 05:07:28 -08004075 case AMOTION_EVENT_ACTION_HOVER_MOVE:
Jeff Browna032cc02011-03-07 16:56:21 -08004076 case AMOTION_EVENT_ACTION_HOVER_EXIT:
Jeff Brownb88102f2010-09-08 11:49:43 -07004077 mMotionMementos.removeAt(i);
Jeff Browncc0c1592011-02-19 05:07:28 -08004078 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07004079
4080 case AMOTION_EVENT_ACTION_DOWN:
Jeff Browncc0c1592011-02-19 05:07:28 -08004081 mMotionMementos.removeAt(i);
4082 goto Found;
Jeff Brownb88102f2010-09-08 11:49:43 -07004083
4084 case AMOTION_EVENT_ACTION_POINTER_UP:
Jeff Browncc0c1592011-02-19 05:07:28 -08004085 case AMOTION_EVENT_ACTION_POINTER_DOWN:
Jeff Brownb88102f2010-09-08 11:49:43 -07004086 case AMOTION_EVENT_ACTION_MOVE:
Jeff Browncc0c1592011-02-19 05:07:28 -08004087 memento.setPointers(entry);
4088 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07004089
4090 default:
Jeff Browncc0c1592011-02-19 05:07:28 -08004091 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07004092 }
4093 }
4094 }
4095
Jeff Browncc0c1592011-02-19 05:07:28 -08004096Found:
Jeff Browna032cc02011-03-07 16:56:21 -08004097 switch (actionMasked) {
4098 case AMOTION_EVENT_ACTION_DOWN:
4099 case AMOTION_EVENT_ACTION_HOVER_ENTER:
4100 case AMOTION_EVENT_ACTION_HOVER_MOVE:
4101 case AMOTION_EVENT_ACTION_HOVER_EXIT:
Jeff Brownb88102f2010-09-08 11:49:43 -07004102 mMotionMementos.push();
4103 MotionMemento& memento = mMotionMementos.editTop();
4104 memento.deviceId = entry->deviceId;
4105 memento.source = entry->source;
4106 memento.xPrecision = entry->xPrecision;
4107 memento.yPrecision = entry->yPrecision;
4108 memento.downTime = entry->downTime;
4109 memento.setPointers(entry);
Jeff Browna032cc02011-03-07 16:56:21 -08004110 memento.hovering = actionMasked != AMOTION_EVENT_ACTION_DOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07004111 }
4112}
4113
4114void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
4115 pointerCount = entry->pointerCount;
4116 for (uint32_t i = 0; i < entry->pointerCount; i++) {
4117 pointerIds[i] = entry->pointerIds[i];
Jeff Brownace13b12011-03-09 17:39:48 -08004118 pointerCoords[i].copyFrom(entry->lastSample->pointerCoords[i]);
Jeff Brownb88102f2010-09-08 11:49:43 -07004119 }
4120}
4121
Jeff Brownb6997262010-10-08 22:31:17 -07004122void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
4123 Allocator* allocator, Vector<EventEntry*>& outEvents,
Jeff Brownda3d5a92011-03-29 15:11:34 -07004124 const CancelationOptions& options) {
Jeff Brownb6997262010-10-08 22:31:17 -07004125 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07004126 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08004127 if (shouldCancelKey(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07004128 outEvents.push(allocator->obtainKeyEntry(currentTime,
4129 memento.deviceId, memento.source, 0,
Jeff Brown49ed71d2010-12-06 17:13:33 -08004130 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
Jeff Brownb6997262010-10-08 22:31:17 -07004131 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
4132 mKeyMementos.removeAt(i);
4133 } else {
4134 i += 1;
4135 }
Jeff Brownb88102f2010-09-08 11:49:43 -07004136 }
4137
Jeff Browna1160a72010-10-11 18:22:53 -07004138 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07004139 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08004140 if (shouldCancelMotion(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07004141 outEvents.push(allocator->obtainMotionEntry(currentTime,
4142 memento.deviceId, memento.source, 0,
Jeff Browna032cc02011-03-07 16:56:21 -08004143 memento.hovering
4144 ? AMOTION_EVENT_ACTION_HOVER_EXIT
4145 : AMOTION_EVENT_ACTION_CANCEL,
4146 0, 0, 0,
Jeff Brownb6997262010-10-08 22:31:17 -07004147 memento.xPrecision, memento.yPrecision, memento.downTime,
4148 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
4149 mMotionMementos.removeAt(i);
4150 } else {
4151 i += 1;
4152 }
Jeff Brownb88102f2010-09-08 11:49:43 -07004153 }
4154}
4155
4156void InputDispatcher::InputState::clear() {
4157 mKeyMementos.clear();
4158 mMotionMementos.clear();
Jeff Brownda3d5a92011-03-29 15:11:34 -07004159 mFallbackKeys.clear();
Jeff Brownb6997262010-10-08 22:31:17 -07004160}
4161
Jeff Brown9c9f1a32010-10-11 18:32:20 -07004162void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
4163 for (size_t i = 0; i < mMotionMementos.size(); i++) {
4164 const MotionMemento& memento = mMotionMementos.itemAt(i);
4165 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
4166 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
4167 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
4168 if (memento.deviceId == otherMemento.deviceId
4169 && memento.source == otherMemento.source) {
4170 other.mMotionMementos.removeAt(j);
4171 } else {
4172 j += 1;
4173 }
4174 }
4175 other.mMotionMementos.push(memento);
4176 }
4177 }
4178}
4179
Jeff Brownda3d5a92011-03-29 15:11:34 -07004180int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
4181 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
4182 return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
4183}
4184
4185void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
4186 int32_t fallbackKeyCode) {
4187 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
4188 if (index >= 0) {
4189 mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
4190 } else {
4191 mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
4192 }
4193}
4194
4195void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
4196 mFallbackKeys.removeItem(originalKeyCode);
4197}
4198
Jeff Brown49ed71d2010-12-06 17:13:33 -08004199bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
Jeff Brownda3d5a92011-03-29 15:11:34 -07004200 const CancelationOptions& options) {
4201 if (options.keyCode != -1 && memento.keyCode != options.keyCode) {
4202 return false;
4203 }
4204
4205 switch (options.mode) {
4206 case CancelationOptions::CANCEL_ALL_EVENTS:
4207 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07004208 return true;
Jeff Brownda3d5a92011-03-29 15:11:34 -07004209 case CancelationOptions::CANCEL_FALLBACK_EVENTS:
Jeff Brown49ed71d2010-12-06 17:13:33 -08004210 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
4211 default:
4212 return false;
4213 }
4214}
4215
4216bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
Jeff Brownda3d5a92011-03-29 15:11:34 -07004217 const CancelationOptions& options) {
4218 switch (options.mode) {
4219 case CancelationOptions::CANCEL_ALL_EVENTS:
Jeff Brown49ed71d2010-12-06 17:13:33 -08004220 return true;
Jeff Brownda3d5a92011-03-29 15:11:34 -07004221 case CancelationOptions::CANCEL_POINTER_EVENTS:
Jeff Brown49ed71d2010-12-06 17:13:33 -08004222 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
Jeff Brownda3d5a92011-03-29 15:11:34 -07004223 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
Jeff Brown49ed71d2010-12-06 17:13:33 -08004224 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
4225 default:
4226 return false;
Jeff Brownb6997262010-10-08 22:31:17 -07004227 }
Jeff Brownb88102f2010-09-08 11:49:43 -07004228}
4229
4230
Jeff Brown46b9ac02010-04-22 18:58:52 -07004231// --- InputDispatcher::Connection ---
4232
Jeff Brown928e0542011-01-10 11:17:36 -08004233InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
4234 const sp<InputWindowHandle>& inputWindowHandle) :
4235 status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
4236 inputPublisher(inputChannel),
Jeff Brownda3d5a92011-03-29 15:11:34 -07004237 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07004238}
4239
4240InputDispatcher::Connection::~Connection() {
4241}
4242
4243status_t InputDispatcher::Connection::initialize() {
4244 return inputPublisher.initialize();
4245}
4246
Jeff Brown9c3cda02010-06-15 01:31:58 -07004247const char* InputDispatcher::Connection::getStatusLabel() const {
4248 switch (status) {
4249 case STATUS_NORMAL:
4250 return "NORMAL";
4251
4252 case STATUS_BROKEN:
4253 return "BROKEN";
4254
Jeff Brown9c3cda02010-06-15 01:31:58 -07004255 case STATUS_ZOMBIE:
4256 return "ZOMBIE";
4257
4258 default:
4259 return "UNKNOWN";
4260 }
4261}
4262
Jeff Brown46b9ac02010-04-22 18:58:52 -07004263InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
4264 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07004265 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
4266 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07004267 if (dispatchEntry->eventEntry == eventEntry) {
4268 return dispatchEntry;
4269 }
4270 }
4271 return NULL;
4272}
4273
Jeff Brownb88102f2010-09-08 11:49:43 -07004274
Jeff Brown9c3cda02010-06-15 01:31:58 -07004275// --- InputDispatcher::CommandEntry ---
4276
Jeff Brownb88102f2010-09-08 11:49:43 -07004277InputDispatcher::CommandEntry::CommandEntry() :
4278 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07004279}
4280
4281InputDispatcher::CommandEntry::~CommandEntry() {
4282}
4283
Jeff Brown46b9ac02010-04-22 18:58:52 -07004284
Jeff Brown01ce2e92010-09-26 22:20:12 -07004285// --- InputDispatcher::TouchState ---
4286
4287InputDispatcher::TouchState::TouchState() :
Jeff Brown58a2da82011-01-25 16:02:22 -08004288 down(false), split(false), deviceId(-1), source(0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07004289}
4290
4291InputDispatcher::TouchState::~TouchState() {
4292}
4293
4294void InputDispatcher::TouchState::reset() {
4295 down = false;
4296 split = false;
Jeff Brown95712852011-01-04 19:41:59 -08004297 deviceId = -1;
Jeff Brown58a2da82011-01-25 16:02:22 -08004298 source = 0;
Jeff Brown01ce2e92010-09-26 22:20:12 -07004299 windows.clear();
4300}
4301
4302void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
4303 down = other.down;
4304 split = other.split;
Jeff Brown95712852011-01-04 19:41:59 -08004305 deviceId = other.deviceId;
Jeff Brown58a2da82011-01-25 16:02:22 -08004306 source = other.source;
Jeff Brown01ce2e92010-09-26 22:20:12 -07004307 windows.clear();
4308 windows.appendVector(other.windows);
4309}
4310
4311void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
4312 int32_t targetFlags, BitSet32 pointerIds) {
4313 if (targetFlags & InputTarget::FLAG_SPLIT) {
4314 split = true;
4315 }
4316
4317 for (size_t i = 0; i < windows.size(); i++) {
4318 TouchedWindow& touchedWindow = windows.editItemAt(i);
4319 if (touchedWindow.window == window) {
4320 touchedWindow.targetFlags |= targetFlags;
4321 touchedWindow.pointerIds.value |= pointerIds.value;
4322 return;
4323 }
4324 }
4325
4326 windows.push();
4327
4328 TouchedWindow& touchedWindow = windows.editTop();
4329 touchedWindow.window = window;
4330 touchedWindow.targetFlags = targetFlags;
4331 touchedWindow.pointerIds = pointerIds;
4332 touchedWindow.channel = window->inputChannel;
4333}
4334
Jeff Browna032cc02011-03-07 16:56:21 -08004335void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
Jeff Brown01ce2e92010-09-26 22:20:12 -07004336 for (size_t i = 0 ; i < windows.size(); ) {
Jeff Browna032cc02011-03-07 16:56:21 -08004337 TouchedWindow& window = windows.editItemAt(i);
4338 if (window.targetFlags & InputTarget::FLAG_DISPATCH_AS_IS) {
4339 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
4340 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
Jeff Brown01ce2e92010-09-26 22:20:12 -07004341 i += 1;
Jeff Browna032cc02011-03-07 16:56:21 -08004342 } else {
4343 windows.removeAt(i);
Jeff Brown01ce2e92010-09-26 22:20:12 -07004344 }
4345 }
4346}
4347
4348const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
4349 for (size_t i = 0; i < windows.size(); i++) {
4350 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
4351 return windows[i].window;
4352 }
4353 }
4354 return NULL;
4355}
4356
4357
Jeff Brown46b9ac02010-04-22 18:58:52 -07004358// --- InputDispatcherThread ---
4359
4360InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
4361 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
4362}
4363
4364InputDispatcherThread::~InputDispatcherThread() {
4365}
4366
4367bool InputDispatcherThread::threadLoop() {
4368 mDispatcher->dispatchOnce();
4369 return true;
4370}
4371
4372} // namespace android