blob: e614e818d32c348a926314878ea528c78b42265f [file] [log] [blame]
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070017#define LOG_TAG "InputDispatcher"
18
19//#define LOG_NDEBUG 0
20
21// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070022#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070023
24// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070025#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070026
27// Log debug messages about batching.
Jeff Brown349703e2010-06-22 01:27:15 -070028#define DEBUG_BATCHING 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070029
30// Log debug messages about the dispatch cycle.
Jeff Brown349703e2010-06-22 01:27:15 -070031#define DEBUG_DISPATCH_CYCLE 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070032
Jeff Brown9c3cda02010-06-15 01:31:58 -070033// Log debug messages about registrations.
Jeff Brown349703e2010-06-22 01:27:15 -070034#define DEBUG_REGISTRATION 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070035
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070036// Log debug messages about performance statistics.
Jeff Brown349703e2010-06-22 01:27:15 -070037#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070038
Jeff Brown7fbdc842010-06-17 20:52:56 -070039// Log debug messages about input event injection.
Jeff Brown349703e2010-06-22 01:27:15 -070040#define DEBUG_INJECTION 0
Jeff Brown7fbdc842010-06-17 20:52:56 -070041
Jeff Brownae9fc032010-08-18 15:51:08 -070042// Log debug messages about input event throttling.
43#define DEBUG_THROTTLING 0
44
Jeff Brownb88102f2010-09-08 11:49:43 -070045// Log debug messages about input focus tracking.
46#define DEBUG_FOCUS 0
47
48// Log debug messages about the app switch latency optimization.
49#define DEBUG_APP_SWITCH 0
50
Jeff Brownb4ff35d2011-01-02 16:37:43 -080051#include "InputDispatcher.h"
52
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070053#include <cutils/log.h>
Jeff Brownb88102f2010-09-08 11:49:43 -070054#include <ui/PowerManager.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070055
56#include <stddef.h>
57#include <unistd.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070058#include <errno.h>
59#include <limits.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070060
Jeff Brownf2f487182010-10-01 17:46:21 -070061#define INDENT " "
62#define INDENT2 " "
63
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070064namespace android {
65
Jeff Brownb88102f2010-09-08 11:49:43 -070066// Default input dispatching timeout if there is no focused application or paused window
67// from which to determine an appropriate dispatching timeout.
68const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
69
70// Amount of time to allow for all pending events to be processed when an app switch
71// key is on the way. This is used to preempt input dispatch and drop input events
72// when an application takes too long to respond and the user has pressed an app switch key.
73const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
74
Jeff Brown928e0542011-01-10 11:17:36 -080075// Amount of time to allow for an event to be dispatched (measured since its eventTime)
76// before considering it stale and dropping it.
77const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
78
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070079
Jeff Brown7fbdc842010-06-17 20:52:56 -070080static inline nsecs_t now() {
81 return systemTime(SYSTEM_TIME_MONOTONIC);
82}
83
Jeff Brownb88102f2010-09-08 11:49:43 -070084static inline const char* toString(bool value) {
85 return value ? "true" : "false";
86}
87
Jeff Brown01ce2e92010-09-26 22:20:12 -070088static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
89 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
90 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
91}
92
93static bool isValidKeyAction(int32_t action) {
94 switch (action) {
95 case AKEY_EVENT_ACTION_DOWN:
96 case AKEY_EVENT_ACTION_UP:
97 return true;
98 default:
99 return false;
100 }
101}
102
103static bool validateKeyEvent(int32_t action) {
104 if (! isValidKeyAction(action)) {
105 LOGE("Key event has invalid action code 0x%x", action);
106 return false;
107 }
108 return true;
109}
110
Jeff Brownb6997262010-10-08 22:31:17 -0700111static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700112 switch (action & AMOTION_EVENT_ACTION_MASK) {
113 case AMOTION_EVENT_ACTION_DOWN:
114 case AMOTION_EVENT_ACTION_UP:
115 case AMOTION_EVENT_ACTION_CANCEL:
116 case AMOTION_EVENT_ACTION_MOVE:
Jeff Brown01ce2e92010-09-26 22:20:12 -0700117 case AMOTION_EVENT_ACTION_OUTSIDE:
Jeff Browncc0c1592011-02-19 05:07:28 -0800118 case AMOTION_EVENT_ACTION_HOVER_MOVE:
Jeff Brown33bbfd22011-02-24 20:55:35 -0800119 case AMOTION_EVENT_ACTION_SCROLL:
Jeff Brown01ce2e92010-09-26 22:20:12 -0700120 return true;
Jeff Brownb6997262010-10-08 22:31:17 -0700121 case AMOTION_EVENT_ACTION_POINTER_DOWN:
122 case AMOTION_EVENT_ACTION_POINTER_UP: {
123 int32_t index = getMotionEventActionPointerIndex(action);
124 return index >= 0 && size_t(index) < pointerCount;
125 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700126 default:
127 return false;
128 }
129}
130
131static bool validateMotionEvent(int32_t action, size_t pointerCount,
132 const int32_t* pointerIds) {
Jeff Brownb6997262010-10-08 22:31:17 -0700133 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700134 LOGE("Motion event has invalid action code 0x%x", action);
135 return false;
136 }
137 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
138 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
139 pointerCount, MAX_POINTERS);
140 return false;
141 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700142 BitSet32 pointerIdBits;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700143 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownc3db8582010-10-20 15:33:38 -0700144 int32_t id = pointerIds[i];
145 if (id < 0 || id > MAX_POINTER_ID) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700146 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
Jeff Brownc3db8582010-10-20 15:33:38 -0700147 id, MAX_POINTER_ID);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700148 return false;
149 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700150 if (pointerIdBits.hasBit(id)) {
151 LOGE("Motion event has duplicate pointer id %d", id);
152 return false;
153 }
154 pointerIdBits.markBit(id);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700155 }
156 return true;
157}
158
Jeff Brownfbf09772011-01-16 14:06:57 -0800159static void dumpRegion(String8& dump, const SkRegion& region) {
160 if (region.isEmpty()) {
161 dump.append("<empty>");
162 return;
163 }
164
165 bool first = true;
166 for (SkRegion::Iterator it(region); !it.done(); it.next()) {
167 if (first) {
168 first = false;
169 } else {
170 dump.append("|");
171 }
172 const SkIRect& rect = it.rect();
173 dump.appendFormat("[%d,%d][%d,%d]", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
174 }
175}
176
Jeff Brownb88102f2010-09-08 11:49:43 -0700177
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700178// --- InputDispatcher ---
179
Jeff Brown9c3cda02010-06-15 01:31:58 -0700180InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Brownb88102f2010-09-08 11:49:43 -0700181 mPolicy(policy),
Jeff Brown928e0542011-01-10 11:17:36 -0800182 mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
183 mNextUnblockedEvent(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700184 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brown01ce2e92010-09-26 22:20:12 -0700185 mFocusedWindow(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700186 mFocusedApplication(NULL),
187 mCurrentInputTargetsValid(false),
188 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700189 mLooper = new Looper(false);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700190
Jeff Brownb88102f2010-09-08 11:49:43 -0700191 mInboundQueue.headSentinel.refCount = -1;
192 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
193 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700194
Jeff Brownb88102f2010-09-08 11:49:43 -0700195 mInboundQueue.tailSentinel.refCount = -1;
196 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
197 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700198
199 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700200
Jeff Brownae9fc032010-08-18 15:51:08 -0700201 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
202 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
203 mThrottleState.lastDeviceId = -1;
204
205#if DEBUG_THROTTLING
206 mThrottleState.originalSampleCount = 0;
207 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
208#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700209}
210
211InputDispatcher::~InputDispatcher() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700212 { // acquire lock
213 AutoMutex _l(mLock);
214
215 resetKeyRepeatLocked();
Jeff Brown54a18252010-09-16 14:07:33 -0700216 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700217 drainInboundQueueLocked();
218 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700219
220 while (mConnectionsByReceiveFd.size() != 0) {
221 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
222 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700223}
224
225void InputDispatcher::dispatchOnce() {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700226 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700227 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700228
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700229 nsecs_t nextWakeupTime = LONG_LONG_MAX;
230 { // acquire lock
231 AutoMutex _l(mLock);
Jeff Brownb88102f2010-09-08 11:49:43 -0700232 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700233
Jeff Brownb88102f2010-09-08 11:49:43 -0700234 if (runCommandsLockedInterruptible()) {
235 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700236 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700237 } // release lock
238
Jeff Brownb88102f2010-09-08 11:49:43 -0700239 // Wait for callback or timeout or wake. (make sure we round up, not down)
240 nsecs_t currentTime = now();
241 int32_t timeoutMillis;
242 if (nextWakeupTime > currentTime) {
243 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
244 timeout = (timeout + 999999LL) / 1000000LL;
245 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
246 } else {
247 timeoutMillis = 0;
248 }
249
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700250 mLooper->pollOnce(timeoutMillis);
Jeff Brownb88102f2010-09-08 11:49:43 -0700251}
252
253void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
254 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
255 nsecs_t currentTime = now();
256
257 // Reset the key repeat timer whenever we disallow key events, even if the next event
258 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
259 // out of sleep.
260 if (keyRepeatTimeout < 0) {
261 resetKeyRepeatLocked();
262 }
263
Jeff Brownb88102f2010-09-08 11:49:43 -0700264 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
265 if (mDispatchFrozen) {
266#if DEBUG_FOCUS
267 LOGD("Dispatch frozen. Waiting some more.");
268#endif
269 return;
270 }
271
272 // Optimize latency of app switches.
273 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
274 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
275 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
276 if (mAppSwitchDueTime < *nextWakeupTime) {
277 *nextWakeupTime = mAppSwitchDueTime;
278 }
279
Jeff Brownb88102f2010-09-08 11:49:43 -0700280 // Ready to start a new event.
281 // If we don't already have a pending event, go grab one.
282 if (! mPendingEvent) {
283 if (mInboundQueue.isEmpty()) {
284 if (isAppSwitchDue) {
285 // The inbound queue is empty so the app switch key we were waiting
286 // for will never arrive. Stop waiting for it.
287 resetPendingAppSwitchLocked(false);
288 isAppSwitchDue = false;
289 }
290
291 // Synthesize a key repeat if appropriate.
292 if (mKeyRepeatState.lastKeyEntry) {
293 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
294 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
295 } else {
296 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
297 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
298 }
299 }
300 }
301 if (! mPendingEvent) {
302 return;
303 }
304 } else {
305 // Inbound queue has at least one entry.
306 EventEntry* entry = mInboundQueue.headSentinel.next;
307
308 // Throttle the entry if it is a move event and there are no
309 // other events behind it in the queue. Due to movement batching, additional
310 // samples may be appended to this event by the time the throttling timeout
311 // expires.
312 // TODO Make this smarter and consider throttling per device independently.
Jeff Brownb6997262010-10-08 22:31:17 -0700313 if (entry->type == EventEntry::TYPE_MOTION
314 && !isAppSwitchDue
315 && mDispatchEnabled
316 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
317 && !entry->isInjected()) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700318 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
319 int32_t deviceId = motionEntry->deviceId;
320 uint32_t source = motionEntry->source;
321 if (! isAppSwitchDue
322 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
Jeff Browncc0c1592011-02-19 05:07:28 -0800323 && (motionEntry->action == AMOTION_EVENT_ACTION_MOVE
324 || motionEntry->action == AMOTION_EVENT_ACTION_HOVER_MOVE)
Jeff Brownb88102f2010-09-08 11:49:43 -0700325 && deviceId == mThrottleState.lastDeviceId
326 && source == mThrottleState.lastSource) {
327 nsecs_t nextTime = mThrottleState.lastEventTime
328 + mThrottleState.minTimeBetweenEvents;
329 if (currentTime < nextTime) {
330 // Throttle it!
331#if DEBUG_THROTTLING
332 LOGD("Throttling - Delaying motion event for "
Jeff Brown90655042010-12-02 13:50:46 -0800333 "device %d, source 0x%08x by up to %0.3fms.",
Jeff Brownb88102f2010-09-08 11:49:43 -0700334 deviceId, source, (nextTime - currentTime) * 0.000001);
335#endif
336 if (nextTime < *nextWakeupTime) {
337 *nextWakeupTime = nextTime;
338 }
339 if (mThrottleState.originalSampleCount == 0) {
340 mThrottleState.originalSampleCount =
341 motionEntry->countSamples();
342 }
343 return;
344 }
345 }
346
347#if DEBUG_THROTTLING
348 if (mThrottleState.originalSampleCount != 0) {
349 uint32_t count = motionEntry->countSamples();
350 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
351 count - mThrottleState.originalSampleCount,
352 mThrottleState.originalSampleCount, count);
353 mThrottleState.originalSampleCount = 0;
354 }
355#endif
356
makarand.karvekarf634ded2011-03-02 15:41:03 -0600357 mThrottleState.lastEventTime = currentTime;
Jeff Brownb88102f2010-09-08 11:49:43 -0700358 mThrottleState.lastDeviceId = deviceId;
359 mThrottleState.lastSource = source;
360 }
361
362 mInboundQueue.dequeue(entry);
363 mPendingEvent = entry;
364 }
Jeff Browne2fe69e2010-10-18 13:21:23 -0700365
366 // Poke user activity for this event.
367 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
368 pokeUserActivityLocked(mPendingEvent);
369 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700370 }
371
372 // Now we have an event to dispatch.
Jeff Brown928e0542011-01-10 11:17:36 -0800373 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Jeff Brownb88102f2010-09-08 11:49:43 -0700374 assert(mPendingEvent != NULL);
Jeff Brown54a18252010-09-16 14:07:33 -0700375 bool done = false;
Jeff Brownb6997262010-10-08 22:31:17 -0700376 DropReason dropReason = DROP_REASON_NOT_DROPPED;
377 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
378 dropReason = DROP_REASON_POLICY;
379 } else if (!mDispatchEnabled) {
380 dropReason = DROP_REASON_DISABLED;
381 }
Jeff Brown928e0542011-01-10 11:17:36 -0800382
383 if (mNextUnblockedEvent == mPendingEvent) {
384 mNextUnblockedEvent = NULL;
385 }
386
Jeff Brownb88102f2010-09-08 11:49:43 -0700387 switch (mPendingEvent->type) {
388 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
389 ConfigurationChangedEntry* typedEntry =
390 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700391 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brownb6997262010-10-08 22:31:17 -0700392 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Brownb88102f2010-09-08 11:49:43 -0700393 break;
394 }
395
396 case EventEntry::TYPE_KEY: {
397 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700398 if (isAppSwitchDue) {
399 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700400 resetPendingAppSwitchLocked(true);
Jeff Brownb6997262010-10-08 22:31:17 -0700401 isAppSwitchDue = false;
402 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
403 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700404 }
405 }
Jeff Brown928e0542011-01-10 11:17:36 -0800406 if (dropReason == DROP_REASON_NOT_DROPPED
407 && isStaleEventLocked(currentTime, typedEntry)) {
408 dropReason = DROP_REASON_STALE;
409 }
410 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
411 dropReason = DROP_REASON_BLOCKED;
412 }
Jeff Brownb6997262010-10-08 22:31:17 -0700413 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Browne20c9e02010-10-11 14:20:19 -0700414 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700415 break;
416 }
417
418 case EventEntry::TYPE_MOTION: {
419 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700420 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
421 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700422 }
Jeff Brown928e0542011-01-10 11:17:36 -0800423 if (dropReason == DROP_REASON_NOT_DROPPED
424 && isStaleEventLocked(currentTime, typedEntry)) {
425 dropReason = DROP_REASON_STALE;
426 }
427 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
428 dropReason = DROP_REASON_BLOCKED;
429 }
Jeff Brownb6997262010-10-08 22:31:17 -0700430 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Browne20c9e02010-10-11 14:20:19 -0700431 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700432 break;
433 }
434
435 default:
436 assert(false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700437 break;
438 }
439
Jeff Brown54a18252010-09-16 14:07:33 -0700440 if (done) {
Jeff Brownb6997262010-10-08 22:31:17 -0700441 if (dropReason != DROP_REASON_NOT_DROPPED) {
442 dropInboundEventLocked(mPendingEvent, dropReason);
443 }
444
Jeff Brown54a18252010-09-16 14:07:33 -0700445 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700446 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
447 }
448}
449
450bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
451 bool needWake = mInboundQueue.isEmpty();
452 mInboundQueue.enqueueAtTail(entry);
453
454 switch (entry->type) {
Jeff Brownb6997262010-10-08 22:31:17 -0700455 case EventEntry::TYPE_KEY: {
Jeff Brown928e0542011-01-10 11:17:36 -0800456 // Optimize app switch latency.
457 // If the application takes too long to catch up then we drop all events preceding
458 // the app switch key.
Jeff Brownb6997262010-10-08 22:31:17 -0700459 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
460 if (isAppSwitchKeyEventLocked(keyEntry)) {
461 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
462 mAppSwitchSawKeyDown = true;
463 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
464 if (mAppSwitchSawKeyDown) {
465#if DEBUG_APP_SWITCH
466 LOGD("App switch is pending!");
467#endif
468 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
469 mAppSwitchSawKeyDown = false;
470 needWake = true;
471 }
472 }
473 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700474 break;
475 }
Jeff Brown928e0542011-01-10 11:17:36 -0800476
477 case EventEntry::TYPE_MOTION: {
478 // Optimize case where the current application is unresponsive and the user
479 // decides to touch a window in a different application.
480 // If the application takes too long to catch up then we drop all events preceding
481 // the touch into the other window.
482 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
Jeff Brown33bbfd22011-02-24 20:55:35 -0800483 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
Jeff Brown928e0542011-01-10 11:17:36 -0800484 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
485 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
486 && mInputTargetWaitApplication != NULL) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800487 int32_t x = int32_t(motionEntry->firstSample.pointerCoords[0].
Jeff Brownebbd5d12011-02-17 13:01:34 -0800488 getAxisValue(AMOTION_EVENT_AXIS_X));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800489 int32_t y = int32_t(motionEntry->firstSample.pointerCoords[0].
Jeff Brownebbd5d12011-02-17 13:01:34 -0800490 getAxisValue(AMOTION_EVENT_AXIS_Y));
Jeff Brown928e0542011-01-10 11:17:36 -0800491 const InputWindow* touchedWindow = findTouchedWindowAtLocked(x, y);
492 if (touchedWindow
493 && touchedWindow->inputWindowHandle != NULL
494 && touchedWindow->inputWindowHandle->getInputApplicationHandle()
495 != mInputTargetWaitApplication) {
496 // User touched a different application than the one we are waiting on.
497 // Flag the event, and start pruning the input queue.
498 mNextUnblockedEvent = motionEntry;
499 needWake = true;
500 }
501 }
502 break;
503 }
Jeff Brownb6997262010-10-08 22:31:17 -0700504 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700505
506 return needWake;
507}
508
Jeff Brown928e0542011-01-10 11:17:36 -0800509const InputWindow* InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
510 // Traverse windows from front to back to find touched window.
511 size_t numWindows = mWindows.size();
512 for (size_t i = 0; i < numWindows; i++) {
513 const InputWindow* window = & mWindows.editItemAt(i);
514 int32_t flags = window->layoutParamsFlags;
515
516 if (window->visible) {
517 if (!(flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
518 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
519 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
Jeff Brownfbf09772011-01-16 14:06:57 -0800520 if (isTouchModal || window->touchableRegionContainsPoint(x, y)) {
Jeff Brown928e0542011-01-10 11:17:36 -0800521 // Found window.
522 return window;
523 }
524 }
525 }
526
527 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
528 // Error window is on top but not visible, so touch is dropped.
529 return NULL;
530 }
531 }
532 return NULL;
533}
534
Jeff Brownb6997262010-10-08 22:31:17 -0700535void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
536 const char* reason;
537 switch (dropReason) {
538 case DROP_REASON_POLICY:
Jeff Browne20c9e02010-10-11 14:20:19 -0700539#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown3122e442010-10-11 23:32:49 -0700540 LOGD("Dropped event because policy consumed it.");
Jeff Browne20c9e02010-10-11 14:20:19 -0700541#endif
Jeff Brown3122e442010-10-11 23:32:49 -0700542 reason = "inbound event was dropped because the policy consumed it";
Jeff Brownb6997262010-10-08 22:31:17 -0700543 break;
544 case DROP_REASON_DISABLED:
545 LOGI("Dropped event because input dispatch is disabled.");
546 reason = "inbound event was dropped because input dispatch is disabled";
547 break;
548 case DROP_REASON_APP_SWITCH:
549 LOGI("Dropped event because of pending overdue app switch.");
550 reason = "inbound event was dropped because of pending overdue app switch";
551 break;
Jeff Brown928e0542011-01-10 11:17:36 -0800552 case DROP_REASON_BLOCKED:
553 LOGI("Dropped event because the current application is not responding and the user "
554 "has started interating with a different application.");
555 reason = "inbound event was dropped because the current application is not responding "
556 "and the user has started interating with a different application";
557 break;
558 case DROP_REASON_STALE:
559 LOGI("Dropped event because it is stale.");
560 reason = "inbound event was dropped because it is stale";
561 break;
Jeff Brownb6997262010-10-08 22:31:17 -0700562 default:
563 assert(false);
564 return;
565 }
566
567 switch (entry->type) {
568 case EventEntry::TYPE_KEY:
569 synthesizeCancelationEventsForAllConnectionsLocked(
570 InputState::CANCEL_NON_POINTER_EVENTS, reason);
571 break;
572 case EventEntry::TYPE_MOTION: {
573 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
574 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
575 synthesizeCancelationEventsForAllConnectionsLocked(
576 InputState::CANCEL_POINTER_EVENTS, reason);
577 } else {
578 synthesizeCancelationEventsForAllConnectionsLocked(
579 InputState::CANCEL_NON_POINTER_EVENTS, reason);
580 }
581 break;
582 }
583 }
584}
585
586bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700587 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
588}
589
Jeff Brownb6997262010-10-08 22:31:17 -0700590bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
591 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
592 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Browne20c9e02010-10-11 14:20:19 -0700593 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brownb6997262010-10-08 22:31:17 -0700594 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
595}
596
Jeff Brownb88102f2010-09-08 11:49:43 -0700597bool InputDispatcher::isAppSwitchPendingLocked() {
598 return mAppSwitchDueTime != LONG_LONG_MAX;
599}
600
Jeff Brownb88102f2010-09-08 11:49:43 -0700601void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
602 mAppSwitchDueTime = LONG_LONG_MAX;
603
604#if DEBUG_APP_SWITCH
605 if (handled) {
606 LOGD("App switch has arrived.");
607 } else {
608 LOGD("App switch was abandoned.");
609 }
610#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700611}
612
Jeff Brown928e0542011-01-10 11:17:36 -0800613bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
614 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
615}
616
Jeff Brown9c3cda02010-06-15 01:31:58 -0700617bool InputDispatcher::runCommandsLockedInterruptible() {
618 if (mCommandQueue.isEmpty()) {
619 return false;
620 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700621
Jeff Brown9c3cda02010-06-15 01:31:58 -0700622 do {
623 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
624
625 Command command = commandEntry->command;
626 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
627
Jeff Brown7fbdc842010-06-17 20:52:56 -0700628 commandEntry->connection.clear();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700629 mAllocator.releaseCommandEntry(commandEntry);
630 } while (! mCommandQueue.isEmpty());
631 return true;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700632}
633
Jeff Brown9c3cda02010-06-15 01:31:58 -0700634InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
635 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
636 mCommandQueue.enqueueAtTail(commandEntry);
637 return commandEntry;
638}
639
Jeff Brownb88102f2010-09-08 11:49:43 -0700640void InputDispatcher::drainInboundQueueLocked() {
641 while (! mInboundQueue.isEmpty()) {
642 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700643 releaseInboundEventLocked(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700644 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700645}
646
Jeff Brown54a18252010-09-16 14:07:33 -0700647void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700648 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700649 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700650 mPendingEvent = NULL;
651 }
652}
653
Jeff Brown54a18252010-09-16 14:07:33 -0700654void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700655 InjectionState* injectionState = entry->injectionState;
656 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700657#if DEBUG_DISPATCH_CYCLE
Jeff Brown01ce2e92010-09-26 22:20:12 -0700658 LOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700659#endif
660 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
661 }
662 mAllocator.releaseEventEntry(entry);
663}
664
Jeff Brownb88102f2010-09-08 11:49:43 -0700665void InputDispatcher::resetKeyRepeatLocked() {
666 if (mKeyRepeatState.lastKeyEntry) {
667 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
668 mKeyRepeatState.lastKeyEntry = NULL;
669 }
670}
671
672InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brownb21fb102010-09-07 10:44:57 -0700673 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown349703e2010-06-22 01:27:15 -0700674 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
675
Jeff Brown349703e2010-06-22 01:27:15 -0700676 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Browne20c9e02010-10-11 14:20:19 -0700677 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
678 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700679 if (entry->refCount == 1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700680 mAllocator.recycleKeyEntry(entry);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700681 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700682 entry->policyFlags = policyFlags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700683 entry->repeatCount += 1;
684 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700685 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700686 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700687 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700688 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700689
690 mKeyRepeatState.lastKeyEntry = newEntry;
691 mAllocator.releaseKeyEntry(entry);
692
693 entry = newEntry;
694 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700695 entry->syntheticRepeat = true;
696
697 // Increment reference count since we keep a reference to the event in
698 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
699 entry->refCount += 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700700
Jeff Brownb21fb102010-09-07 10:44:57 -0700701 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700702 return entry;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700703}
704
Jeff Brownb88102f2010-09-08 11:49:43 -0700705bool InputDispatcher::dispatchConfigurationChangedLocked(
706 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700707#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownb88102f2010-09-08 11:49:43 -0700708 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
709#endif
710
711 // Reset key repeating in case a keyboard device was added or removed or something.
712 resetKeyRepeatLocked();
713
714 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
715 CommandEntry* commandEntry = postCommandLocked(
716 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
717 commandEntry->eventTime = entry->eventTime;
718 return true;
719}
720
721bool InputDispatcher::dispatchKeyLocked(
722 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Browne20c9e02010-10-11 14:20:19 -0700723 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700724 // Preprocessing.
725 if (! entry->dispatchInProgress) {
726 if (entry->repeatCount == 0
727 && entry->action == AKEY_EVENT_ACTION_DOWN
728 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
729 && !entry->isInjected()) {
730 if (mKeyRepeatState.lastKeyEntry
731 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
732 // We have seen two identical key downs in a row which indicates that the device
733 // driver is automatically generating key repeats itself. We take note of the
734 // repeat here, but we disable our own next key repeat timer since it is clear that
735 // we will not need to synthesize key repeats ourselves.
736 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
737 resetKeyRepeatLocked();
738 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
739 } else {
740 // Not a repeat. Save key down state in case we do see a repeat later.
741 resetKeyRepeatLocked();
742 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
743 }
744 mKeyRepeatState.lastKeyEntry = entry;
745 entry->refCount += 1;
746 } else if (! entry->syntheticRepeat) {
747 resetKeyRepeatLocked();
748 }
749
Jeff Browne2e01262011-03-02 20:34:30 -0800750 if (entry->repeatCount == 1) {
751 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
752 } else {
753 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
754 }
755
Jeff Browne46a0a42010-11-02 17:58:22 -0700756 entry->dispatchInProgress = true;
757 resetTargetsLocked();
758
759 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
760 }
761
Jeff Brown54a18252010-09-16 14:07:33 -0700762 // Give the policy a chance to intercept the key.
763 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700764 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brown54a18252010-09-16 14:07:33 -0700765 CommandEntry* commandEntry = postCommandLocked(
766 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Browne20c9e02010-10-11 14:20:19 -0700767 if (mFocusedWindow) {
Jeff Brown928e0542011-01-10 11:17:36 -0800768 commandEntry->inputWindowHandle = mFocusedWindow->inputWindowHandle;
Jeff Brown54a18252010-09-16 14:07:33 -0700769 }
770 commandEntry->keyEntry = entry;
771 entry->refCount += 1;
772 return false; // wait for the command to run
773 } else {
774 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
775 }
776 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700777 if (*dropReason == DROP_REASON_NOT_DROPPED) {
778 *dropReason = DROP_REASON_POLICY;
779 }
Jeff Brown54a18252010-09-16 14:07:33 -0700780 }
781
782 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700783 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700784 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700785 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
786 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700787 return true;
788 }
789
Jeff Brownb88102f2010-09-08 11:49:43 -0700790 // Identify targets.
791 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700792 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
793 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700794 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
795 return false;
796 }
797
798 setInjectionResultLocked(entry, injectionResult);
799 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
800 return true;
801 }
802
803 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700804 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700805 }
806
807 // Dispatch the key.
808 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700809 return true;
810}
811
812void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
813#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800814 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brownb88102f2010-09-08 11:49:43 -0700815 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
Jeff Browne46a0a42010-11-02 17:58:22 -0700816 "repeatCount=%d, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700817 prefix,
818 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
819 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Jeff Browne46a0a42010-11-02 17:58:22 -0700820 entry->repeatCount, entry->downTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700821#endif
822}
823
824bool InputDispatcher::dispatchMotionLocked(
Jeff Browne20c9e02010-10-11 14:20:19 -0700825 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700826 // Preprocessing.
827 if (! entry->dispatchInProgress) {
828 entry->dispatchInProgress = true;
829 resetTargetsLocked();
830
831 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
832 }
833
Jeff Brown54a18252010-09-16 14:07:33 -0700834 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700835 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700836 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700837 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
838 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700839 return true;
840 }
841
Jeff Brownb88102f2010-09-08 11:49:43 -0700842 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
843
844 // Identify targets.
Jeff Browncc0c1592011-02-19 05:07:28 -0800845 bool conflictingPointerActions = false;
Jeff Brownb88102f2010-09-08 11:49:43 -0700846 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700847 int32_t injectionResult;
848 if (isPointerEvent) {
849 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700850 injectionResult = findTouchedWindowTargetsLocked(currentTime,
Jeff Browncc0c1592011-02-19 05:07:28 -0800851 entry, nextWakeupTime, &conflictingPointerActions);
Jeff Brownb88102f2010-09-08 11:49:43 -0700852 } else {
853 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700854 injectionResult = findFocusedWindowTargetsLocked(currentTime,
855 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700856 }
857 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
858 return false;
859 }
860
861 setInjectionResultLocked(entry, injectionResult);
862 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
863 return true;
864 }
865
866 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700867 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700868 }
869
870 // Dispatch the motion.
Jeff Browncc0c1592011-02-19 05:07:28 -0800871 if (conflictingPointerActions) {
872 synthesizeCancelationEventsForAllConnectionsLocked(
873 InputState::CANCEL_POINTER_EVENTS, "Conflicting pointer actions.");
874 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700875 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700876 return true;
877}
878
879
880void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
881#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800882 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700883 "action=0x%x, flags=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700884 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700885 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700886 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
887 entry->action, entry->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700888 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
889 entry->downTime);
890
891 // Print the most recent sample that we have available, this may change due to batching.
892 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700893 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700894 for (; sample->next != NULL; sample = sample->next) {
895 sampleCount += 1;
896 }
897 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -0700898 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700899 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700900 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700901 i, entry->pointerIds[i],
Jeff Brownebbd5d12011-02-17 13:01:34 -0800902 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
903 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
904 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
905 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
906 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
907 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
908 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
909 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
910 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700911 }
912
913 // Keep in mind that due to batching, it is possible for the number of samples actually
914 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700915 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700916 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
917 }
918#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700919}
920
921void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
922 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
923#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -0700924 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700925 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700926 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700927#endif
928
Jeff Brown9c3cda02010-06-15 01:31:58 -0700929 assert(eventEntry->dispatchInProgress); // should already have been set to true
930
Jeff Browne2fe69e2010-10-18 13:21:23 -0700931 pokeUserActivityLocked(eventEntry);
932
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700933 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
934 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
935
Jeff Brown519e0242010-09-15 15:18:56 -0700936 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700937 if (connectionIndex >= 0) {
938 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700939 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700940 resumeWithAppendedMotionSample);
941 } else {
Jeff Brownb6997262010-10-08 22:31:17 -0700942#if DEBUG_FOCUS
943 LOGD("Dropping event delivery to target with channel '%s' because it "
944 "is no longer registered with the input dispatcher.",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700945 inputTarget.inputChannel->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -0700946#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700947 }
948 }
949}
950
Jeff Brown54a18252010-09-16 14:07:33 -0700951void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700952 mCurrentInputTargetsValid = false;
953 mCurrentInputTargets.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700954 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Jeff Brown928e0542011-01-10 11:17:36 -0800955 mInputTargetWaitApplication.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700956}
957
Jeff Brown01ce2e92010-09-26 22:20:12 -0700958void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700959 mCurrentInputTargetsValid = true;
960}
961
962int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
963 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
964 nsecs_t* nextWakeupTime) {
965 if (application == NULL && window == NULL) {
966 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
967#if DEBUG_FOCUS
968 LOGD("Waiting for system to become ready for input.");
969#endif
970 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
971 mInputTargetWaitStartTime = currentTime;
972 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
973 mInputTargetWaitTimeoutExpired = false;
Jeff Brown928e0542011-01-10 11:17:36 -0800974 mInputTargetWaitApplication.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700975 }
976 } else {
977 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
978#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700979 LOGD("Waiting for application to become ready for input: %s",
980 getApplicationWindowLabelLocked(application, window).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700981#endif
982 nsecs_t timeout = window ? window->dispatchingTimeout :
983 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
984
985 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
986 mInputTargetWaitStartTime = currentTime;
987 mInputTargetWaitTimeoutTime = currentTime + timeout;
988 mInputTargetWaitTimeoutExpired = false;
Jeff Brown928e0542011-01-10 11:17:36 -0800989 mInputTargetWaitApplication.clear();
990
991 if (window && window->inputWindowHandle != NULL) {
992 mInputTargetWaitApplication =
993 window->inputWindowHandle->getInputApplicationHandle();
994 }
995 if (mInputTargetWaitApplication == NULL && application) {
996 mInputTargetWaitApplication = application->inputApplicationHandle;
997 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700998 }
999 }
1000
1001 if (mInputTargetWaitTimeoutExpired) {
1002 return INPUT_EVENT_INJECTION_TIMED_OUT;
1003 }
1004
1005 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown519e0242010-09-15 15:18:56 -07001006 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001007
1008 // Force poll loop to wake up immediately on next iteration once we get the
1009 // ANR response back from the policy.
1010 *nextWakeupTime = LONG_LONG_MIN;
1011 return INPUT_EVENT_INJECTION_PENDING;
1012 } else {
1013 // Force poll loop to wake up when timeout is due.
1014 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1015 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1016 }
1017 return INPUT_EVENT_INJECTION_PENDING;
1018 }
1019}
1020
Jeff Brown519e0242010-09-15 15:18:56 -07001021void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1022 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001023 if (newTimeout > 0) {
1024 // Extend the timeout.
1025 mInputTargetWaitTimeoutTime = now() + newTimeout;
1026 } else {
1027 // Give up.
1028 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -07001029
Jeff Brown01ce2e92010-09-26 22:20:12 -07001030 // Release the touch targets.
1031 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07001032
Jeff Brown519e0242010-09-15 15:18:56 -07001033 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -07001034 if (inputChannel.get()) {
1035 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1036 if (connectionIndex >= 0) {
1037 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown00045a72010-12-09 18:10:30 -08001038 if (connection->status == Connection::STATUS_NORMAL) {
1039 synthesizeCancelationEventsForConnectionLocked(
1040 connection, InputState::CANCEL_ALL_EVENTS,
1041 "application not responding");
1042 }
Jeff Browndc3e0052010-09-16 11:02:16 -07001043 }
Jeff Brown519e0242010-09-15 15:18:56 -07001044 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001045 }
1046}
1047
Jeff Brown519e0242010-09-15 15:18:56 -07001048nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -07001049 nsecs_t currentTime) {
1050 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1051 return currentTime - mInputTargetWaitStartTime;
1052 }
1053 return 0;
1054}
1055
1056void InputDispatcher::resetANRTimeoutsLocked() {
1057#if DEBUG_FOCUS
1058 LOGD("Resetting ANR timeouts.");
1059#endif
1060
Jeff Brownb88102f2010-09-08 11:49:43 -07001061 // Reset input target wait timeout.
1062 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
1063}
1064
Jeff Brown01ce2e92010-09-26 22:20:12 -07001065int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
1066 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001067 mCurrentInputTargets.clear();
1068
1069 int32_t injectionResult;
1070
1071 // If there is no currently focused window and no focused application
1072 // then drop the event.
1073 if (! mFocusedWindow) {
1074 if (mFocusedApplication) {
1075#if DEBUG_FOCUS
1076 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001077 "focused application that may eventually add a window: %s.",
1078 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001079#endif
1080 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1081 mFocusedApplication, NULL, nextWakeupTime);
1082 goto Unresponsive;
1083 }
1084
1085 LOGI("Dropping event because there is no focused window or focused application.");
1086 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1087 goto Failed;
1088 }
1089
1090 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001091 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001092 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1093 goto Failed;
1094 }
1095
1096 // If the currently focused window is paused then keep waiting.
1097 if (mFocusedWindow->paused) {
1098#if DEBUG_FOCUS
1099 LOGD("Waiting because focused window is paused.");
1100#endif
1101 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1102 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1103 goto Unresponsive;
1104 }
1105
Jeff Brown519e0242010-09-15 15:18:56 -07001106 // If the currently focused window is still working on previous events then keep waiting.
1107 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
1108#if DEBUG_FOCUS
1109 LOGD("Waiting because focused window still processing previous input.");
1110#endif
1111 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1112 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1113 goto Unresponsive;
1114 }
1115
Jeff Brownb88102f2010-09-08 11:49:43 -07001116 // Success! Output targets.
1117 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001118 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001119
1120 // Done.
1121Failed:
1122Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001123 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1124 updateDispatchStatisticsLocked(currentTime, entry,
1125 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001126#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -07001127 LOGD("findFocusedWindow finished: injectionResult=%d, "
1128 "timeSpendWaitingForApplication=%0.1fms",
1129 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001130#endif
1131 return injectionResult;
1132}
1133
Jeff Brown01ce2e92010-09-26 22:20:12 -07001134int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Jeff Browncc0c1592011-02-19 05:07:28 -08001135 const MotionEntry* entry, nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001136 enum InjectionPermission {
1137 INJECTION_PERMISSION_UNKNOWN,
1138 INJECTION_PERMISSION_GRANTED,
1139 INJECTION_PERMISSION_DENIED
1140 };
1141
Jeff Brownb88102f2010-09-08 11:49:43 -07001142 mCurrentInputTargets.clear();
1143
1144 nsecs_t startTime = now();
1145
1146 // For security reasons, we defer updating the touch state until we are sure that
1147 // event injection will be allowed.
1148 //
1149 // FIXME In the original code, screenWasOff could never be set to true.
1150 // The reason is that the POLICY_FLAG_WOKE_HERE
1151 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1152 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1153 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1154 // events upon which no preprocessing took place. So policyFlags was always 0.
1155 // In the new native input dispatcher we're a bit more careful about event
1156 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1157 // Unfortunately we obtain undesirable behavior.
1158 //
1159 // Here's what happens:
1160 //
1161 // When the device dims in anticipation of going to sleep, touches
1162 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1163 // the device to brighten and reset the user activity timer.
1164 // Touches on other windows (such as the launcher window)
1165 // are dropped. Then after a moment, the device goes to sleep. Oops.
1166 //
1167 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1168 // instead of POLICY_FLAG_WOKE_HERE...
1169 //
1170 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1171
1172 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001173 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001174
1175 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001176 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1177 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Jeff Browncc0c1592011-02-19 05:07:28 -08001178
1179 bool isSplit = mTouchState.split;
1180 bool wrongDevice = mTouchState.down
1181 && (mTouchState.deviceId != entry->deviceId
1182 || mTouchState.source != entry->source);
1183 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
Jeff Brown33bbfd22011-02-24 20:55:35 -08001184 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1185 || maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
Jeff Browncc0c1592011-02-19 05:07:28 -08001186 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
1187 if (wrongDevice && !down) {
1188 mTempTouchState.copyFrom(mTouchState);
1189 } else {
1190 mTempTouchState.reset();
1191 mTempTouchState.down = down;
1192 mTempTouchState.deviceId = entry->deviceId;
1193 mTempTouchState.source = entry->source;
1194 isSplit = false;
1195 wrongDevice = false;
1196 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001197 } else {
1198 mTempTouchState.copyFrom(mTouchState);
Jeff Browncc0c1592011-02-19 05:07:28 -08001199 }
1200 if (wrongDevice) {
Jeff Brown95712852011-01-04 19:41:59 -08001201#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Browncc0c1592011-02-19 05:07:28 -08001202 LOGD("Dropping event because a pointer for a different device is already down.");
Jeff Brown95712852011-01-04 19:41:59 -08001203#endif
Jeff Browncc0c1592011-02-19 05:07:28 -08001204 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1205 goto Failed;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001206 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001207
Jeff Brown01ce2e92010-09-26 22:20:12 -07001208 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
Jeff Browncc0c1592011-02-19 05:07:28 -08001209 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)
Jeff Brown33bbfd22011-02-24 20:55:35 -08001210 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1211 || maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1212 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001213
Jeff Brown01ce2e92010-09-26 22:20:12 -07001214 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Jeff Brown91c69ab2011-02-14 17:03:18 -08001215 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].
Jeff Brownebbd5d12011-02-17 13:01:34 -08001216 getAxisValue(AMOTION_EVENT_AXIS_X));
Jeff Brown91c69ab2011-02-14 17:03:18 -08001217 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].
Jeff Brownebbd5d12011-02-17 13:01:34 -08001218 getAxisValue(AMOTION_EVENT_AXIS_Y));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001219 const InputWindow* newTouchedWindow = NULL;
1220 const InputWindow* topErrorWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07001221
1222 // Traverse windows from front to back to find touched window and outside targets.
1223 size_t numWindows = mWindows.size();
1224 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001225 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001226 int32_t flags = window->layoutParamsFlags;
1227
1228 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1229 if (! topErrorWindow) {
1230 topErrorWindow = window;
1231 }
1232 }
1233
1234 if (window->visible) {
1235 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1236 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1237 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
Jeff Brownfbf09772011-01-16 14:06:57 -08001238 if (isTouchModal || window->touchableRegionContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001239 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1240 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001241 }
1242 break; // found touched window, exit window loop
1243 }
1244 }
1245
Jeff Brown01ce2e92010-09-26 22:20:12 -07001246 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1247 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001248 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1249 if (isWindowObscuredAtPointLocked(window, x, y)) {
1250 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1251 }
1252
1253 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001254 }
1255 }
1256 }
1257
1258 // If there is an error window but it is not taking focus (typically because
1259 // it is invisible) then wait for it. Any other focused window may in
1260 // fact be in ANR state.
1261 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1262#if DEBUG_FOCUS
1263 LOGD("Waiting because system error window is pending.");
1264#endif
1265 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1266 NULL, NULL, nextWakeupTime);
1267 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1268 goto Unresponsive;
1269 }
1270
Jeff Brown01ce2e92010-09-26 22:20:12 -07001271 // Figure out whether splitting will be allowed for this window.
Jeff Brown46e75292010-11-10 16:53:45 -08001272 if (newTouchedWindow && newTouchedWindow->supportsSplitTouch()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001273 // New window supports splitting.
1274 isSplit = true;
1275 } else if (isSplit) {
1276 // New window does not support splitting but we have already split events.
1277 // Assign the pointer to the first foreground window we find.
1278 // (May be NULL which is why we put this code block before the next check.)
1279 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1280 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001281
Jeff Brownb88102f2010-09-08 11:49:43 -07001282 // If we did not find a touched window then fail.
1283 if (! newTouchedWindow) {
1284 if (mFocusedApplication) {
1285#if DEBUG_FOCUS
1286 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001287 "focused application that may eventually add a new window: %s.",
1288 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001289#endif
1290 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1291 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001292 goto Unresponsive;
1293 }
1294
1295 LOGI("Dropping event because there is no touched window or focused application.");
1296 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001297 goto Failed;
1298 }
1299
Jeff Brown19dfc832010-10-05 12:26:23 -07001300 // Set target flags.
1301 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1302 if (isSplit) {
1303 targetFlags |= InputTarget::FLAG_SPLIT;
1304 }
1305 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1306 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1307 }
1308
Jeff Brown01ce2e92010-09-26 22:20:12 -07001309 // Update the temporary touch state.
1310 BitSet32 pointerIds;
1311 if (isSplit) {
1312 uint32_t pointerId = entry->pointerIds[pointerIndex];
1313 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001314 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001315 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001316 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001317 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001318
1319 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001320 if (! mTempTouchState.down) {
Jeff Brown76860e32010-10-25 17:37:46 -07001321#if DEBUG_INPUT_DISPATCHER_POLICY
1322 LOGD("Dropping event because the pointer is not down or we previously "
1323 "dropped the pointer down event.");
1324#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001325 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001326 goto Failed;
1327 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001328 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001329
Jeff Brown01ce2e92010-09-26 22:20:12 -07001330 // Check permission to inject into all touched foreground windows and ensure there
1331 // is at least one touched foreground window.
1332 {
1333 bool haveForegroundWindow = false;
1334 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1335 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1336 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1337 haveForegroundWindow = true;
1338 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1339 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1340 injectionPermission = INJECTION_PERMISSION_DENIED;
1341 goto Failed;
1342 }
1343 }
1344 }
1345 if (! haveForegroundWindow) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001346#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown01ce2e92010-09-26 22:20:12 -07001347 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001348#endif
1349 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001350 goto Failed;
1351 }
1352
Jeff Brown01ce2e92010-09-26 22:20:12 -07001353 // Permission granted to injection into all touched foreground windows.
1354 injectionPermission = INJECTION_PERMISSION_GRANTED;
1355 }
Jeff Brown519e0242010-09-15 15:18:56 -07001356
Jeff Brown01ce2e92010-09-26 22:20:12 -07001357 // Ensure all touched foreground windows are ready for new input.
1358 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1359 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1360 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1361 // If the touched window is paused then keep waiting.
1362 if (touchedWindow.window->paused) {
1363#if DEBUG_INPUT_DISPATCHER_POLICY
1364 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001365#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001366 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1367 NULL, touchedWindow.window, nextWakeupTime);
1368 goto Unresponsive;
1369 }
1370
1371 // If the touched window is still working on previous events then keep waiting.
1372 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1373#if DEBUG_FOCUS
1374 LOGD("Waiting because touched window still processing previous input.");
1375#endif
1376 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1377 NULL, touchedWindow.window, nextWakeupTime);
1378 goto Unresponsive;
1379 }
1380 }
1381 }
1382
1383 // If this is the first pointer going down and the touched window has a wallpaper
1384 // then also add the touched wallpaper windows so they are locked in for the duration
1385 // of the touch gesture.
Jeff Brown33bbfd22011-02-24 20:55:35 -08001386 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1387 // engine only supports touch events. We would need to add a mechanism similar
1388 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1389 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001390 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1391 if (foregroundWindow->hasWallpaper) {
1392 for (size_t i = 0; i < mWindows.size(); i++) {
1393 const InputWindow* window = & mWindows[i];
1394 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001395 mTempTouchState.addOrUpdateWindow(window,
1396 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001397 }
1398 }
1399 }
1400 }
1401
Jeff Brownb88102f2010-09-08 11:49:43 -07001402 // Success! Output targets.
1403 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001404
Jeff Brown01ce2e92010-09-26 22:20:12 -07001405 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1406 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1407 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1408 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001409 }
1410
Jeff Brown01ce2e92010-09-26 22:20:12 -07001411 // Drop the outside touch window since we will not care about them in the next iteration.
1412 mTempTouchState.removeOutsideTouchWindows();
1413
Jeff Brownb88102f2010-09-08 11:49:43 -07001414Failed:
1415 // Check injection permission once and for all.
1416 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001417 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001418 injectionPermission = INJECTION_PERMISSION_GRANTED;
1419 } else {
1420 injectionPermission = INJECTION_PERMISSION_DENIED;
1421 }
1422 }
1423
1424 // Update final pieces of touch state if the injector had permission.
1425 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown95712852011-01-04 19:41:59 -08001426 if (!wrongDevice) {
1427 if (maskedAction == AMOTION_EVENT_ACTION_UP
Jeff Browncc0c1592011-02-19 05:07:28 -08001428 || maskedAction == AMOTION_EVENT_ACTION_CANCEL
1429 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brown95712852011-01-04 19:41:59 -08001430 // All pointers up or canceled.
Jeff Brown33bbfd22011-02-24 20:55:35 -08001431 mTouchState.reset();
Jeff Brown95712852011-01-04 19:41:59 -08001432 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1433 // First pointer went down.
1434 if (mTouchState.down) {
Jeff Browncc0c1592011-02-19 05:07:28 -08001435 *outConflictingPointerActions = true;
Jeff Brownb6997262010-10-08 22:31:17 -07001436#if DEBUG_FOCUS
Jeff Brown95712852011-01-04 19:41:59 -08001437 LOGD("Pointer down received while already down.");
Jeff Brownb6997262010-10-08 22:31:17 -07001438#endif
Jeff Brown95712852011-01-04 19:41:59 -08001439 }
Jeff Brown33bbfd22011-02-24 20:55:35 -08001440 mTouchState.copyFrom(mTempTouchState);
Jeff Brown95712852011-01-04 19:41:59 -08001441 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1442 // One pointer went up.
1443 if (isSplit) {
1444 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1445 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001446
Jeff Brown95712852011-01-04 19:41:59 -08001447 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1448 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1449 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1450 touchedWindow.pointerIds.clearBit(pointerId);
1451 if (touchedWindow.pointerIds.isEmpty()) {
1452 mTempTouchState.windows.removeAt(i);
1453 continue;
1454 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001455 }
Jeff Brown95712852011-01-04 19:41:59 -08001456 i += 1;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001457 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001458 }
Jeff Brown33bbfd22011-02-24 20:55:35 -08001459 mTouchState.copyFrom(mTempTouchState);
1460 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1461 // Discard temporary touch state since it was only valid for this action.
1462 } else {
1463 // Save changes to touch state as-is for all other actions.
1464 mTouchState.copyFrom(mTempTouchState);
Jeff Brownb88102f2010-09-08 11:49:43 -07001465 }
Jeff Brown95712852011-01-04 19:41:59 -08001466 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001467 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001468#if DEBUG_FOCUS
1469 LOGD("Not updating touch focus because injection was denied.");
1470#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001471 }
1472
1473Unresponsive:
Jeff Brown120a4592010-10-27 18:43:51 -07001474 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1475 mTempTouchState.reset();
1476
Jeff Brown519e0242010-09-15 15:18:56 -07001477 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1478 updateDispatchStatisticsLocked(currentTime, entry,
1479 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001480#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001481 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1482 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001483 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001484#endif
1485 return injectionResult;
1486}
1487
Jeff Brown01ce2e92010-09-26 22:20:12 -07001488void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1489 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001490 mCurrentInputTargets.push();
1491
1492 InputTarget& target = mCurrentInputTargets.editTop();
1493 target.inputChannel = window->inputChannel;
1494 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001495 target.xOffset = - window->frameLeft;
1496 target.yOffset = - window->frameTop;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001497 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001498}
1499
1500void InputDispatcher::addMonitoringTargetsLocked() {
1501 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1502 mCurrentInputTargets.push();
1503
1504 InputTarget& target = mCurrentInputTargets.editTop();
1505 target.inputChannel = mMonitoringChannels[i];
1506 target.flags = 0;
Jeff Brownb88102f2010-09-08 11:49:43 -07001507 target.xOffset = 0;
1508 target.yOffset = 0;
1509 }
1510}
1511
1512bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001513 const InjectionState* injectionState) {
1514 if (injectionState
Jeff Brownb6997262010-10-08 22:31:17 -07001515 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1516 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1517 if (window) {
1518 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1519 "with input channel %s owned by uid %d",
1520 injectionState->injectorPid, injectionState->injectorUid,
1521 window->inputChannel->getName().string(),
1522 window->ownerUid);
1523 } else {
1524 LOGW("Permission denied: injecting event from pid %d uid %d",
1525 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001526 }
Jeff Brownb6997262010-10-08 22:31:17 -07001527 return false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001528 }
1529 return true;
1530}
1531
Jeff Brown19dfc832010-10-05 12:26:23 -07001532bool InputDispatcher::isWindowObscuredAtPointLocked(
1533 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07001534 size_t numWindows = mWindows.size();
1535 for (size_t i = 0; i < numWindows; i++) {
1536 const InputWindow* other = & mWindows.itemAt(i);
1537 if (other == window) {
1538 break;
1539 }
Jeff Brown19dfc832010-10-05 12:26:23 -07001540 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001541 return true;
1542 }
1543 }
1544 return false;
1545}
1546
Jeff Brown519e0242010-09-15 15:18:56 -07001547bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1548 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1549 if (connectionIndex >= 0) {
1550 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1551 return connection->outboundQueue.isEmpty();
1552 } else {
1553 return true;
1554 }
1555}
1556
1557String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1558 const InputWindow* window) {
1559 if (application) {
1560 if (window) {
1561 String8 label(application->name);
1562 label.append(" - ");
1563 label.append(window->name);
1564 return label;
1565 } else {
1566 return application->name;
1567 }
1568 } else if (window) {
1569 return window->name;
1570 } else {
1571 return String8("<unknown application or window>");
1572 }
1573}
1574
Jeff Browne2fe69e2010-10-18 13:21:23 -07001575void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
Jeff Brown56194eb2011-03-02 19:23:13 -08001576 int32_t eventType = POWER_MANAGER_OTHER_EVENT;
Jeff Brown4d396052010-10-29 21:50:21 -07001577 switch (eventEntry->type) {
1578 case EventEntry::TYPE_MOTION: {
Jeff Browne2fe69e2010-10-18 13:21:23 -07001579 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Brown4d396052010-10-29 21:50:21 -07001580 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1581 return;
1582 }
1583
Jeff Brown56194eb2011-03-02 19:23:13 -08001584 if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
Joe Onorato1a542c72010-11-08 09:48:20 -08001585 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001586 }
Jeff Brown4d396052010-10-29 21:50:21 -07001587 break;
1588 }
1589 case EventEntry::TYPE_KEY: {
1590 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1591 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1592 return;
1593 }
Jeff Brown56194eb2011-03-02 19:23:13 -08001594 eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brown4d396052010-10-29 21:50:21 -07001595 break;
1596 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001597 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001598
Jeff Brownb88102f2010-09-08 11:49:43 -07001599 CommandEntry* commandEntry = postCommandLocked(
1600 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Browne2fe69e2010-10-18 13:21:23 -07001601 commandEntry->eventTime = eventEntry->eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001602 commandEntry->userActivityEventType = eventType;
1603}
1604
Jeff Brown7fbdc842010-06-17 20:52:56 -07001605void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1606 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001607 bool resumeWithAppendedMotionSample) {
1608#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001609 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001610 "xOffset=%f, yOffset=%f, "
Jeff Brown83c09682010-12-23 17:50:18 -08001611 "pointerIds=0x%x, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001612 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001613 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001614 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brown83c09682010-12-23 17:50:18 -08001615 inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001616 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001617#endif
1618
Jeff Brown01ce2e92010-09-26 22:20:12 -07001619 // Make sure we are never called for streaming when splitting across multiple windows.
1620 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1621 assert(! (resumeWithAppendedMotionSample && isSplit));
1622
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001623 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001624 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001625 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb6997262010-10-08 22:31:17 -07001626#if DEBUG_DISPATCH_CYCLE
1627 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001628 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brownb6997262010-10-08 22:31:17 -07001629#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001630 return;
1631 }
1632
Jeff Brown01ce2e92010-09-26 22:20:12 -07001633 // Split a motion event if needed.
1634 if (isSplit) {
1635 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1636
1637 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1638 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1639 MotionEntry* splitMotionEntry = splitMotionEvent(
1640 originalMotionEntry, inputTarget->pointerIds);
Jeff Brown58a2da82011-01-25 16:02:22 -08001641 if (!splitMotionEntry) {
1642 return; // split event was dropped
1643 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001644#if DEBUG_FOCUS
1645 LOGD("channel '%s' ~ Split motion event.",
1646 connection->getInputChannelName());
1647 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1648#endif
1649 eventEntry = splitMotionEntry;
1650 }
1651 }
1652
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001653 // Resume the dispatch cycle with a freshly appended motion sample.
1654 // First we check that the last dispatch entry in the outbound queue is for the same
1655 // motion event to which we appended the motion sample. If we find such a dispatch
1656 // entry, and if it is currently in progress then we try to stream the new sample.
1657 bool wasEmpty = connection->outboundQueue.isEmpty();
1658
1659 if (! wasEmpty && resumeWithAppendedMotionSample) {
1660 DispatchEntry* motionEventDispatchEntry =
1661 connection->findQueuedDispatchEntryForEvent(eventEntry);
1662 if (motionEventDispatchEntry) {
1663 // If the dispatch entry is not in progress, then we must be busy dispatching an
1664 // earlier event. Not a problem, the motion event is on the outbound queue and will
1665 // be dispatched later.
1666 if (! motionEventDispatchEntry->inProgress) {
1667#if DEBUG_BATCHING
1668 LOGD("channel '%s' ~ Not streaming because the motion event has "
1669 "not yet been dispatched. "
1670 "(Waiting for earlier events to be consumed.)",
1671 connection->getInputChannelName());
1672#endif
1673 return;
1674 }
1675
1676 // If the dispatch entry is in progress but it already has a tail of pending
1677 // motion samples, then it must mean that the shared memory buffer filled up.
1678 // Not a problem, when this dispatch cycle is finished, we will eventually start
1679 // a new dispatch cycle to process the tail and that tail includes the newly
1680 // appended motion sample.
1681 if (motionEventDispatchEntry->tailMotionSample) {
1682#if DEBUG_BATCHING
1683 LOGD("channel '%s' ~ Not streaming because no new samples can "
1684 "be appended to the motion event in this dispatch cycle. "
1685 "(Waiting for next dispatch cycle to start.)",
1686 connection->getInputChannelName());
1687#endif
1688 return;
1689 }
1690
1691 // The dispatch entry is in progress and is still potentially open for streaming.
1692 // Try to stream the new motion sample. This might fail if the consumer has already
1693 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001694 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1695 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001696 status_t status = connection->inputPublisher.appendMotionSample(
1697 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1698 if (status == OK) {
1699#if DEBUG_BATCHING
1700 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1701 connection->getInputChannelName());
1702#endif
1703 return;
1704 }
1705
1706#if DEBUG_BATCHING
1707 if (status == NO_MEMORY) {
1708 LOGD("channel '%s' ~ Could not append motion sample to currently "
1709 "dispatched move event because the shared memory buffer is full. "
1710 "(Waiting for next dispatch cycle to start.)",
1711 connection->getInputChannelName());
1712 } else if (status == status_t(FAILED_TRANSACTION)) {
1713 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001714 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001715 "(Waiting for next dispatch cycle to start.)",
1716 connection->getInputChannelName());
1717 } else {
1718 LOGD("channel '%s' ~ Could not append motion sample to currently "
1719 "dispatched move event due to an error, status=%d. "
1720 "(Waiting for next dispatch cycle to start.)",
1721 connection->getInputChannelName(), status);
1722 }
1723#endif
1724 // Failed to stream. Start a new tail of pending motion samples to dispatch
1725 // in the next cycle.
1726 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1727 return;
1728 }
1729 }
1730
1731 // This is a new event.
1732 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001733 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown519e0242010-09-15 15:18:56 -07001734 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1735 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001736 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001737 }
1738
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001739 // Handle the case where we could not stream a new motion sample because the consumer has
1740 // already consumed the motion event (otherwise the corresponding dispatch entry would
1741 // still be in the outbound queue for this connection). We set the head motion sample
1742 // to the list starting with the newly appended motion sample.
1743 if (resumeWithAppendedMotionSample) {
1744#if DEBUG_BATCHING
1745 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1746 "that cannot be streamed because the motion event has already been consumed.",
1747 connection->getInputChannelName());
1748#endif
1749 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1750 dispatchEntry->headMotionSample = appendedMotionSample;
1751 }
1752
1753 // Enqueue the dispatch entry.
1754 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1755
1756 // If the outbound queue was previously empty, start the dispatch cycle going.
1757 if (wasEmpty) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001758 activateConnectionLocked(connection.get());
Jeff Brown519e0242010-09-15 15:18:56 -07001759 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001760 }
1761}
1762
Jeff Brown7fbdc842010-06-17 20:52:56 -07001763void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001764 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001765#if DEBUG_DISPATCH_CYCLE
1766 LOGD("channel '%s' ~ startDispatchCycle",
1767 connection->getInputChannelName());
1768#endif
1769
1770 assert(connection->status == Connection::STATUS_NORMAL);
1771 assert(! connection->outboundQueue.isEmpty());
1772
Jeff Brownb88102f2010-09-08 11:49:43 -07001773 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001774 assert(! dispatchEntry->inProgress);
1775
Jeff Brownb88102f2010-09-08 11:49:43 -07001776 // Mark the dispatch entry as in progress.
1777 dispatchEntry->inProgress = true;
1778
1779 // Update the connection's input state.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001780 EventEntry* eventEntry = dispatchEntry->eventEntry;
Jeff Browncc0c1592011-02-19 05:07:28 -08001781 connection->inputState.trackEvent(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001782
1783 // Publish the event.
1784 status_t status;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001785 switch (eventEntry->type) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001786 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001787 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001788
1789 // Apply target flags.
1790 int32_t action = keyEntry->action;
1791 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001792
1793 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001794 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001795 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1796 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1797 keyEntry->eventTime);
1798
1799 if (status) {
1800 LOGE("channel '%s' ~ Could not publish key event, "
1801 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001802 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001803 return;
1804 }
1805 break;
1806 }
1807
1808 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001809 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001810
1811 // Apply target flags.
1812 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001813 int32_t flags = motionEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001814 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001815 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001816 }
Jeff Brown85a31762010-09-01 17:01:00 -07001817 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1818 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1819 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001820
1821 // If headMotionSample is non-NULL, then it points to the first new sample that we
1822 // were unable to dispatch during the previous cycle so we resume dispatching from
1823 // that point in the list of motion samples.
1824 // Otherwise, we just start from the first sample of the motion event.
1825 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1826 if (! firstMotionSample) {
1827 firstMotionSample = & motionEntry->firstSample;
1828 }
1829
Jeff Brownd3616592010-07-16 17:21:06 -07001830 // Set the X and Y offset depending on the input source.
1831 float xOffset, yOffset;
1832 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1833 xOffset = dispatchEntry->xOffset;
1834 yOffset = dispatchEntry->yOffset;
1835 } else {
1836 xOffset = 0.0f;
1837 yOffset = 0.0f;
1838 }
1839
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001840 // Publish the motion event and the first motion sample.
1841 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07001842 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownd3616592010-07-16 17:21:06 -07001843 xOffset, yOffset,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001844 motionEntry->xPrecision, motionEntry->yPrecision,
1845 motionEntry->downTime, firstMotionSample->eventTime,
1846 motionEntry->pointerCount, motionEntry->pointerIds,
1847 firstMotionSample->pointerCoords);
1848
1849 if (status) {
1850 LOGE("channel '%s' ~ Could not publish motion event, "
1851 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001852 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001853 return;
1854 }
1855
1856 // Append additional motion samples.
1857 MotionSample* nextMotionSample = firstMotionSample->next;
1858 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1859 status = connection->inputPublisher.appendMotionSample(
1860 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1861 if (status == NO_MEMORY) {
1862#if DEBUG_DISPATCH_CYCLE
1863 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1864 "be sent in the next dispatch cycle.",
1865 connection->getInputChannelName());
1866#endif
1867 break;
1868 }
1869 if (status != OK) {
1870 LOGE("channel '%s' ~ Could not append motion sample "
1871 "for a reason other than out of memory, status=%d",
1872 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001873 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001874 return;
1875 }
1876 }
1877
1878 // Remember the next motion sample that we could not dispatch, in case we ran out
1879 // of space in the shared memory buffer.
1880 dispatchEntry->tailMotionSample = nextMotionSample;
1881 break;
1882 }
1883
1884 default: {
1885 assert(false);
1886 }
1887 }
1888
1889 // Send the dispatch signal.
1890 status = connection->inputPublisher.sendDispatchSignal();
1891 if (status) {
1892 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1893 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001894 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001895 return;
1896 }
1897
1898 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001899 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001900 connection->lastDispatchTime = currentTime;
1901
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001902 // Notify other system components.
1903 onDispatchCycleStartedLocked(currentTime, connection);
1904}
1905
Jeff Brown7fbdc842010-06-17 20:52:56 -07001906void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown3915bb82010-11-05 15:02:16 -07001907 const sp<Connection>& connection, bool handled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001908#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001909 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown3915bb82010-11-05 15:02:16 -07001910 "%01.1fms since dispatch, handled=%s",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001911 connection->getInputChannelName(),
1912 connection->getEventLatencyMillis(currentTime),
Jeff Brown3915bb82010-11-05 15:02:16 -07001913 connection->getDispatchLatencyMillis(currentTime),
1914 toString(handled));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001915#endif
1916
Jeff Brown9c3cda02010-06-15 01:31:58 -07001917 if (connection->status == Connection::STATUS_BROKEN
1918 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001919 return;
1920 }
1921
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001922 // Reset the publisher since the event has been consumed.
1923 // We do this now so that the publisher can release some of its internal resources
1924 // while waiting for the next dispatch cycle to begin.
1925 status_t status = connection->inputPublisher.reset();
1926 if (status) {
1927 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1928 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001929 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001930 return;
1931 }
1932
Jeff Brown3915bb82010-11-05 15:02:16 -07001933 // Notify other system components and prepare to start the next dispatch cycle.
1934 onDispatchCycleFinishedLocked(currentTime, connection, handled);
Jeff Brownb88102f2010-09-08 11:49:43 -07001935}
1936
1937void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1938 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001939 // Start the next dispatch cycle for this connection.
1940 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001941 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001942 if (dispatchEntry->inProgress) {
1943 // Finish or resume current event in progress.
1944 if (dispatchEntry->tailMotionSample) {
1945 // We have a tail of undispatched motion samples.
1946 // Reuse the same DispatchEntry and start a new cycle.
1947 dispatchEntry->inProgress = false;
1948 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1949 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07001950 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001951 return;
1952 }
1953 // Finished.
1954 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07001955 if (dispatchEntry->hasForegroundTarget()) {
1956 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001957 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001958 mAllocator.releaseDispatchEntry(dispatchEntry);
1959 } else {
1960 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07001961 // progress event, which means we actually aborted it.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001962 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07001963 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001964 return;
1965 }
1966 }
1967
1968 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07001969 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001970}
1971
Jeff Brownb6997262010-10-08 22:31:17 -07001972void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1973 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001974#if DEBUG_DISPATCH_CYCLE
Jeff Brown83c09682010-12-23 17:50:18 -08001975 LOGD("channel '%s' ~ abortBrokenDispatchCycle",
1976 connection->getInputChannelName());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001977#endif
1978
Jeff Brownb88102f2010-09-08 11:49:43 -07001979 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07001980 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001981
Jeff Brownb6997262010-10-08 22:31:17 -07001982 // The connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07001983 // Ignore already broken or zombie connections.
Jeff Brownb6997262010-10-08 22:31:17 -07001984 if (connection->status == Connection::STATUS_NORMAL) {
1985 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001986
Jeff Brownb6997262010-10-08 22:31:17 -07001987 // Notify other system components.
1988 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001989 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001990}
1991
Jeff Brown519e0242010-09-15 15:18:56 -07001992void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1993 while (! connection->outboundQueue.isEmpty()) {
1994 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1995 if (dispatchEntry->hasForegroundTarget()) {
1996 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001997 }
1998 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001999 }
2000
Jeff Brown519e0242010-09-15 15:18:56 -07002001 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07002002}
2003
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002004int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002005 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2006
2007 { // acquire lock
2008 AutoMutex _l(d->mLock);
2009
2010 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
2011 if (connectionIndex < 0) {
2012 LOGE("Received spurious receive callback for unknown input channel. "
2013 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002014 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002015 }
2016
Jeff Brown7fbdc842010-06-17 20:52:56 -07002017 nsecs_t currentTime = now();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002018
2019 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002020 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002021 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
2022 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brownb6997262010-10-08 22:31:17 -07002023 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002024 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002025 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002026 }
2027
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002028 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002029 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
2030 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002031 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002032 }
2033
Jeff Brown3915bb82010-11-05 15:02:16 -07002034 bool handled = false;
Jeff Brown49ed71d2010-12-06 17:13:33 -08002035 status_t status = connection->inputPublisher.receiveFinishedSignal(&handled);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002036 if (status) {
2037 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
2038 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07002039 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002040 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002041 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002042 }
2043
Jeff Brown3915bb82010-11-05 15:02:16 -07002044 d->finishDispatchCycleLocked(currentTime, connection, handled);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002045 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002046 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002047 } // release lock
2048}
2049
Jeff Brownb6997262010-10-08 22:31:17 -07002050void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
2051 InputState::CancelationOptions options, const char* reason) {
2052 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
2053 synthesizeCancelationEventsForConnectionLocked(
2054 mConnectionsByReceiveFd.valueAt(i), options, reason);
2055 }
2056}
2057
2058void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2059 const sp<InputChannel>& channel, InputState::CancelationOptions options,
2060 const char* reason) {
2061 ssize_t index = getConnectionIndexLocked(channel);
2062 if (index >= 0) {
2063 synthesizeCancelationEventsForConnectionLocked(
2064 mConnectionsByReceiveFd.valueAt(index), options, reason);
2065 }
2066}
2067
2068void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2069 const sp<Connection>& connection, InputState::CancelationOptions options,
2070 const char* reason) {
2071 nsecs_t currentTime = now();
2072
2073 mTempCancelationEvents.clear();
2074 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
2075 mTempCancelationEvents, options);
2076
2077 if (! mTempCancelationEvents.isEmpty()
2078 && connection->status != Connection::STATUS_BROKEN) {
2079#if DEBUG_OUTBOUND_EVENT_DETAILS
2080 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
2081 "with reality: %s, options=%d.",
2082 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
2083#endif
2084 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
2085 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
2086 switch (cancelationEventEntry->type) {
2087 case EventEntry::TYPE_KEY:
2088 logOutboundKeyDetailsLocked("cancel - ",
2089 static_cast<KeyEntry*>(cancelationEventEntry));
2090 break;
2091 case EventEntry::TYPE_MOTION:
2092 logOutboundMotionDetailsLocked("cancel - ",
2093 static_cast<MotionEntry*>(cancelationEventEntry));
2094 break;
2095 }
2096
2097 int32_t xOffset, yOffset;
2098 const InputWindow* window = getWindowLocked(connection->inputChannel);
2099 if (window) {
2100 xOffset = -window->frameLeft;
2101 yOffset = -window->frameTop;
2102 } else {
2103 xOffset = 0;
2104 yOffset = 0;
2105 }
2106
2107 DispatchEntry* cancelationDispatchEntry =
2108 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
2109 0, xOffset, yOffset);
2110 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
2111
2112 mAllocator.releaseEventEntry(cancelationEventEntry);
2113 }
2114
2115 if (!connection->outboundQueue.headSentinel.next->inProgress) {
2116 startDispatchCycleLocked(currentTime, connection);
2117 }
2118 }
2119}
2120
Jeff Brown01ce2e92010-09-26 22:20:12 -07002121InputDispatcher::MotionEntry*
2122InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2123 assert(pointerIds.value != 0);
2124
2125 uint32_t splitPointerIndexMap[MAX_POINTERS];
2126 int32_t splitPointerIds[MAX_POINTERS];
2127 PointerCoords splitPointerCoords[MAX_POINTERS];
2128
2129 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2130 uint32_t splitPointerCount = 0;
2131
2132 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2133 originalPointerIndex++) {
2134 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
2135 if (pointerIds.hasBit(pointerId)) {
2136 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2137 splitPointerIds[splitPointerCount] = pointerId;
2138 splitPointerCoords[splitPointerCount] =
2139 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
2140 splitPointerCount += 1;
2141 }
2142 }
Jeff Brown58a2da82011-01-25 16:02:22 -08002143
2144 if (splitPointerCount != pointerIds.count()) {
2145 // This is bad. We are missing some of the pointers that we expected to deliver.
2146 // Most likely this indicates that we received an ACTION_MOVE events that has
2147 // different pointer ids than we expected based on the previous ACTION_DOWN
2148 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2149 // in this way.
2150 LOGW("Dropping split motion event because the pointer count is %d but "
2151 "we expected there to be %d pointers. This probably means we received "
2152 "a broken sequence of pointer ids from the input device.",
2153 splitPointerCount, pointerIds.count());
2154 return NULL;
2155 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002156
2157 int32_t action = originalMotionEntry->action;
2158 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2159 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2160 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2161 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2162 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2163 if (pointerIds.hasBit(pointerId)) {
2164 if (pointerIds.count() == 1) {
2165 // The first/last pointer went down/up.
2166 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2167 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07002168 } else {
2169 // A secondary pointer went down/up.
2170 uint32_t splitPointerIndex = 0;
2171 while (pointerId != splitPointerIds[splitPointerIndex]) {
2172 splitPointerIndex += 1;
2173 }
2174 action = maskedAction | (splitPointerIndex
2175 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002176 }
2177 } else {
2178 // An unrelated pointer changed.
2179 action = AMOTION_EVENT_ACTION_MOVE;
2180 }
2181 }
2182
2183 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2184 originalMotionEntry->eventTime,
2185 originalMotionEntry->deviceId,
2186 originalMotionEntry->source,
2187 originalMotionEntry->policyFlags,
2188 action,
2189 originalMotionEntry->flags,
2190 originalMotionEntry->metaState,
2191 originalMotionEntry->edgeFlags,
2192 originalMotionEntry->xPrecision,
2193 originalMotionEntry->yPrecision,
2194 originalMotionEntry->downTime,
2195 splitPointerCount, splitPointerIds, splitPointerCoords);
2196
2197 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2198 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2199 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2200 splitPointerIndex++) {
2201 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2202 splitPointerCoords[splitPointerIndex] =
2203 originalMotionSample->pointerCoords[originalPointerIndex];
2204 }
2205
2206 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2207 splitPointerCoords);
2208 }
2209
2210 return splitMotionEntry;
2211}
2212
Jeff Brown9c3cda02010-06-15 01:31:58 -07002213void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002214#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07002215 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002216#endif
2217
Jeff Brownb88102f2010-09-08 11:49:43 -07002218 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002219 { // acquire lock
2220 AutoMutex _l(mLock);
2221
Jeff Brown7fbdc842010-06-17 20:52:56 -07002222 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07002223 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002224 } // release lock
2225
Jeff Brownb88102f2010-09-08 11:49:43 -07002226 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002227 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002228 }
2229}
2230
Jeff Brown58a2da82011-01-25 16:02:22 -08002231void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002232 uint32_t policyFlags, int32_t action, int32_t flags,
2233 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2234#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002235 LOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002236 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07002237 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002238 keyCode, scanCode, metaState, downTime);
2239#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002240 if (! validateKeyEvent(action)) {
2241 return;
2242 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002243
Jeff Brown1f245102010-11-18 20:53:46 -08002244 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2245 policyFlags |= POLICY_FLAG_VIRTUAL;
2246 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2247 }
2248
Jeff Browne20c9e02010-10-11 14:20:19 -07002249 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown1f245102010-11-18 20:53:46 -08002250
2251 KeyEvent event;
2252 event.initialize(deviceId, source, action, flags, keyCode, scanCode,
2253 metaState, 0, downTime, eventTime);
2254
2255 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
2256
2257 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2258 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2259 }
Jeff Brownb6997262010-10-08 22:31:17 -07002260
Jeff Brownb88102f2010-09-08 11:49:43 -07002261 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002262 { // acquire lock
2263 AutoMutex _l(mLock);
2264
Jeff Brown7fbdc842010-06-17 20:52:56 -07002265 int32_t repeatCount = 0;
2266 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002267 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002268 metaState, repeatCount, downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002269
Jeff Brownb88102f2010-09-08 11:49:43 -07002270 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002271 } // release lock
2272
Jeff Brownb88102f2010-09-08 11:49:43 -07002273 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002274 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002275 }
2276}
2277
Jeff Brown58a2da82011-01-25 16:02:22 -08002278void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002279 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002280 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2281 float xPrecision, float yPrecision, nsecs_t downTime) {
2282#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002283 LOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002284 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2285 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2286 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002287 xPrecision, yPrecision, downTime);
2288 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002289 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002290 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002291 "orientation=%f",
Jeff Brown91c69ab2011-02-14 17:03:18 -08002292 i, pointerIds[i],
Jeff Brownebbd5d12011-02-17 13:01:34 -08002293 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2294 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2295 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2296 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2297 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2298 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2299 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2300 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2301 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002302 }
2303#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002304 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2305 return;
2306 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002307
Jeff Browne20c9e02010-10-11 14:20:19 -07002308 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown56194eb2011-03-02 19:23:13 -08002309 mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002310
Jeff Brownb88102f2010-09-08 11:49:43 -07002311 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002312 { // acquire lock
2313 AutoMutex _l(mLock);
2314
2315 // Attempt batching and streaming of move events.
Jeff Browncc0c1592011-02-19 05:07:28 -08002316 if (action == AMOTION_EVENT_ACTION_MOVE
2317 || action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002318 // BATCHING CASE
2319 //
2320 // Try to append a move sample to the tail of the inbound queue for this device.
2321 // Give up if we encounter a non-move motion event for this device since that
2322 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002323 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2324 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002325 if (entry->type != EventEntry::TYPE_MOTION) {
2326 // Keep looking for motion events.
2327 continue;
2328 }
2329
2330 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2331 if (motionEntry->deviceId != deviceId) {
2332 // Keep looking for this device.
2333 continue;
2334 }
2335
Jeff Browncc0c1592011-02-19 05:07:28 -08002336 if (motionEntry->action != action
Jeff Brown58a2da82011-01-25 16:02:22 -08002337 || motionEntry->source != source
Jeff Brown7fbdc842010-06-17 20:52:56 -07002338 || motionEntry->pointerCount != pointerCount
2339 || motionEntry->isInjected()) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002340 // Last motion event in the queue for this device is not compatible for
2341 // appending new samples. Stop here.
2342 goto NoBatchingOrStreaming;
2343 }
2344
2345 // The last motion event is a move and is compatible for appending.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002346 // Do the batching magic.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002347 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002348#if DEBUG_BATCHING
2349 LOGD("Appended motion sample onto batch for most recent "
2350 "motion event for this device in the inbound queue.");
2351#endif
Jeff Brown9c3cda02010-06-15 01:31:58 -07002352 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002353 }
2354
2355 // STREAMING CASE
2356 //
2357 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002358 // Search the outbound queue for the current foreground targets to find a dispatched
2359 // motion event that is still in progress. If found, then, appen the new sample to
2360 // that event and push it out to all current targets. The logic in
2361 // prepareDispatchCycleLocked takes care of the case where some targets may
2362 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002363 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002364 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2365 const InputTarget& inputTarget = mCurrentInputTargets[i];
2366 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2367 // Skip non-foreground targets. We only want to stream if there is at
2368 // least one foreground target whose dispatch is still in progress.
2369 continue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002370 }
Jeff Brown519e0242010-09-15 15:18:56 -07002371
2372 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2373 if (connectionIndex < 0) {
2374 // Connection must no longer be valid.
2375 continue;
2376 }
2377
2378 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2379 if (connection->outboundQueue.isEmpty()) {
2380 // This foreground target has an empty outbound queue.
2381 continue;
2382 }
2383
2384 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2385 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002386 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2387 || dispatchEntry->isSplit()) {
2388 // No motion event is being dispatched, or it is being split across
2389 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002390 continue;
2391 }
2392
2393 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2394 dispatchEntry->eventEntry);
Jeff Browncc0c1592011-02-19 05:07:28 -08002395 if (motionEntry->action != action
Jeff Brown519e0242010-09-15 15:18:56 -07002396 || motionEntry->deviceId != deviceId
Jeff Brown58a2da82011-01-25 16:02:22 -08002397 || motionEntry->source != source
Jeff Brown519e0242010-09-15 15:18:56 -07002398 || motionEntry->pointerCount != pointerCount
2399 || motionEntry->isInjected()) {
2400 // The motion event is not compatible with this move.
2401 continue;
2402 }
2403
2404 // Hurray! This foreground target is currently dispatching a move event
2405 // that we can stream onto. Append the motion sample and resume dispatch.
2406 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2407#if DEBUG_BATCHING
2408 LOGD("Appended motion sample onto batch for most recently dispatched "
2409 "motion event for this device in the outbound queues. "
2410 "Attempting to stream the motion sample.");
2411#endif
2412 nsecs_t currentTime = now();
2413 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2414 true /*resumeWithAppendedMotionSample*/);
2415
2416 runCommandsLockedInterruptible();
2417 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002418 }
2419 }
2420
2421NoBatchingOrStreaming:;
2422 }
2423
2424 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002425 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002426 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002427 xPrecision, yPrecision, downTime,
2428 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002429
Jeff Brownb88102f2010-09-08 11:49:43 -07002430 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002431 } // release lock
2432
Jeff Brownb88102f2010-09-08 11:49:43 -07002433 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002434 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002435 }
2436}
2437
Jeff Brownb6997262010-10-08 22:31:17 -07002438void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2439 uint32_t policyFlags) {
2440#if DEBUG_INBOUND_EVENT_DETAILS
2441 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2442 switchCode, switchValue, policyFlags);
2443#endif
2444
Jeff Browne20c9e02010-10-11 14:20:19 -07002445 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002446 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2447}
2448
Jeff Brown7fbdc842010-06-17 20:52:56 -07002449int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002450 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002451#if DEBUG_INBOUND_EVENT_DETAILS
2452 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002453 "syncMode=%d, timeoutMillis=%d",
2454 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002455#endif
2456
2457 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Browne20c9e02010-10-11 14:20:19 -07002458
2459 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2460 if (hasInjectionPermission(injectorPid, injectorUid)) {
2461 policyFlags |= POLICY_FLAG_TRUSTED;
2462 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002463
Jeff Brownb6997262010-10-08 22:31:17 -07002464 EventEntry* injectedEntry;
2465 switch (event->getType()) {
2466 case AINPUT_EVENT_TYPE_KEY: {
2467 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2468 int32_t action = keyEvent->getAction();
2469 if (! validateKeyEvent(action)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002470 return INPUT_EVENT_INJECTION_FAILED;
2471 }
2472
Jeff Brownb6997262010-10-08 22:31:17 -07002473 int32_t flags = keyEvent->getFlags();
Jeff Brown1f245102010-11-18 20:53:46 -08002474 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2475 policyFlags |= POLICY_FLAG_VIRTUAL;
2476 }
2477
2478 mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
2479
2480 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2481 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2482 }
Jeff Brown6ec402b2010-07-28 15:48:59 -07002483
Jeff Brownb6997262010-10-08 22:31:17 -07002484 mLock.lock();
Jeff Brown1f245102010-11-18 20:53:46 -08002485 injectedEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
2486 keyEvent->getDeviceId(), keyEvent->getSource(),
2487 policyFlags, action, flags,
2488 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
Jeff Brownb6997262010-10-08 22:31:17 -07002489 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2490 break;
2491 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002492
Jeff Brownb6997262010-10-08 22:31:17 -07002493 case AINPUT_EVENT_TYPE_MOTION: {
2494 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2495 int32_t action = motionEvent->getAction();
2496 size_t pointerCount = motionEvent->getPointerCount();
2497 const int32_t* pointerIds = motionEvent->getPointerIds();
2498 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2499 return INPUT_EVENT_INJECTION_FAILED;
2500 }
2501
2502 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown56194eb2011-03-02 19:23:13 -08002503 mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002504
2505 mLock.lock();
2506 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2507 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2508 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2509 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2510 action, motionEvent->getFlags(),
2511 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2512 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2513 motionEvent->getDownTime(), uint32_t(pointerCount),
2514 pointerIds, samplePointerCoords);
2515 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2516 sampleEventTimes += 1;
2517 samplePointerCoords += pointerCount;
2518 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2519 }
2520 injectedEntry = motionEntry;
2521 break;
2522 }
2523
2524 default:
2525 LOGW("Cannot inject event of type %d", event->getType());
2526 return INPUT_EVENT_INJECTION_FAILED;
2527 }
2528
2529 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2530 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2531 injectionState->injectionIsAsync = true;
2532 }
2533
2534 injectionState->refCount += 1;
2535 injectedEntry->injectionState = injectionState;
2536
2537 bool needWake = enqueueInboundEventLocked(injectedEntry);
2538 mLock.unlock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002539
Jeff Brownb88102f2010-09-08 11:49:43 -07002540 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002541 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002542 }
2543
2544 int32_t injectionResult;
2545 { // acquire lock
2546 AutoMutex _l(mLock);
2547
Jeff Brown6ec402b2010-07-28 15:48:59 -07002548 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2549 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2550 } else {
2551 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002552 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002553 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2554 break;
2555 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002556
Jeff Brown7fbdc842010-06-17 20:52:56 -07002557 nsecs_t remainingTimeout = endTime - now();
2558 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002559#if DEBUG_INJECTION
2560 LOGD("injectInputEvent - Timed out waiting for injection result "
2561 "to become available.");
2562#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002563 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2564 break;
2565 }
2566
Jeff Brown6ec402b2010-07-28 15:48:59 -07002567 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2568 }
2569
2570 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2571 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002572 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002573#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002574 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002575 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002576#endif
2577 nsecs_t remainingTimeout = endTime - now();
2578 if (remainingTimeout <= 0) {
2579#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002580 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002581 "dispatches to finish.");
2582#endif
2583 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2584 break;
2585 }
2586
2587 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2588 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002589 }
2590 }
2591
Jeff Brown01ce2e92010-09-26 22:20:12 -07002592 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002593 } // release lock
2594
Jeff Brown6ec402b2010-07-28 15:48:59 -07002595#if DEBUG_INJECTION
2596 LOGD("injectInputEvent - Finished with result %d. "
2597 "injectorPid=%d, injectorUid=%d",
2598 injectionResult, injectorPid, injectorUid);
2599#endif
2600
Jeff Brown7fbdc842010-06-17 20:52:56 -07002601 return injectionResult;
2602}
2603
Jeff Brownb6997262010-10-08 22:31:17 -07002604bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2605 return injectorUid == 0
2606 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2607}
2608
Jeff Brown7fbdc842010-06-17 20:52:56 -07002609void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002610 InjectionState* injectionState = entry->injectionState;
2611 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002612#if DEBUG_INJECTION
2613 LOGD("Setting input event injection result to %d. "
2614 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002615 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002616#endif
2617
Jeff Brown01ce2e92010-09-26 22:20:12 -07002618 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002619 // Log the outcome since the injector did not wait for the injection result.
2620 switch (injectionResult) {
2621 case INPUT_EVENT_INJECTION_SUCCEEDED:
2622 LOGV("Asynchronous input event injection succeeded.");
2623 break;
2624 case INPUT_EVENT_INJECTION_FAILED:
2625 LOGW("Asynchronous input event injection failed.");
2626 break;
2627 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2628 LOGW("Asynchronous input event injection permission denied.");
2629 break;
2630 case INPUT_EVENT_INJECTION_TIMED_OUT:
2631 LOGW("Asynchronous input event injection timed out.");
2632 break;
2633 }
2634 }
2635
Jeff Brown01ce2e92010-09-26 22:20:12 -07002636 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002637 mInjectionResultAvailableCondition.broadcast();
2638 }
2639}
2640
Jeff Brown01ce2e92010-09-26 22:20:12 -07002641void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2642 InjectionState* injectionState = entry->injectionState;
2643 if (injectionState) {
2644 injectionState->pendingForegroundDispatches += 1;
2645 }
2646}
2647
Jeff Brown519e0242010-09-15 15:18:56 -07002648void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002649 InjectionState* injectionState = entry->injectionState;
2650 if (injectionState) {
2651 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002652
Jeff Brown01ce2e92010-09-26 22:20:12 -07002653 if (injectionState->pendingForegroundDispatches == 0) {
2654 mInjectionSyncFinishedCondition.broadcast();
2655 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002656 }
2657}
2658
Jeff Brown01ce2e92010-09-26 22:20:12 -07002659const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2660 for (size_t i = 0; i < mWindows.size(); i++) {
2661 const InputWindow* window = & mWindows[i];
2662 if (window->inputChannel == inputChannel) {
2663 return window;
2664 }
2665 }
2666 return NULL;
2667}
2668
Jeff Brownb88102f2010-09-08 11:49:43 -07002669void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2670#if DEBUG_FOCUS
2671 LOGD("setInputWindows");
2672#endif
2673 { // acquire lock
2674 AutoMutex _l(mLock);
2675
Jeff Brown01ce2e92010-09-26 22:20:12 -07002676 // Clear old window pointers.
Jeff Brownb6997262010-10-08 22:31:17 -07002677 sp<InputChannel> oldFocusedWindowChannel;
2678 if (mFocusedWindow) {
2679 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2680 mFocusedWindow = NULL;
2681 }
2682
Jeff Brownb88102f2010-09-08 11:49:43 -07002683 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002684
2685 // Loop over new windows and rebuild the necessary window pointers for
2686 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002687 mWindows.appendVector(inputWindows);
2688
2689 size_t numWindows = mWindows.size();
2690 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002691 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002692 if (window->hasFocus) {
2693 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002694 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002695 }
2696 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002697
Jeff Brownb6997262010-10-08 22:31:17 -07002698 if (oldFocusedWindowChannel != NULL) {
2699 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2700#if DEBUG_FOCUS
2701 LOGD("Focus left window: %s",
2702 oldFocusedWindowChannel->getName().string());
2703#endif
2704 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2705 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2706 oldFocusedWindowChannel.clear();
2707 }
2708 }
2709 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2710#if DEBUG_FOCUS
2711 LOGD("Focus entered window: %s",
2712 mFocusedWindow->inputChannel->getName().string());
2713#endif
2714 }
2715
Jeff Brown01ce2e92010-09-26 22:20:12 -07002716 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2717 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2718 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2719 if (window) {
2720 touchedWindow.window = window;
2721 i += 1;
2722 } else {
Jeff Brownb6997262010-10-08 22:31:17 -07002723#if DEBUG_FOCUS
2724 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2725#endif
Jeff Brownb6997262010-10-08 22:31:17 -07002726 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2727 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownaf48cae2010-10-15 16:20:51 -07002728 mTouchState.windows.removeAt(i);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002729 }
2730 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002731
Jeff Brownb88102f2010-09-08 11:49:43 -07002732#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002733 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002734#endif
2735 } // release lock
2736
2737 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002738 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002739}
2740
2741void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2742#if DEBUG_FOCUS
2743 LOGD("setFocusedApplication");
2744#endif
2745 { // acquire lock
2746 AutoMutex _l(mLock);
2747
2748 releaseFocusedApplicationLocked();
2749
2750 if (inputApplication) {
2751 mFocusedApplicationStorage = *inputApplication;
2752 mFocusedApplication = & mFocusedApplicationStorage;
2753 }
2754
2755#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002756 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002757#endif
2758 } // release lock
2759
2760 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002761 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002762}
2763
2764void InputDispatcher::releaseFocusedApplicationLocked() {
2765 if (mFocusedApplication) {
2766 mFocusedApplication = NULL;
Jeff Brown928e0542011-01-10 11:17:36 -08002767 mFocusedApplicationStorage.inputApplicationHandle.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -07002768 }
2769}
2770
2771void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2772#if DEBUG_FOCUS
2773 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2774#endif
2775
2776 bool changed;
2777 { // acquire lock
2778 AutoMutex _l(mLock);
2779
2780 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brown120a4592010-10-27 18:43:51 -07002781 if (mDispatchFrozen && !frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002782 resetANRTimeoutsLocked();
2783 }
2784
Jeff Brown120a4592010-10-27 18:43:51 -07002785 if (mDispatchEnabled && !enabled) {
2786 resetAndDropEverythingLocked("dispatcher is being disabled");
2787 }
2788
Jeff Brownb88102f2010-09-08 11:49:43 -07002789 mDispatchEnabled = enabled;
2790 mDispatchFrozen = frozen;
2791 changed = true;
2792 } else {
2793 changed = false;
2794 }
2795
2796#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002797 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002798#endif
2799 } // release lock
2800
2801 if (changed) {
2802 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002803 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002804 }
2805}
2806
Jeff Browne6504122010-09-27 14:52:15 -07002807bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2808 const sp<InputChannel>& toChannel) {
2809#if DEBUG_FOCUS
2810 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2811 fromChannel->getName().string(), toChannel->getName().string());
2812#endif
2813 { // acquire lock
2814 AutoMutex _l(mLock);
2815
2816 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2817 const InputWindow* toWindow = getWindowLocked(toChannel);
2818 if (! fromWindow || ! toWindow) {
2819#if DEBUG_FOCUS
2820 LOGD("Cannot transfer focus because from or to window not found.");
2821#endif
2822 return false;
2823 }
2824 if (fromWindow == toWindow) {
2825#if DEBUG_FOCUS
2826 LOGD("Trivial transfer to same window.");
2827#endif
2828 return true;
2829 }
2830
2831 bool found = false;
2832 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2833 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2834 if (touchedWindow.window == fromWindow) {
2835 int32_t oldTargetFlags = touchedWindow.targetFlags;
2836 BitSet32 pointerIds = touchedWindow.pointerIds;
2837
2838 mTouchState.windows.removeAt(i);
2839
Jeff Brown46e75292010-11-10 16:53:45 -08002840 int32_t newTargetFlags = oldTargetFlags
2841 & (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT);
Jeff Browne6504122010-09-27 14:52:15 -07002842 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2843
2844 found = true;
2845 break;
2846 }
2847 }
2848
2849 if (! found) {
2850#if DEBUG_FOCUS
2851 LOGD("Focus transfer failed because from window did not have focus.");
2852#endif
2853 return false;
2854 }
2855
Jeff Brown9c9f1a32010-10-11 18:32:20 -07002856 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2857 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2858 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2859 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2860 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2861
2862 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2863 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2864 InputState::CANCEL_POINTER_EVENTS,
2865 "transferring touch focus from this window to another window");
2866 }
2867
Jeff Browne6504122010-09-27 14:52:15 -07002868#if DEBUG_FOCUS
2869 logDispatchStateLocked();
2870#endif
2871 } // release lock
2872
2873 // Wake up poll loop since it may need to make new input dispatching choices.
2874 mLooper->wake();
2875 return true;
2876}
2877
Jeff Brown120a4592010-10-27 18:43:51 -07002878void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2879#if DEBUG_FOCUS
2880 LOGD("Resetting and dropping all events (%s).", reason);
2881#endif
2882
2883 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2884
2885 resetKeyRepeatLocked();
2886 releasePendingEventLocked();
2887 drainInboundQueueLocked();
2888 resetTargetsLocked();
2889
2890 mTouchState.reset();
2891}
2892
Jeff Brownb88102f2010-09-08 11:49:43 -07002893void InputDispatcher::logDispatchStateLocked() {
2894 String8 dump;
2895 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002896
2897 char* text = dump.lockBuffer(dump.size());
2898 char* start = text;
2899 while (*start != '\0') {
2900 char* end = strchr(start, '\n');
2901 if (*end == '\n') {
2902 *(end++) = '\0';
2903 }
2904 LOGD("%s", start);
2905 start = end;
2906 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002907}
2908
2909void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002910 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2911 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07002912
2913 if (mFocusedApplication) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002914 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002915 mFocusedApplication->name.string(),
2916 mFocusedApplication->dispatchingTimeout / 1000000.0);
2917 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002918 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002919 }
Jeff Brownf2f487182010-10-01 17:46:21 -07002920 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002921 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f487182010-10-01 17:46:21 -07002922
2923 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2924 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
Jeff Brown95712852011-01-04 19:41:59 -08002925 dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
Jeff Brown58a2da82011-01-25 16:02:22 -08002926 dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
Jeff Brownf2f487182010-10-01 17:46:21 -07002927 if (!mTouchState.windows.isEmpty()) {
2928 dump.append(INDENT "TouchedWindows:\n");
2929 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2930 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2931 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2932 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2933 touchedWindow.targetFlags);
2934 }
2935 } else {
2936 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002937 }
2938
Jeff Brownf2f487182010-10-01 17:46:21 -07002939 if (!mWindows.isEmpty()) {
2940 dump.append(INDENT "Windows:\n");
2941 for (size_t i = 0; i < mWindows.size(); i++) {
2942 const InputWindow& window = mWindows[i];
2943 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2944 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2945 "frame=[%d,%d][%d,%d], "
Jeff Brownfbf09772011-01-16 14:06:57 -08002946 "touchableRegion=",
Jeff Brownf2f487182010-10-01 17:46:21 -07002947 i, window.name.string(),
2948 toString(window.paused),
2949 toString(window.hasFocus),
2950 toString(window.hasWallpaper),
2951 toString(window.visible),
2952 toString(window.canReceiveKeys),
2953 window.layoutParamsFlags, window.layoutParamsType,
2954 window.layer,
2955 window.frameLeft, window.frameTop,
Jeff Brownfbf09772011-01-16 14:06:57 -08002956 window.frameRight, window.frameBottom);
2957 dumpRegion(dump, window.touchableRegion);
2958 dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07002959 window.ownerPid, window.ownerUid,
2960 window.dispatchingTimeout / 1000000.0);
2961 }
2962 } else {
2963 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002964 }
2965
Jeff Brownf2f487182010-10-01 17:46:21 -07002966 if (!mMonitoringChannels.isEmpty()) {
2967 dump.append(INDENT "MonitoringChannels:\n");
2968 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2969 const sp<InputChannel>& channel = mMonitoringChannels[i];
2970 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2971 }
2972 } else {
2973 dump.append(INDENT "MonitoringChannels: <none>\n");
2974 }
Jeff Brown519e0242010-09-15 15:18:56 -07002975
Jeff Brownf2f487182010-10-01 17:46:21 -07002976 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2977
2978 if (!mActiveConnections.isEmpty()) {
2979 dump.append(INDENT "ActiveConnections:\n");
2980 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2981 const Connection* connection = mActiveConnections[i];
Jeff Brown76860e32010-10-25 17:37:46 -07002982 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brownb6997262010-10-08 22:31:17 -07002983 "inputState.isNeutral=%s\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07002984 i, connection->getInputChannelName(), connection->getStatusLabel(),
2985 connection->outboundQueue.count(),
Jeff Brownb6997262010-10-08 22:31:17 -07002986 toString(connection->inputState.isNeutral()));
Jeff Brownf2f487182010-10-01 17:46:21 -07002987 }
2988 } else {
2989 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002990 }
2991
2992 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002993 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002994 (mAppSwitchDueTime - now()) / 1000000.0);
2995 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002996 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002997 }
2998}
2999
Jeff Brown928e0542011-01-10 11:17:36 -08003000status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
3001 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003002#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07003003 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
3004 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07003005#endif
3006
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003007 { // acquire lock
3008 AutoMutex _l(mLock);
3009
Jeff Brown519e0242010-09-15 15:18:56 -07003010 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003011 LOGW("Attempted to register already registered input channel '%s'",
3012 inputChannel->getName().string());
3013 return BAD_VALUE;
3014 }
3015
Jeff Brown928e0542011-01-10 11:17:36 -08003016 sp<Connection> connection = new Connection(inputChannel, inputWindowHandle);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003017 status_t status = connection->initialize();
3018 if (status) {
3019 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
3020 inputChannel->getName().string(), status);
3021 return status;
3022 }
3023
Jeff Brown2cbecea2010-08-17 15:59:26 -07003024 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003025 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003026
Jeff Brownb88102f2010-09-08 11:49:43 -07003027 if (monitor) {
3028 mMonitoringChannels.push(inputChannel);
3029 }
3030
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003031 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07003032
Jeff Brown9c3cda02010-06-15 01:31:58 -07003033 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003034 } // release lock
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003035 return OK;
3036}
3037
3038status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003039#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07003040 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07003041#endif
3042
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003043 { // acquire lock
3044 AutoMutex _l(mLock);
3045
Jeff Brown519e0242010-09-15 15:18:56 -07003046 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003047 if (connectionIndex < 0) {
3048 LOGW("Attempted to unregister already unregistered input channel '%s'",
3049 inputChannel->getName().string());
3050 return BAD_VALUE;
3051 }
3052
3053 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3054 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
3055
3056 connection->status = Connection::STATUS_ZOMBIE;
3057
Jeff Brownb88102f2010-09-08 11:49:43 -07003058 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3059 if (mMonitoringChannels[i] == inputChannel) {
3060 mMonitoringChannels.removeAt(i);
3061 break;
3062 }
3063 }
3064
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003065 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07003066
Jeff Brown7fbdc842010-06-17 20:52:56 -07003067 nsecs_t currentTime = now();
Jeff Brownb6997262010-10-08 22:31:17 -07003068 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003069
3070 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003071 } // release lock
3072
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003073 // Wake the poll loop because removing the connection may have changed the current
3074 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003075 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003076 return OK;
3077}
3078
Jeff Brown519e0242010-09-15 15:18:56 -07003079ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07003080 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
3081 if (connectionIndex >= 0) {
3082 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3083 if (connection->inputChannel.get() == inputChannel.get()) {
3084 return connectionIndex;
3085 }
3086 }
3087
3088 return -1;
3089}
3090
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003091void InputDispatcher::activateConnectionLocked(Connection* connection) {
3092 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3093 if (mActiveConnections.itemAt(i) == connection) {
3094 return;
3095 }
3096 }
3097 mActiveConnections.add(connection);
3098}
3099
3100void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
3101 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3102 if (mActiveConnections.itemAt(i) == connection) {
3103 mActiveConnections.removeAt(i);
3104 return;
3105 }
3106 }
3107}
3108
Jeff Brown9c3cda02010-06-15 01:31:58 -07003109void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003110 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003111}
3112
Jeff Brown9c3cda02010-06-15 01:31:58 -07003113void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown3915bb82010-11-05 15:02:16 -07003114 nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
3115 CommandEntry* commandEntry = postCommandLocked(
3116 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
3117 commandEntry->connection = connection;
3118 commandEntry->handled = handled;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003119}
3120
Jeff Brown9c3cda02010-06-15 01:31:58 -07003121void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003122 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003123 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3124 connection->getInputChannelName());
3125
Jeff Brown9c3cda02010-06-15 01:31:58 -07003126 CommandEntry* commandEntry = postCommandLocked(
3127 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003128 commandEntry->connection = connection;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003129}
3130
Jeff Brown519e0242010-09-15 15:18:56 -07003131void InputDispatcher::onANRLocked(
3132 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
3133 nsecs_t eventTime, nsecs_t waitStartTime) {
3134 LOGI("Application is not responding: %s. "
3135 "%01.1fms since event, %01.1fms since wait started",
3136 getApplicationWindowLabelLocked(application, window).string(),
3137 (currentTime - eventTime) / 1000000.0,
3138 (currentTime - waitStartTime) / 1000000.0);
3139
3140 CommandEntry* commandEntry = postCommandLocked(
3141 & InputDispatcher::doNotifyANRLockedInterruptible);
3142 if (application) {
Jeff Brown928e0542011-01-10 11:17:36 -08003143 commandEntry->inputApplicationHandle = application->inputApplicationHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003144 }
3145 if (window) {
Jeff Brown928e0542011-01-10 11:17:36 -08003146 commandEntry->inputWindowHandle = window->inputWindowHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003147 commandEntry->inputChannel = window->inputChannel;
3148 }
3149}
3150
Jeff Brownb88102f2010-09-08 11:49:43 -07003151void InputDispatcher::doNotifyConfigurationChangedInterruptible(
3152 CommandEntry* commandEntry) {
3153 mLock.unlock();
3154
3155 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
3156
3157 mLock.lock();
3158}
3159
Jeff Brown9c3cda02010-06-15 01:31:58 -07003160void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
3161 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003162 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07003163
Jeff Brown7fbdc842010-06-17 20:52:56 -07003164 if (connection->status != Connection::STATUS_ZOMBIE) {
3165 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003166
Jeff Brown928e0542011-01-10 11:17:36 -08003167 mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003168
3169 mLock.lock();
3170 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07003171}
3172
Jeff Brown519e0242010-09-15 15:18:56 -07003173void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07003174 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07003175 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003176
Jeff Brown519e0242010-09-15 15:18:56 -07003177 nsecs_t newTimeout = mPolicy->notifyANR(
Jeff Brown928e0542011-01-10 11:17:36 -08003178 commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003179
Jeff Brown519e0242010-09-15 15:18:56 -07003180 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07003181
Jeff Brown519e0242010-09-15 15:18:56 -07003182 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003183}
3184
Jeff Brownb88102f2010-09-08 11:49:43 -07003185void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3186 CommandEntry* commandEntry) {
3187 KeyEntry* entry = commandEntry->keyEntry;
Jeff Brown1f245102010-11-18 20:53:46 -08003188
3189 KeyEvent event;
3190 initializeKeyEvent(&event, entry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003191
3192 mLock.unlock();
3193
Jeff Brown928e0542011-01-10 11:17:36 -08003194 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
Jeff Brown1f245102010-11-18 20:53:46 -08003195 &event, entry->policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -07003196
3197 mLock.lock();
3198
3199 entry->interceptKeyResult = consumed
3200 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
3201 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3202 mAllocator.releaseKeyEntry(entry);
3203}
3204
Jeff Brown3915bb82010-11-05 15:02:16 -07003205void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3206 CommandEntry* commandEntry) {
3207 sp<Connection> connection = commandEntry->connection;
3208 bool handled = commandEntry->handled;
3209
Jeff Brown49ed71d2010-12-06 17:13:33 -08003210 if (!connection->outboundQueue.isEmpty()) {
Jeff Brown3915bb82010-11-05 15:02:16 -07003211 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
3212 if (dispatchEntry->inProgress
3213 && dispatchEntry->hasForegroundTarget()
3214 && dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3215 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003216 if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
3217 if (handled) {
3218 // If the application handled a non-fallback key, then immediately
3219 // cancel all fallback keys previously dispatched to the application.
3220 // This behavior will prevent chording with fallback keys (so they cannot
3221 // be used as modifiers) but it will ensure that fallback keys do not
3222 // get stuck. This takes care of the case where the application does not handle
3223 // the original DOWN so we generate a fallback DOWN but it does handle
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003224 // the original UP in which case we want to send a fallback CANCEL.
Jeff Brown49ed71d2010-12-06 17:13:33 -08003225 synthesizeCancelationEventsForConnectionLocked(connection,
3226 InputState::CANCEL_FALLBACK_EVENTS,
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003227 "application handled a non-fallback event, "
3228 "canceling all fallback events");
3229 connection->originalKeyCodeForFallback = -1;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003230 } else {
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003231 // If the application did not handle a non-fallback key, first check
3232 // that we are in a good state to handle the fallback key. Then ask
3233 // the policy what to do with it.
3234 if (connection->originalKeyCodeForFallback < 0) {
3235 if (keyEntry->action != AKEY_EVENT_ACTION_DOWN
3236 || keyEntry->repeatCount != 0) {
3237#if DEBUG_OUTBOUND_EVENT_DETAILS
3238 LOGD("Unhandled key event: Skipping fallback since this "
3239 "is not an initial down. "
3240 "keyCode=%d, action=%d, repeatCount=%d",
3241 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount);
3242#endif
3243 goto SkipFallback;
3244 }
3245
3246 // Start handling the fallback key on DOWN.
3247 connection->originalKeyCodeForFallback = keyEntry->keyCode;
3248 } else {
3249 if (keyEntry->keyCode != connection->originalKeyCodeForFallback) {
3250#if DEBUG_OUTBOUND_EVENT_DETAILS
3251 LOGD("Unhandled key event: Skipping fallback since there is "
3252 "already a different fallback in progress. "
3253 "keyCode=%d, originalKeyCodeForFallback=%d",
3254 keyEntry->keyCode, connection->originalKeyCodeForFallback);
3255#endif
3256 goto SkipFallback;
3257 }
3258
3259 // Finish handling the fallback key on UP.
3260 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
3261 connection->originalKeyCodeForFallback = -1;
3262 }
3263 }
3264
3265#if DEBUG_OUTBOUND_EVENT_DETAILS
3266 LOGD("Unhandled key event: Asking policy to perform fallback action. "
3267 "keyCode=%d, action=%d, repeatCount=%d",
3268 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount);
3269#endif
Jeff Brown49ed71d2010-12-06 17:13:33 -08003270 KeyEvent event;
3271 initializeKeyEvent(&event, keyEntry);
Jeff Brown3915bb82010-11-05 15:02:16 -07003272
Jeff Brown49ed71d2010-12-06 17:13:33 -08003273 mLock.unlock();
Jeff Brown3915bb82010-11-05 15:02:16 -07003274
Jeff Brown928e0542011-01-10 11:17:36 -08003275 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003276 &event, keyEntry->policyFlags, &event);
Jeff Brown3915bb82010-11-05 15:02:16 -07003277
Jeff Brown49ed71d2010-12-06 17:13:33 -08003278 mLock.lock();
3279
Jeff Brown00045a72010-12-09 18:10:30 -08003280 if (connection->status != Connection::STATUS_NORMAL) {
3281 return;
3282 }
3283
3284 assert(connection->outboundQueue.headSentinel.next == dispatchEntry);
3285
Jeff Brown49ed71d2010-12-06 17:13:33 -08003286 if (fallback) {
3287 // Restart the dispatch cycle using the fallback key.
3288 keyEntry->eventTime = event.getEventTime();
3289 keyEntry->deviceId = event.getDeviceId();
3290 keyEntry->source = event.getSource();
3291 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
3292 keyEntry->keyCode = event.getKeyCode();
3293 keyEntry->scanCode = event.getScanCode();
3294 keyEntry->metaState = event.getMetaState();
3295 keyEntry->repeatCount = event.getRepeatCount();
3296 keyEntry->downTime = event.getDownTime();
3297 keyEntry->syntheticRepeat = false;
3298
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003299#if DEBUG_OUTBOUND_EVENT_DETAILS
3300 LOGD("Unhandled key event: Dispatching fallback key. "
3301 "fallbackKeyCode=%d, fallbackMetaState=%08x",
3302 keyEntry->keyCode, keyEntry->metaState);
3303#endif
3304
Jeff Brown49ed71d2010-12-06 17:13:33 -08003305 dispatchEntry->inProgress = false;
3306 startDispatchCycleLocked(now(), connection);
3307 return;
3308 }
3309 }
3310 }
Jeff Brown3915bb82010-11-05 15:02:16 -07003311 }
3312 }
3313
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003314SkipFallback:
Jeff Brown3915bb82010-11-05 15:02:16 -07003315 startNextDispatchCycleLocked(now(), connection);
3316}
3317
Jeff Brownb88102f2010-09-08 11:49:43 -07003318void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3319 mLock.unlock();
3320
Jeff Brown01ce2e92010-09-26 22:20:12 -07003321 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07003322
3323 mLock.lock();
3324}
3325
Jeff Brown3915bb82010-11-05 15:02:16 -07003326void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
3327 event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3328 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3329 entry->downTime, entry->eventTime);
3330}
3331
Jeff Brown519e0242010-09-15 15:18:56 -07003332void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3333 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3334 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07003335}
3336
3337void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003338 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003339 dumpDispatchStateLocked(dump);
3340}
3341
Jeff Brown9c3cda02010-06-15 01:31:58 -07003342
Jeff Brown519e0242010-09-15 15:18:56 -07003343// --- InputDispatcher::Queue ---
3344
3345template <typename T>
3346uint32_t InputDispatcher::Queue<T>::count() const {
3347 uint32_t result = 0;
3348 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3349 result += 1;
3350 }
3351 return result;
3352}
3353
3354
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003355// --- InputDispatcher::Allocator ---
3356
3357InputDispatcher::Allocator::Allocator() {
3358}
3359
Jeff Brown01ce2e92010-09-26 22:20:12 -07003360InputDispatcher::InjectionState*
3361InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3362 InjectionState* injectionState = mInjectionStatePool.alloc();
3363 injectionState->refCount = 1;
3364 injectionState->injectorPid = injectorPid;
3365 injectionState->injectorUid = injectorUid;
3366 injectionState->injectionIsAsync = false;
3367 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3368 injectionState->pendingForegroundDispatches = 0;
3369 return injectionState;
3370}
3371
Jeff Brown7fbdc842010-06-17 20:52:56 -07003372void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brownb6997262010-10-08 22:31:17 -07003373 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003374 entry->type = type;
3375 entry->refCount = 1;
3376 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07003377 entry->eventTime = eventTime;
Jeff Brownb6997262010-10-08 22:31:17 -07003378 entry->policyFlags = policyFlags;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003379 entry->injectionState = NULL;
3380}
3381
3382void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3383 if (entry->injectionState) {
3384 releaseInjectionState(entry->injectionState);
3385 entry->injectionState = NULL;
3386 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07003387}
3388
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003389InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07003390InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003391 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003392 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003393 return entry;
3394}
3395
Jeff Brown7fbdc842010-06-17 20:52:56 -07003396InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown58a2da82011-01-25 16:02:22 -08003397 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003398 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3399 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003400 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003401 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003402
3403 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003404 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003405 entry->action = action;
3406 entry->flags = flags;
3407 entry->keyCode = keyCode;
3408 entry->scanCode = scanCode;
3409 entry->metaState = metaState;
3410 entry->repeatCount = repeatCount;
3411 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003412 entry->syntheticRepeat = false;
3413 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003414 return entry;
3415}
3416
Jeff Brown7fbdc842010-06-17 20:52:56 -07003417InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown58a2da82011-01-25 16:02:22 -08003418 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003419 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3420 nsecs_t downTime, uint32_t pointerCount,
3421 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003422 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003423 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003424
3425 entry->eventTime = eventTime;
3426 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003427 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003428 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07003429 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003430 entry->metaState = metaState;
3431 entry->edgeFlags = edgeFlags;
3432 entry->xPrecision = xPrecision;
3433 entry->yPrecision = yPrecision;
3434 entry->downTime = downTime;
3435 entry->pointerCount = pointerCount;
3436 entry->firstSample.eventTime = eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003437 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003438 entry->lastSample = & entry->firstSample;
3439 for (uint32_t i = 0; i < pointerCount; i++) {
3440 entry->pointerIds[i] = pointerIds[i];
3441 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3442 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003443 return entry;
3444}
3445
3446InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07003447 EventEntry* eventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07003448 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003449 DispatchEntry* entry = mDispatchEntryPool.alloc();
3450 entry->eventEntry = eventEntry;
3451 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07003452 entry->targetFlags = targetFlags;
3453 entry->xOffset = xOffset;
3454 entry->yOffset = yOffset;
Jeff Brownb88102f2010-09-08 11:49:43 -07003455 entry->inProgress = false;
3456 entry->headMotionSample = NULL;
3457 entry->tailMotionSample = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003458 return entry;
3459}
3460
Jeff Brown9c3cda02010-06-15 01:31:58 -07003461InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3462 CommandEntry* entry = mCommandEntryPool.alloc();
3463 entry->command = command;
3464 return entry;
3465}
3466
Jeff Brown01ce2e92010-09-26 22:20:12 -07003467void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3468 injectionState->refCount -= 1;
3469 if (injectionState->refCount == 0) {
3470 mInjectionStatePool.free(injectionState);
3471 } else {
3472 assert(injectionState->refCount > 0);
3473 }
3474}
3475
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003476void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3477 switch (entry->type) {
3478 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3479 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3480 break;
3481 case EventEntry::TYPE_KEY:
3482 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3483 break;
3484 case EventEntry::TYPE_MOTION:
3485 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3486 break;
3487 default:
3488 assert(false);
3489 break;
3490 }
3491}
3492
3493void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3494 ConfigurationChangedEntry* entry) {
3495 entry->refCount -= 1;
3496 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003497 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003498 mConfigurationChangeEntryPool.free(entry);
3499 } else {
3500 assert(entry->refCount > 0);
3501 }
3502}
3503
3504void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3505 entry->refCount -= 1;
3506 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003507 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003508 mKeyEntryPool.free(entry);
3509 } else {
3510 assert(entry->refCount > 0);
3511 }
3512}
3513
3514void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3515 entry->refCount -= 1;
3516 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003517 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003518 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3519 MotionSample* next = sample->next;
3520 mMotionSamplePool.free(sample);
3521 sample = next;
3522 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003523 mMotionEntryPool.free(entry);
3524 } else {
3525 assert(entry->refCount > 0);
3526 }
3527}
3528
3529void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3530 releaseEventEntry(entry->eventEntry);
3531 mDispatchEntryPool.free(entry);
3532}
3533
Jeff Brown9c3cda02010-06-15 01:31:58 -07003534void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3535 mCommandEntryPool.free(entry);
3536}
3537
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003538void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003539 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003540 MotionSample* sample = mMotionSamplePool.alloc();
3541 sample->eventTime = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003542 uint32_t pointerCount = motionEntry->pointerCount;
3543 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003544 sample->pointerCoords[i] = pointerCoords[i];
3545 }
3546
3547 sample->next = NULL;
3548 motionEntry->lastSample->next = sample;
3549 motionEntry->lastSample = sample;
3550}
3551
Jeff Brown01ce2e92010-09-26 22:20:12 -07003552void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3553 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003554
Jeff Brown01ce2e92010-09-26 22:20:12 -07003555 keyEntry->dispatchInProgress = false;
3556 keyEntry->syntheticRepeat = false;
3557 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003558}
3559
3560
Jeff Brownae9fc032010-08-18 15:51:08 -07003561// --- InputDispatcher::MotionEntry ---
3562
3563uint32_t InputDispatcher::MotionEntry::countSamples() const {
3564 uint32_t count = 1;
3565 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3566 count += 1;
3567 }
3568 return count;
3569}
3570
Jeff Brownb88102f2010-09-08 11:49:43 -07003571
3572// --- InputDispatcher::InputState ---
3573
Jeff Brownb6997262010-10-08 22:31:17 -07003574InputDispatcher::InputState::InputState() {
Jeff Brownb88102f2010-09-08 11:49:43 -07003575}
3576
3577InputDispatcher::InputState::~InputState() {
3578}
3579
3580bool InputDispatcher::InputState::isNeutral() const {
3581 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3582}
3583
Jeff Browncc0c1592011-02-19 05:07:28 -08003584void InputDispatcher::InputState::trackEvent(
Jeff Brownb88102f2010-09-08 11:49:43 -07003585 const EventEntry* entry) {
3586 switch (entry->type) {
3587 case EventEntry::TYPE_KEY:
Jeff Browncc0c1592011-02-19 05:07:28 -08003588 trackKey(static_cast<const KeyEntry*>(entry));
3589 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07003590
3591 case EventEntry::TYPE_MOTION:
Jeff Browncc0c1592011-02-19 05:07:28 -08003592 trackMotion(static_cast<const MotionEntry*>(entry));
3593 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07003594 }
3595}
3596
Jeff Browncc0c1592011-02-19 05:07:28 -08003597void InputDispatcher::InputState::trackKey(
Jeff Brownb88102f2010-09-08 11:49:43 -07003598 const KeyEntry* entry) {
3599 int32_t action = entry->action;
3600 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3601 KeyMemento& memento = mKeyMementos.editItemAt(i);
3602 if (memento.deviceId == entry->deviceId
3603 && memento.source == entry->source
3604 && memento.keyCode == entry->keyCode
3605 && memento.scanCode == entry->scanCode) {
3606 switch (action) {
3607 case AKEY_EVENT_ACTION_UP:
3608 mKeyMementos.removeAt(i);
Jeff Browncc0c1592011-02-19 05:07:28 -08003609 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003610
3611 case AKEY_EVENT_ACTION_DOWN:
Jeff Browncc0c1592011-02-19 05:07:28 -08003612 mKeyMementos.removeAt(i);
3613 goto Found;
Jeff Brownb88102f2010-09-08 11:49:43 -07003614
3615 default:
Jeff Browncc0c1592011-02-19 05:07:28 -08003616 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003617 }
3618 }
3619 }
3620
Jeff Browncc0c1592011-02-19 05:07:28 -08003621Found:
3622 if (action == AKEY_EVENT_ACTION_DOWN) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003623 mKeyMementos.push();
3624 KeyMemento& memento = mKeyMementos.editTop();
3625 memento.deviceId = entry->deviceId;
3626 memento.source = entry->source;
3627 memento.keyCode = entry->keyCode;
3628 memento.scanCode = entry->scanCode;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003629 memento.flags = entry->flags;
Jeff Brownb88102f2010-09-08 11:49:43 -07003630 memento.downTime = entry->downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003631 }
3632}
3633
Jeff Browncc0c1592011-02-19 05:07:28 -08003634void InputDispatcher::InputState::trackMotion(
Jeff Brownb88102f2010-09-08 11:49:43 -07003635 const MotionEntry* entry) {
3636 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3637 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3638 MotionMemento& memento = mMotionMementos.editItemAt(i);
3639 if (memento.deviceId == entry->deviceId
3640 && memento.source == entry->source) {
3641 switch (action) {
3642 case AMOTION_EVENT_ACTION_UP:
3643 case AMOTION_EVENT_ACTION_CANCEL:
Jeff Browncc0c1592011-02-19 05:07:28 -08003644 case AMOTION_EVENT_ACTION_HOVER_MOVE:
Jeff Brownb88102f2010-09-08 11:49:43 -07003645 mMotionMementos.removeAt(i);
Jeff Browncc0c1592011-02-19 05:07:28 -08003646 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003647
3648 case AMOTION_EVENT_ACTION_DOWN:
Jeff Browncc0c1592011-02-19 05:07:28 -08003649 mMotionMementos.removeAt(i);
3650 goto Found;
Jeff Brownb88102f2010-09-08 11:49:43 -07003651
3652 case AMOTION_EVENT_ACTION_POINTER_UP:
Jeff Browncc0c1592011-02-19 05:07:28 -08003653 case AMOTION_EVENT_ACTION_POINTER_DOWN:
Jeff Brownb88102f2010-09-08 11:49:43 -07003654 case AMOTION_EVENT_ACTION_MOVE:
Jeff Browncc0c1592011-02-19 05:07:28 -08003655 memento.setPointers(entry);
3656 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003657
3658 default:
Jeff Browncc0c1592011-02-19 05:07:28 -08003659 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003660 }
3661 }
3662 }
3663
Jeff Browncc0c1592011-02-19 05:07:28 -08003664Found:
3665 if (action == AMOTION_EVENT_ACTION_DOWN) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003666 mMotionMementos.push();
3667 MotionMemento& memento = mMotionMementos.editTop();
3668 memento.deviceId = entry->deviceId;
3669 memento.source = entry->source;
3670 memento.xPrecision = entry->xPrecision;
3671 memento.yPrecision = entry->yPrecision;
3672 memento.downTime = entry->downTime;
3673 memento.setPointers(entry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003674 }
3675}
3676
3677void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3678 pointerCount = entry->pointerCount;
3679 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3680 pointerIds[i] = entry->pointerIds[i];
3681 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3682 }
3683}
3684
Jeff Brownb6997262010-10-08 22:31:17 -07003685void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3686 Allocator* allocator, Vector<EventEntry*>& outEvents,
3687 CancelationOptions options) {
3688 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003689 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003690 if (shouldCancelKey(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003691 outEvents.push(allocator->obtainKeyEntry(currentTime,
3692 memento.deviceId, memento.source, 0,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003693 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
Jeff Brownb6997262010-10-08 22:31:17 -07003694 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3695 mKeyMementos.removeAt(i);
3696 } else {
3697 i += 1;
3698 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003699 }
3700
Jeff Browna1160a72010-10-11 18:22:53 -07003701 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003702 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003703 if (shouldCancelMotion(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003704 outEvents.push(allocator->obtainMotionEntry(currentTime,
3705 memento.deviceId, memento.source, 0,
3706 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3707 memento.xPrecision, memento.yPrecision, memento.downTime,
3708 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3709 mMotionMementos.removeAt(i);
3710 } else {
3711 i += 1;
3712 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003713 }
3714}
3715
3716void InputDispatcher::InputState::clear() {
3717 mKeyMementos.clear();
3718 mMotionMementos.clear();
Jeff Brownb6997262010-10-08 22:31:17 -07003719}
3720
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003721void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3722 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3723 const MotionMemento& memento = mMotionMementos.itemAt(i);
3724 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3725 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3726 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3727 if (memento.deviceId == otherMemento.deviceId
3728 && memento.source == otherMemento.source) {
3729 other.mMotionMementos.removeAt(j);
3730 } else {
3731 j += 1;
3732 }
3733 }
3734 other.mMotionMementos.push(memento);
3735 }
3736 }
3737}
3738
Jeff Brown49ed71d2010-12-06 17:13:33 -08003739bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
Jeff Brownb6997262010-10-08 22:31:17 -07003740 CancelationOptions options) {
3741 switch (options) {
Jeff Brown49ed71d2010-12-06 17:13:33 -08003742 case CANCEL_ALL_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003743 case CANCEL_NON_POINTER_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003744 return true;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003745 case CANCEL_FALLBACK_EVENTS:
3746 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
3747 default:
3748 return false;
3749 }
3750}
3751
3752bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
3753 CancelationOptions options) {
3754 switch (options) {
3755 case CANCEL_ALL_EVENTS:
3756 return true;
3757 case CANCEL_POINTER_EVENTS:
3758 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
3759 case CANCEL_NON_POINTER_EVENTS:
3760 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
3761 default:
3762 return false;
Jeff Brownb6997262010-10-08 22:31:17 -07003763 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003764}
3765
3766
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003767// --- InputDispatcher::Connection ---
3768
Jeff Brown928e0542011-01-10 11:17:36 -08003769InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
3770 const sp<InputWindowHandle>& inputWindowHandle) :
3771 status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
3772 inputPublisher(inputChannel),
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003773 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX),
3774 originalKeyCodeForFallback(-1) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003775}
3776
3777InputDispatcher::Connection::~Connection() {
3778}
3779
3780status_t InputDispatcher::Connection::initialize() {
3781 return inputPublisher.initialize();
3782}
3783
Jeff Brown9c3cda02010-06-15 01:31:58 -07003784const char* InputDispatcher::Connection::getStatusLabel() const {
3785 switch (status) {
3786 case STATUS_NORMAL:
3787 return "NORMAL";
3788
3789 case STATUS_BROKEN:
3790 return "BROKEN";
3791
Jeff Brown9c3cda02010-06-15 01:31:58 -07003792 case STATUS_ZOMBIE:
3793 return "ZOMBIE";
3794
3795 default:
3796 return "UNKNOWN";
3797 }
3798}
3799
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003800InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3801 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07003802 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3803 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003804 if (dispatchEntry->eventEntry == eventEntry) {
3805 return dispatchEntry;
3806 }
3807 }
3808 return NULL;
3809}
3810
Jeff Brownb88102f2010-09-08 11:49:43 -07003811
Jeff Brown9c3cda02010-06-15 01:31:58 -07003812// --- InputDispatcher::CommandEntry ---
3813
Jeff Brownb88102f2010-09-08 11:49:43 -07003814InputDispatcher::CommandEntry::CommandEntry() :
3815 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003816}
3817
3818InputDispatcher::CommandEntry::~CommandEntry() {
3819}
3820
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003821
Jeff Brown01ce2e92010-09-26 22:20:12 -07003822// --- InputDispatcher::TouchState ---
3823
3824InputDispatcher::TouchState::TouchState() :
Jeff Brown58a2da82011-01-25 16:02:22 -08003825 down(false), split(false), deviceId(-1), source(0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003826}
3827
3828InputDispatcher::TouchState::~TouchState() {
3829}
3830
3831void InputDispatcher::TouchState::reset() {
3832 down = false;
3833 split = false;
Jeff Brown95712852011-01-04 19:41:59 -08003834 deviceId = -1;
Jeff Brown58a2da82011-01-25 16:02:22 -08003835 source = 0;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003836 windows.clear();
3837}
3838
3839void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3840 down = other.down;
3841 split = other.split;
Jeff Brown95712852011-01-04 19:41:59 -08003842 deviceId = other.deviceId;
Jeff Brown58a2da82011-01-25 16:02:22 -08003843 source = other.source;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003844 windows.clear();
3845 windows.appendVector(other.windows);
3846}
3847
3848void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3849 int32_t targetFlags, BitSet32 pointerIds) {
3850 if (targetFlags & InputTarget::FLAG_SPLIT) {
3851 split = true;
3852 }
3853
3854 for (size_t i = 0; i < windows.size(); i++) {
3855 TouchedWindow& touchedWindow = windows.editItemAt(i);
3856 if (touchedWindow.window == window) {
3857 touchedWindow.targetFlags |= targetFlags;
3858 touchedWindow.pointerIds.value |= pointerIds.value;
3859 return;
3860 }
3861 }
3862
3863 windows.push();
3864
3865 TouchedWindow& touchedWindow = windows.editTop();
3866 touchedWindow.window = window;
3867 touchedWindow.targetFlags = targetFlags;
3868 touchedWindow.pointerIds = pointerIds;
3869 touchedWindow.channel = window->inputChannel;
3870}
3871
3872void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3873 for (size_t i = 0 ; i < windows.size(); ) {
3874 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3875 windows.removeAt(i);
3876 } else {
3877 i += 1;
3878 }
3879 }
3880}
3881
3882const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3883 for (size_t i = 0; i < windows.size(); i++) {
3884 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3885 return windows[i].window;
3886 }
3887 }
3888 return NULL;
3889}
3890
3891
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003892// --- InputDispatcherThread ---
3893
3894InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3895 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3896}
3897
3898InputDispatcherThread::~InputDispatcherThread() {
3899}
3900
3901bool InputDispatcherThread::threadLoop() {
3902 mDispatcher->dispatchOnce();
3903 return true;
3904}
3905
3906} // namespace android