blob: 19295e6d77ca148ec683044826f4e3e340244777 [file] [log] [blame]
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jeff Brown46b9ac02010-04-22 18:58:52 -070017#define LOG_TAG "InputDispatcher"
18
19//#define LOG_NDEBUG 0
20
21// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070022#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070023
24// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070025#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070026
27// Log debug messages about batching.
Jeff Brown349703e2010-06-22 01:27:15 -070028#define DEBUG_BATCHING 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070029
30// Log debug messages about the dispatch cycle.
Jeff Brown349703e2010-06-22 01:27:15 -070031#define DEBUG_DISPATCH_CYCLE 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070032
Jeff Brown9c3cda02010-06-15 01:31:58 -070033// Log debug messages about registrations.
Jeff Brown349703e2010-06-22 01:27:15 -070034#define DEBUG_REGISTRATION 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070035
Jeff Brown46b9ac02010-04-22 18:58:52 -070036// Log debug messages about performance statistics.
Jeff Brown349703e2010-06-22 01:27:15 -070037#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070038
Jeff Brown7fbdc842010-06-17 20:52:56 -070039// Log debug messages about input event injection.
Jeff Brown349703e2010-06-22 01:27:15 -070040#define DEBUG_INJECTION 0
Jeff Brown7fbdc842010-06-17 20:52:56 -070041
Jeff Brownae9fc032010-08-18 15:51:08 -070042// Log debug messages about input event throttling.
43#define DEBUG_THROTTLING 0
44
Jeff Brownb88102f2010-09-08 11:49:43 -070045// Log debug messages about input focus tracking.
46#define DEBUG_FOCUS 0
47
48// Log debug messages about the app switch latency optimization.
49#define DEBUG_APP_SWITCH 0
50
Jeff Brownb4ff35d2011-01-02 16:37:43 -080051#include "InputDispatcher.h"
52
Jeff Brown46b9ac02010-04-22 18:58:52 -070053#include <cutils/log.h>
Jeff Brownb88102f2010-09-08 11:49:43 -070054#include <ui/PowerManager.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070055
56#include <stddef.h>
57#include <unistd.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070058#include <errno.h>
59#include <limits.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070060
Jeff Brownf2f48712010-10-01 17:46:21 -070061#define INDENT " "
62#define INDENT2 " "
63
Jeff Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -0700219
220 while (mConnectionsByReceiveFd.size() != 0) {
221 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
222 }
Jeff Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -0700228
Jeff Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -0700236 }
Jeff Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -0700644 }
Jeff Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -0700703}
704
Jeff Brownb88102f2010-09-08 11:49:43 -0700705bool InputDispatcher::dispatchConfigurationChangedLocked(
706 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -0700916 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
917 }
918#endif
Jeff Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -0700925 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700926 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -0700945 inputTarget.inputChannel->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -0700946#endif
Jeff Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -07001788
1789 // Apply target flags.
1790 int32_t action = keyEntry->action;
1791 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -07001900 connection->lastDispatchTime = currentTime;
1901
Jeff Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -07001919 return;
1920 }
1921
Jeff Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -07001986
Jeff Brownb6997262010-10-08 22:31:17 -07001987 // Notify other system components.
1988 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001989 }
Jeff Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -07002015 }
2016
Jeff Brown7fbdc842010-06-17 20:52:56 -07002017 nsecs_t currentTime = now();
Jeff Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -07002026 }
2027
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002028 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-04-22 18:58:52 -07002216#endif
2217
Jeff Brownb88102f2010-09-08 11:49:43 -07002218 bool needWake;
Jeff Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 Brown46b9ac02010-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 }
Jeff Brown924c4d42011-03-07 16:40:47 -08002248 if (policyFlags & POLICY_FLAG_ALT) {
2249 metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON;
2250 }
2251 if (policyFlags & POLICY_FLAG_ALT_GR) {
2252 metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON;
2253 }
2254 if (policyFlags & POLICY_FLAG_SHIFT) {
2255 metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON;
2256 }
2257 if (policyFlags & POLICY_FLAG_CAPS_LOCK) {
2258 metaState |= AMETA_CAPS_LOCK_ON;
2259 }
2260 if (policyFlags & POLICY_FLAG_FUNCTION) {
2261 metaState |= AMETA_FUNCTION_ON;
2262 }
Jeff Brown1f245102010-11-18 20:53:46 -08002263
Jeff Browne20c9e02010-10-11 14:20:19 -07002264 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown1f245102010-11-18 20:53:46 -08002265
2266 KeyEvent event;
2267 event.initialize(deviceId, source, action, flags, keyCode, scanCode,
2268 metaState, 0, downTime, eventTime);
2269
2270 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
2271
2272 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2273 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2274 }
Jeff Brownb6997262010-10-08 22:31:17 -07002275
Jeff Brownb88102f2010-09-08 11:49:43 -07002276 bool needWake;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002277 { // acquire lock
2278 AutoMutex _l(mLock);
2279
Jeff Brown7fbdc842010-06-17 20:52:56 -07002280 int32_t repeatCount = 0;
2281 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002282 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002283 metaState, repeatCount, downTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002284
Jeff Brownb88102f2010-09-08 11:49:43 -07002285 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002286 } // release lock
2287
Jeff Brownb88102f2010-09-08 11:49:43 -07002288 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002289 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002290 }
2291}
2292
Jeff Brown58a2da82011-01-25 16:02:22 -08002293void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002294 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002295 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2296 float xPrecision, float yPrecision, nsecs_t downTime) {
2297#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002298 LOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002299 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2300 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2301 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002302 xPrecision, yPrecision, downTime);
2303 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002304 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002305 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002306 "orientation=%f",
Jeff Brown91c69ab2011-02-14 17:03:18 -08002307 i, pointerIds[i],
Jeff Brownebbd5d12011-02-17 13:01:34 -08002308 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2309 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2310 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2311 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2312 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2313 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2314 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2315 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2316 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Jeff Brown46b9ac02010-04-22 18:58:52 -07002317 }
2318#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002319 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2320 return;
2321 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002322
Jeff Browne20c9e02010-10-11 14:20:19 -07002323 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown56194eb2011-03-02 19:23:13 -08002324 mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002325
Jeff Brownb88102f2010-09-08 11:49:43 -07002326 bool needWake;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002327 { // acquire lock
2328 AutoMutex _l(mLock);
2329
2330 // Attempt batching and streaming of move events.
Jeff Browncc0c1592011-02-19 05:07:28 -08002331 if (action == AMOTION_EVENT_ACTION_MOVE
2332 || action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002333 // BATCHING CASE
2334 //
2335 // Try to append a move sample to the tail of the inbound queue for this device.
2336 // Give up if we encounter a non-move motion event for this device since that
2337 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002338 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2339 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002340 if (entry->type != EventEntry::TYPE_MOTION) {
2341 // Keep looking for motion events.
2342 continue;
2343 }
2344
2345 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
Jeff Brownefd32662011-03-08 15:13:06 -08002346 if (motionEntry->deviceId != deviceId
2347 || motionEntry->source != source) {
2348 // Keep looking for this device and source.
Jeff Brown46b9ac02010-04-22 18:58:52 -07002349 continue;
2350 }
2351
Jeff Browncc0c1592011-02-19 05:07:28 -08002352 if (motionEntry->action != action
Jeff Brown7fbdc842010-06-17 20:52:56 -07002353 || motionEntry->pointerCount != pointerCount
2354 || motionEntry->isInjected()) {
Jeff Brownefd32662011-03-08 15:13:06 -08002355 // Last motion event in the queue for this device and source is
2356 // not compatible for appending new samples. Stop here.
Jeff Brown46b9ac02010-04-22 18:58:52 -07002357 goto NoBatchingOrStreaming;
2358 }
2359
2360 // The last motion event is a move and is compatible for appending.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002361 // Do the batching magic.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002362 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002363#if DEBUG_BATCHING
2364 LOGD("Appended motion sample onto batch for most recent "
2365 "motion event for this device in the inbound queue.");
2366#endif
Jeff Brown9c3cda02010-06-15 01:31:58 -07002367 return; // done!
Jeff Brown46b9ac02010-04-22 18:58:52 -07002368 }
2369
2370 // STREAMING CASE
2371 //
2372 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002373 // Search the outbound queue for the current foreground targets to find a dispatched
2374 // motion event that is still in progress. If found, then, appen the new sample to
2375 // that event and push it out to all current targets. The logic in
2376 // prepareDispatchCycleLocked takes care of the case where some targets may
2377 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002378 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002379 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2380 const InputTarget& inputTarget = mCurrentInputTargets[i];
2381 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2382 // Skip non-foreground targets. We only want to stream if there is at
2383 // least one foreground target whose dispatch is still in progress.
2384 continue;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002385 }
Jeff Brown519e0242010-09-15 15:18:56 -07002386
2387 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2388 if (connectionIndex < 0) {
2389 // Connection must no longer be valid.
2390 continue;
2391 }
2392
2393 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2394 if (connection->outboundQueue.isEmpty()) {
2395 // This foreground target has an empty outbound queue.
2396 continue;
2397 }
2398
2399 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2400 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002401 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2402 || dispatchEntry->isSplit()) {
2403 // No motion event is being dispatched, or it is being split across
2404 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002405 continue;
2406 }
2407
2408 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2409 dispatchEntry->eventEntry);
Jeff Browncc0c1592011-02-19 05:07:28 -08002410 if (motionEntry->action != action
Jeff Brown519e0242010-09-15 15:18:56 -07002411 || motionEntry->deviceId != deviceId
Jeff Brown58a2da82011-01-25 16:02:22 -08002412 || motionEntry->source != source
Jeff Brown519e0242010-09-15 15:18:56 -07002413 || motionEntry->pointerCount != pointerCount
2414 || motionEntry->isInjected()) {
2415 // The motion event is not compatible with this move.
2416 continue;
2417 }
2418
2419 // Hurray! This foreground target is currently dispatching a move event
2420 // that we can stream onto. Append the motion sample and resume dispatch.
2421 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2422#if DEBUG_BATCHING
2423 LOGD("Appended motion sample onto batch for most recently dispatched "
2424 "motion event for this device in the outbound queues. "
2425 "Attempting to stream the motion sample.");
2426#endif
2427 nsecs_t currentTime = now();
2428 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2429 true /*resumeWithAppendedMotionSample*/);
2430
2431 runCommandsLockedInterruptible();
2432 return; // done!
Jeff Brown46b9ac02010-04-22 18:58:52 -07002433 }
2434 }
2435
2436NoBatchingOrStreaming:;
2437 }
2438
2439 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002440 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002441 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002442 xPrecision, yPrecision, downTime,
2443 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002444
Jeff Brownb88102f2010-09-08 11:49:43 -07002445 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002446 } // release lock
2447
Jeff Brownb88102f2010-09-08 11:49:43 -07002448 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002449 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002450 }
2451}
2452
Jeff Brownb6997262010-10-08 22:31:17 -07002453void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2454 uint32_t policyFlags) {
2455#if DEBUG_INBOUND_EVENT_DETAILS
2456 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2457 switchCode, switchValue, policyFlags);
2458#endif
2459
Jeff Browne20c9e02010-10-11 14:20:19 -07002460 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002461 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2462}
2463
Jeff Brown7fbdc842010-06-17 20:52:56 -07002464int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002465 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002466#if DEBUG_INBOUND_EVENT_DETAILS
2467 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002468 "syncMode=%d, timeoutMillis=%d",
2469 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002470#endif
2471
2472 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Browne20c9e02010-10-11 14:20:19 -07002473
2474 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2475 if (hasInjectionPermission(injectorPid, injectorUid)) {
2476 policyFlags |= POLICY_FLAG_TRUSTED;
2477 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002478
Jeff Brownb6997262010-10-08 22:31:17 -07002479 EventEntry* injectedEntry;
2480 switch (event->getType()) {
2481 case AINPUT_EVENT_TYPE_KEY: {
2482 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2483 int32_t action = keyEvent->getAction();
2484 if (! validateKeyEvent(action)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002485 return INPUT_EVENT_INJECTION_FAILED;
2486 }
2487
Jeff Brownb6997262010-10-08 22:31:17 -07002488 int32_t flags = keyEvent->getFlags();
Jeff Brown1f245102010-11-18 20:53:46 -08002489 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2490 policyFlags |= POLICY_FLAG_VIRTUAL;
2491 }
2492
2493 mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
2494
2495 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2496 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2497 }
Jeff Brown6ec402b2010-07-28 15:48:59 -07002498
Jeff Brownb6997262010-10-08 22:31:17 -07002499 mLock.lock();
Jeff Brown1f245102010-11-18 20:53:46 -08002500 injectedEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
2501 keyEvent->getDeviceId(), keyEvent->getSource(),
2502 policyFlags, action, flags,
2503 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
Jeff Brownb6997262010-10-08 22:31:17 -07002504 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2505 break;
2506 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002507
Jeff Brownb6997262010-10-08 22:31:17 -07002508 case AINPUT_EVENT_TYPE_MOTION: {
2509 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2510 int32_t action = motionEvent->getAction();
2511 size_t pointerCount = motionEvent->getPointerCount();
2512 const int32_t* pointerIds = motionEvent->getPointerIds();
2513 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2514 return INPUT_EVENT_INJECTION_FAILED;
2515 }
2516
2517 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown56194eb2011-03-02 19:23:13 -08002518 mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002519
2520 mLock.lock();
2521 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2522 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2523 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2524 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2525 action, motionEvent->getFlags(),
2526 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2527 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2528 motionEvent->getDownTime(), uint32_t(pointerCount),
2529 pointerIds, samplePointerCoords);
2530 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2531 sampleEventTimes += 1;
2532 samplePointerCoords += pointerCount;
2533 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2534 }
2535 injectedEntry = motionEntry;
2536 break;
2537 }
2538
2539 default:
2540 LOGW("Cannot inject event of type %d", event->getType());
2541 return INPUT_EVENT_INJECTION_FAILED;
2542 }
2543
2544 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2545 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2546 injectionState->injectionIsAsync = true;
2547 }
2548
2549 injectionState->refCount += 1;
2550 injectedEntry->injectionState = injectionState;
2551
2552 bool needWake = enqueueInboundEventLocked(injectedEntry);
2553 mLock.unlock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002554
Jeff Brownb88102f2010-09-08 11:49:43 -07002555 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002556 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002557 }
2558
2559 int32_t injectionResult;
2560 { // acquire lock
2561 AutoMutex _l(mLock);
2562
Jeff Brown6ec402b2010-07-28 15:48:59 -07002563 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2564 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2565 } else {
2566 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002567 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002568 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2569 break;
2570 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002571
Jeff Brown7fbdc842010-06-17 20:52:56 -07002572 nsecs_t remainingTimeout = endTime - now();
2573 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002574#if DEBUG_INJECTION
2575 LOGD("injectInputEvent - Timed out waiting for injection result "
2576 "to become available.");
2577#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002578 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2579 break;
2580 }
2581
Jeff Brown6ec402b2010-07-28 15:48:59 -07002582 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2583 }
2584
2585 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2586 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002587 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002588#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002589 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002590 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002591#endif
2592 nsecs_t remainingTimeout = endTime - now();
2593 if (remainingTimeout <= 0) {
2594#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002595 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002596 "dispatches to finish.");
2597#endif
2598 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2599 break;
2600 }
2601
2602 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2603 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002604 }
2605 }
2606
Jeff Brown01ce2e92010-09-26 22:20:12 -07002607 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002608 } // release lock
2609
Jeff Brown6ec402b2010-07-28 15:48:59 -07002610#if DEBUG_INJECTION
2611 LOGD("injectInputEvent - Finished with result %d. "
2612 "injectorPid=%d, injectorUid=%d",
2613 injectionResult, injectorPid, injectorUid);
2614#endif
2615
Jeff Brown7fbdc842010-06-17 20:52:56 -07002616 return injectionResult;
2617}
2618
Jeff Brownb6997262010-10-08 22:31:17 -07002619bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2620 return injectorUid == 0
2621 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2622}
2623
Jeff Brown7fbdc842010-06-17 20:52:56 -07002624void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002625 InjectionState* injectionState = entry->injectionState;
2626 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002627#if DEBUG_INJECTION
2628 LOGD("Setting input event injection result to %d. "
2629 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002630 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002631#endif
2632
Jeff Brown01ce2e92010-09-26 22:20:12 -07002633 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002634 // Log the outcome since the injector did not wait for the injection result.
2635 switch (injectionResult) {
2636 case INPUT_EVENT_INJECTION_SUCCEEDED:
2637 LOGV("Asynchronous input event injection succeeded.");
2638 break;
2639 case INPUT_EVENT_INJECTION_FAILED:
2640 LOGW("Asynchronous input event injection failed.");
2641 break;
2642 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2643 LOGW("Asynchronous input event injection permission denied.");
2644 break;
2645 case INPUT_EVENT_INJECTION_TIMED_OUT:
2646 LOGW("Asynchronous input event injection timed out.");
2647 break;
2648 }
2649 }
2650
Jeff Brown01ce2e92010-09-26 22:20:12 -07002651 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002652 mInjectionResultAvailableCondition.broadcast();
2653 }
2654}
2655
Jeff Brown01ce2e92010-09-26 22:20:12 -07002656void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2657 InjectionState* injectionState = entry->injectionState;
2658 if (injectionState) {
2659 injectionState->pendingForegroundDispatches += 1;
2660 }
2661}
2662
Jeff Brown519e0242010-09-15 15:18:56 -07002663void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002664 InjectionState* injectionState = entry->injectionState;
2665 if (injectionState) {
2666 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002667
Jeff Brown01ce2e92010-09-26 22:20:12 -07002668 if (injectionState->pendingForegroundDispatches == 0) {
2669 mInjectionSyncFinishedCondition.broadcast();
2670 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002671 }
2672}
2673
Jeff Brown01ce2e92010-09-26 22:20:12 -07002674const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2675 for (size_t i = 0; i < mWindows.size(); i++) {
2676 const InputWindow* window = & mWindows[i];
2677 if (window->inputChannel == inputChannel) {
2678 return window;
2679 }
2680 }
2681 return NULL;
2682}
2683
Jeff Brownb88102f2010-09-08 11:49:43 -07002684void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2685#if DEBUG_FOCUS
2686 LOGD("setInputWindows");
2687#endif
2688 { // acquire lock
2689 AutoMutex _l(mLock);
2690
Jeff Brown01ce2e92010-09-26 22:20:12 -07002691 // Clear old window pointers.
Jeff Brownb6997262010-10-08 22:31:17 -07002692 sp<InputChannel> oldFocusedWindowChannel;
2693 if (mFocusedWindow) {
2694 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2695 mFocusedWindow = NULL;
2696 }
2697
Jeff Brownb88102f2010-09-08 11:49:43 -07002698 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002699
2700 // Loop over new windows and rebuild the necessary window pointers for
2701 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002702 mWindows.appendVector(inputWindows);
2703
2704 size_t numWindows = mWindows.size();
2705 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002706 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002707 if (window->hasFocus) {
2708 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002709 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002710 }
2711 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002712
Jeff Brownb6997262010-10-08 22:31:17 -07002713 if (oldFocusedWindowChannel != NULL) {
2714 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2715#if DEBUG_FOCUS
2716 LOGD("Focus left window: %s",
2717 oldFocusedWindowChannel->getName().string());
2718#endif
2719 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2720 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2721 oldFocusedWindowChannel.clear();
2722 }
2723 }
2724 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2725#if DEBUG_FOCUS
2726 LOGD("Focus entered window: %s",
2727 mFocusedWindow->inputChannel->getName().string());
2728#endif
2729 }
2730
Jeff Brown01ce2e92010-09-26 22:20:12 -07002731 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2732 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2733 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2734 if (window) {
2735 touchedWindow.window = window;
2736 i += 1;
2737 } else {
Jeff Brownb6997262010-10-08 22:31:17 -07002738#if DEBUG_FOCUS
2739 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2740#endif
Jeff Brownb6997262010-10-08 22:31:17 -07002741 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2742 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownaf48cae2010-10-15 16:20:51 -07002743 mTouchState.windows.removeAt(i);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002744 }
2745 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002746
Jeff Brownb88102f2010-09-08 11:49:43 -07002747#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002748 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002749#endif
2750 } // release lock
2751
2752 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002753 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002754}
2755
2756void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2757#if DEBUG_FOCUS
2758 LOGD("setFocusedApplication");
2759#endif
2760 { // acquire lock
2761 AutoMutex _l(mLock);
2762
2763 releaseFocusedApplicationLocked();
2764
2765 if (inputApplication) {
2766 mFocusedApplicationStorage = *inputApplication;
2767 mFocusedApplication = & mFocusedApplicationStorage;
2768 }
2769
2770#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002771 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002772#endif
2773 } // release lock
2774
2775 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002776 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002777}
2778
2779void InputDispatcher::releaseFocusedApplicationLocked() {
2780 if (mFocusedApplication) {
2781 mFocusedApplication = NULL;
Jeff Brown928e0542011-01-10 11:17:36 -08002782 mFocusedApplicationStorage.inputApplicationHandle.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -07002783 }
2784}
2785
2786void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2787#if DEBUG_FOCUS
2788 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2789#endif
2790
2791 bool changed;
2792 { // acquire lock
2793 AutoMutex _l(mLock);
2794
2795 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brown120a4592010-10-27 18:43:51 -07002796 if (mDispatchFrozen && !frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002797 resetANRTimeoutsLocked();
2798 }
2799
Jeff Brown120a4592010-10-27 18:43:51 -07002800 if (mDispatchEnabled && !enabled) {
2801 resetAndDropEverythingLocked("dispatcher is being disabled");
2802 }
2803
Jeff Brownb88102f2010-09-08 11:49:43 -07002804 mDispatchEnabled = enabled;
2805 mDispatchFrozen = frozen;
2806 changed = true;
2807 } else {
2808 changed = false;
2809 }
2810
2811#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002812 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002813#endif
2814 } // release lock
2815
2816 if (changed) {
2817 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002818 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002819 }
2820}
2821
Jeff Browne6504122010-09-27 14:52:15 -07002822bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2823 const sp<InputChannel>& toChannel) {
2824#if DEBUG_FOCUS
2825 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2826 fromChannel->getName().string(), toChannel->getName().string());
2827#endif
2828 { // acquire lock
2829 AutoMutex _l(mLock);
2830
2831 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2832 const InputWindow* toWindow = getWindowLocked(toChannel);
2833 if (! fromWindow || ! toWindow) {
2834#if DEBUG_FOCUS
2835 LOGD("Cannot transfer focus because from or to window not found.");
2836#endif
2837 return false;
2838 }
2839 if (fromWindow == toWindow) {
2840#if DEBUG_FOCUS
2841 LOGD("Trivial transfer to same window.");
2842#endif
2843 return true;
2844 }
2845
2846 bool found = false;
2847 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2848 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2849 if (touchedWindow.window == fromWindow) {
2850 int32_t oldTargetFlags = touchedWindow.targetFlags;
2851 BitSet32 pointerIds = touchedWindow.pointerIds;
2852
2853 mTouchState.windows.removeAt(i);
2854
Jeff Brown46e75292010-11-10 16:53:45 -08002855 int32_t newTargetFlags = oldTargetFlags
2856 & (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT);
Jeff Browne6504122010-09-27 14:52:15 -07002857 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2858
2859 found = true;
2860 break;
2861 }
2862 }
2863
2864 if (! found) {
2865#if DEBUG_FOCUS
2866 LOGD("Focus transfer failed because from window did not have focus.");
2867#endif
2868 return false;
2869 }
2870
Jeff Brown9c9f1a32010-10-11 18:32:20 -07002871 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2872 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2873 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2874 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2875 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2876
2877 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2878 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2879 InputState::CANCEL_POINTER_EVENTS,
2880 "transferring touch focus from this window to another window");
2881 }
2882
Jeff Browne6504122010-09-27 14:52:15 -07002883#if DEBUG_FOCUS
2884 logDispatchStateLocked();
2885#endif
2886 } // release lock
2887
2888 // Wake up poll loop since it may need to make new input dispatching choices.
2889 mLooper->wake();
2890 return true;
2891}
2892
Jeff Brown120a4592010-10-27 18:43:51 -07002893void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2894#if DEBUG_FOCUS
2895 LOGD("Resetting and dropping all events (%s).", reason);
2896#endif
2897
2898 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2899
2900 resetKeyRepeatLocked();
2901 releasePendingEventLocked();
2902 drainInboundQueueLocked();
2903 resetTargetsLocked();
2904
2905 mTouchState.reset();
2906}
2907
Jeff Brownb88102f2010-09-08 11:49:43 -07002908void InputDispatcher::logDispatchStateLocked() {
2909 String8 dump;
2910 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002911
2912 char* text = dump.lockBuffer(dump.size());
2913 char* start = text;
2914 while (*start != '\0') {
2915 char* end = strchr(start, '\n');
2916 if (*end == '\n') {
2917 *(end++) = '\0';
2918 }
2919 LOGD("%s", start);
2920 start = end;
2921 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002922}
2923
2924void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f48712010-10-01 17:46:21 -07002925 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2926 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07002927
2928 if (mFocusedApplication) {
Jeff Brownf2f48712010-10-01 17:46:21 -07002929 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002930 mFocusedApplication->name.string(),
2931 mFocusedApplication->dispatchingTimeout / 1000000.0);
2932 } else {
Jeff Brownf2f48712010-10-01 17:46:21 -07002933 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002934 }
Jeff Brownf2f48712010-10-01 17:46:21 -07002935 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002936 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f48712010-10-01 17:46:21 -07002937
2938 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2939 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
Jeff Brown95712852011-01-04 19:41:59 -08002940 dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
Jeff Brown58a2da82011-01-25 16:02:22 -08002941 dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
Jeff Brownf2f48712010-10-01 17:46:21 -07002942 if (!mTouchState.windows.isEmpty()) {
2943 dump.append(INDENT "TouchedWindows:\n");
2944 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2945 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2946 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2947 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2948 touchedWindow.targetFlags);
2949 }
2950 } else {
2951 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002952 }
2953
Jeff Brownf2f48712010-10-01 17:46:21 -07002954 if (!mWindows.isEmpty()) {
2955 dump.append(INDENT "Windows:\n");
2956 for (size_t i = 0; i < mWindows.size(); i++) {
2957 const InputWindow& window = mWindows[i];
2958 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2959 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2960 "frame=[%d,%d][%d,%d], "
Jeff Brownfbf09772011-01-16 14:06:57 -08002961 "touchableRegion=",
Jeff Brownf2f48712010-10-01 17:46:21 -07002962 i, window.name.string(),
2963 toString(window.paused),
2964 toString(window.hasFocus),
2965 toString(window.hasWallpaper),
2966 toString(window.visible),
2967 toString(window.canReceiveKeys),
2968 window.layoutParamsFlags, window.layoutParamsType,
2969 window.layer,
2970 window.frameLeft, window.frameTop,
Jeff Brownfbf09772011-01-16 14:06:57 -08002971 window.frameRight, window.frameBottom);
2972 dumpRegion(dump, window.touchableRegion);
2973 dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Jeff Brownf2f48712010-10-01 17:46:21 -07002974 window.ownerPid, window.ownerUid,
2975 window.dispatchingTimeout / 1000000.0);
2976 }
2977 } else {
2978 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002979 }
2980
Jeff Brownf2f48712010-10-01 17:46:21 -07002981 if (!mMonitoringChannels.isEmpty()) {
2982 dump.append(INDENT "MonitoringChannels:\n");
2983 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2984 const sp<InputChannel>& channel = mMonitoringChannels[i];
2985 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2986 }
2987 } else {
2988 dump.append(INDENT "MonitoringChannels: <none>\n");
2989 }
Jeff Brown519e0242010-09-15 15:18:56 -07002990
Jeff Brownf2f48712010-10-01 17:46:21 -07002991 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2992
2993 if (!mActiveConnections.isEmpty()) {
2994 dump.append(INDENT "ActiveConnections:\n");
2995 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2996 const Connection* connection = mActiveConnections[i];
Jeff Brown76860e32010-10-25 17:37:46 -07002997 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brownb6997262010-10-08 22:31:17 -07002998 "inputState.isNeutral=%s\n",
Jeff Brownf2f48712010-10-01 17:46:21 -07002999 i, connection->getInputChannelName(), connection->getStatusLabel(),
3000 connection->outboundQueue.count(),
Jeff Brownb6997262010-10-08 22:31:17 -07003001 toString(connection->inputState.isNeutral()));
Jeff Brownf2f48712010-10-01 17:46:21 -07003002 }
3003 } else {
3004 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003005 }
3006
3007 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f48712010-10-01 17:46:21 -07003008 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07003009 (mAppSwitchDueTime - now()) / 1000000.0);
3010 } else {
Jeff Brownf2f48712010-10-01 17:46:21 -07003011 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003012 }
3013}
3014
Jeff Brown928e0542011-01-10 11:17:36 -08003015status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
3016 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003017#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07003018 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
3019 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07003020#endif
3021
Jeff Brown46b9ac02010-04-22 18:58:52 -07003022 { // acquire lock
3023 AutoMutex _l(mLock);
3024
Jeff Brown519e0242010-09-15 15:18:56 -07003025 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003026 LOGW("Attempted to register already registered input channel '%s'",
3027 inputChannel->getName().string());
3028 return BAD_VALUE;
3029 }
3030
Jeff Brown928e0542011-01-10 11:17:36 -08003031 sp<Connection> connection = new Connection(inputChannel, inputWindowHandle);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003032 status_t status = connection->initialize();
3033 if (status) {
3034 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
3035 inputChannel->getName().string(), status);
3036 return status;
3037 }
3038
Jeff Brown2cbecea2010-08-17 15:59:26 -07003039 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac02010-04-22 18:58:52 -07003040 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003041
Jeff Brownb88102f2010-09-08 11:49:43 -07003042 if (monitor) {
3043 mMonitoringChannels.push(inputChannel);
3044 }
3045
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003046 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07003047
Jeff Brown9c3cda02010-06-15 01:31:58 -07003048 runCommandsLockedInterruptible();
Jeff Brown46b9ac02010-04-22 18:58:52 -07003049 } // release lock
Jeff Brown46b9ac02010-04-22 18:58:52 -07003050 return OK;
3051}
3052
3053status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003054#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07003055 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07003056#endif
3057
Jeff Brown46b9ac02010-04-22 18:58:52 -07003058 { // acquire lock
3059 AutoMutex _l(mLock);
3060
Jeff Brown519e0242010-09-15 15:18:56 -07003061 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003062 if (connectionIndex < 0) {
3063 LOGW("Attempted to unregister already unregistered input channel '%s'",
3064 inputChannel->getName().string());
3065 return BAD_VALUE;
3066 }
3067
3068 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3069 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
3070
3071 connection->status = Connection::STATUS_ZOMBIE;
3072
Jeff Brownb88102f2010-09-08 11:49:43 -07003073 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3074 if (mMonitoringChannels[i] == inputChannel) {
3075 mMonitoringChannels.removeAt(i);
3076 break;
3077 }
3078 }
3079
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003080 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07003081
Jeff Brown7fbdc842010-06-17 20:52:56 -07003082 nsecs_t currentTime = now();
Jeff Brownb6997262010-10-08 22:31:17 -07003083 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003084
3085 runCommandsLockedInterruptible();
Jeff Brown46b9ac02010-04-22 18:58:52 -07003086 } // release lock
3087
Jeff Brown46b9ac02010-04-22 18:58:52 -07003088 // Wake the poll loop because removing the connection may have changed the current
3089 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003090 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07003091 return OK;
3092}
3093
Jeff Brown519e0242010-09-15 15:18:56 -07003094ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07003095 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
3096 if (connectionIndex >= 0) {
3097 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3098 if (connection->inputChannel.get() == inputChannel.get()) {
3099 return connectionIndex;
3100 }
3101 }
3102
3103 return -1;
3104}
3105
Jeff Brown46b9ac02010-04-22 18:58:52 -07003106void InputDispatcher::activateConnectionLocked(Connection* connection) {
3107 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3108 if (mActiveConnections.itemAt(i) == connection) {
3109 return;
3110 }
3111 }
3112 mActiveConnections.add(connection);
3113}
3114
3115void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
3116 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3117 if (mActiveConnections.itemAt(i) == connection) {
3118 mActiveConnections.removeAt(i);
3119 return;
3120 }
3121 }
3122}
3123
Jeff Brown9c3cda02010-06-15 01:31:58 -07003124void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003125 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003126}
3127
Jeff Brown9c3cda02010-06-15 01:31:58 -07003128void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown3915bb82010-11-05 15:02:16 -07003129 nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
3130 CommandEntry* commandEntry = postCommandLocked(
3131 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
3132 commandEntry->connection = connection;
3133 commandEntry->handled = handled;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003134}
3135
Jeff Brown9c3cda02010-06-15 01:31:58 -07003136void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003137 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003138 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3139 connection->getInputChannelName());
3140
Jeff Brown9c3cda02010-06-15 01:31:58 -07003141 CommandEntry* commandEntry = postCommandLocked(
3142 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003143 commandEntry->connection = connection;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003144}
3145
Jeff Brown519e0242010-09-15 15:18:56 -07003146void InputDispatcher::onANRLocked(
3147 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
3148 nsecs_t eventTime, nsecs_t waitStartTime) {
3149 LOGI("Application is not responding: %s. "
3150 "%01.1fms since event, %01.1fms since wait started",
3151 getApplicationWindowLabelLocked(application, window).string(),
3152 (currentTime - eventTime) / 1000000.0,
3153 (currentTime - waitStartTime) / 1000000.0);
3154
3155 CommandEntry* commandEntry = postCommandLocked(
3156 & InputDispatcher::doNotifyANRLockedInterruptible);
3157 if (application) {
Jeff Brown928e0542011-01-10 11:17:36 -08003158 commandEntry->inputApplicationHandle = application->inputApplicationHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003159 }
3160 if (window) {
Jeff Brown928e0542011-01-10 11:17:36 -08003161 commandEntry->inputWindowHandle = window->inputWindowHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003162 commandEntry->inputChannel = window->inputChannel;
3163 }
3164}
3165
Jeff Brownb88102f2010-09-08 11:49:43 -07003166void InputDispatcher::doNotifyConfigurationChangedInterruptible(
3167 CommandEntry* commandEntry) {
3168 mLock.unlock();
3169
3170 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
3171
3172 mLock.lock();
3173}
3174
Jeff Brown9c3cda02010-06-15 01:31:58 -07003175void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
3176 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003177 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07003178
Jeff Brown7fbdc842010-06-17 20:52:56 -07003179 if (connection->status != Connection::STATUS_ZOMBIE) {
3180 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003181
Jeff Brown928e0542011-01-10 11:17:36 -08003182 mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003183
3184 mLock.lock();
3185 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07003186}
3187
Jeff Brown519e0242010-09-15 15:18:56 -07003188void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07003189 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07003190 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003191
Jeff Brown519e0242010-09-15 15:18:56 -07003192 nsecs_t newTimeout = mPolicy->notifyANR(
Jeff Brown928e0542011-01-10 11:17:36 -08003193 commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003194
Jeff Brown519e0242010-09-15 15:18:56 -07003195 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07003196
Jeff Brown519e0242010-09-15 15:18:56 -07003197 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003198}
3199
Jeff Brownb88102f2010-09-08 11:49:43 -07003200void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3201 CommandEntry* commandEntry) {
3202 KeyEntry* entry = commandEntry->keyEntry;
Jeff Brown1f245102010-11-18 20:53:46 -08003203
3204 KeyEvent event;
3205 initializeKeyEvent(&event, entry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003206
3207 mLock.unlock();
3208
Jeff Brown928e0542011-01-10 11:17:36 -08003209 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
Jeff Brown1f245102010-11-18 20:53:46 -08003210 &event, entry->policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -07003211
3212 mLock.lock();
3213
3214 entry->interceptKeyResult = consumed
3215 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
3216 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3217 mAllocator.releaseKeyEntry(entry);
3218}
3219
Jeff Brown3915bb82010-11-05 15:02:16 -07003220void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3221 CommandEntry* commandEntry) {
3222 sp<Connection> connection = commandEntry->connection;
3223 bool handled = commandEntry->handled;
3224
Jeff Brown49ed71d2010-12-06 17:13:33 -08003225 if (!connection->outboundQueue.isEmpty()) {
Jeff Brown3915bb82010-11-05 15:02:16 -07003226 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
3227 if (dispatchEntry->inProgress
3228 && dispatchEntry->hasForegroundTarget()
3229 && dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3230 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003231 if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
3232 if (handled) {
3233 // If the application handled a non-fallback key, then immediately
3234 // cancel all fallback keys previously dispatched to the application.
3235 // This behavior will prevent chording with fallback keys (so they cannot
3236 // be used as modifiers) but it will ensure that fallback keys do not
3237 // get stuck. This takes care of the case where the application does not handle
3238 // the original DOWN so we generate a fallback DOWN but it does handle
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003239 // the original UP in which case we want to send a fallback CANCEL.
Jeff Brown49ed71d2010-12-06 17:13:33 -08003240 synthesizeCancelationEventsForConnectionLocked(connection,
3241 InputState::CANCEL_FALLBACK_EVENTS,
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003242 "application handled a non-fallback event, "
3243 "canceling all fallback events");
3244 connection->originalKeyCodeForFallback = -1;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003245 } else {
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003246 // If the application did not handle a non-fallback key, first check
3247 // that we are in a good state to handle the fallback key. Then ask
3248 // the policy what to do with it.
3249 if (connection->originalKeyCodeForFallback < 0) {
3250 if (keyEntry->action != AKEY_EVENT_ACTION_DOWN
3251 || keyEntry->repeatCount != 0) {
3252#if DEBUG_OUTBOUND_EVENT_DETAILS
3253 LOGD("Unhandled key event: Skipping fallback since this "
3254 "is not an initial down. "
3255 "keyCode=%d, action=%d, repeatCount=%d",
3256 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount);
3257#endif
3258 goto SkipFallback;
3259 }
3260
3261 // Start handling the fallback key on DOWN.
3262 connection->originalKeyCodeForFallback = keyEntry->keyCode;
3263 } else {
3264 if (keyEntry->keyCode != connection->originalKeyCodeForFallback) {
3265#if DEBUG_OUTBOUND_EVENT_DETAILS
3266 LOGD("Unhandled key event: Skipping fallback since there is "
3267 "already a different fallback in progress. "
3268 "keyCode=%d, originalKeyCodeForFallback=%d",
3269 keyEntry->keyCode, connection->originalKeyCodeForFallback);
3270#endif
3271 goto SkipFallback;
3272 }
3273
3274 // Finish handling the fallback key on UP.
3275 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
3276 connection->originalKeyCodeForFallback = -1;
3277 }
3278 }
3279
3280#if DEBUG_OUTBOUND_EVENT_DETAILS
3281 LOGD("Unhandled key event: Asking policy to perform fallback action. "
3282 "keyCode=%d, action=%d, repeatCount=%d",
3283 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount);
3284#endif
Jeff Brown49ed71d2010-12-06 17:13:33 -08003285 KeyEvent event;
3286 initializeKeyEvent(&event, keyEntry);
Jeff Brown3915bb82010-11-05 15:02:16 -07003287
Jeff Brown49ed71d2010-12-06 17:13:33 -08003288 mLock.unlock();
Jeff Brown3915bb82010-11-05 15:02:16 -07003289
Jeff Brown928e0542011-01-10 11:17:36 -08003290 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003291 &event, keyEntry->policyFlags, &event);
Jeff Brown3915bb82010-11-05 15:02:16 -07003292
Jeff Brown49ed71d2010-12-06 17:13:33 -08003293 mLock.lock();
3294
Jeff Brown00045a72010-12-09 18:10:30 -08003295 if (connection->status != Connection::STATUS_NORMAL) {
3296 return;
3297 }
3298
3299 assert(connection->outboundQueue.headSentinel.next == dispatchEntry);
3300
Jeff Brown49ed71d2010-12-06 17:13:33 -08003301 if (fallback) {
3302 // Restart the dispatch cycle using the fallback key.
3303 keyEntry->eventTime = event.getEventTime();
3304 keyEntry->deviceId = event.getDeviceId();
3305 keyEntry->source = event.getSource();
3306 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
3307 keyEntry->keyCode = event.getKeyCode();
3308 keyEntry->scanCode = event.getScanCode();
3309 keyEntry->metaState = event.getMetaState();
3310 keyEntry->repeatCount = event.getRepeatCount();
3311 keyEntry->downTime = event.getDownTime();
3312 keyEntry->syntheticRepeat = false;
3313
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003314#if DEBUG_OUTBOUND_EVENT_DETAILS
3315 LOGD("Unhandled key event: Dispatching fallback key. "
3316 "fallbackKeyCode=%d, fallbackMetaState=%08x",
3317 keyEntry->keyCode, keyEntry->metaState);
3318#endif
3319
Jeff Brown49ed71d2010-12-06 17:13:33 -08003320 dispatchEntry->inProgress = false;
3321 startDispatchCycleLocked(now(), connection);
3322 return;
3323 }
3324 }
3325 }
Jeff Brown3915bb82010-11-05 15:02:16 -07003326 }
3327 }
3328
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003329SkipFallback:
Jeff Brown3915bb82010-11-05 15:02:16 -07003330 startNextDispatchCycleLocked(now(), connection);
3331}
3332
Jeff Brownb88102f2010-09-08 11:49:43 -07003333void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3334 mLock.unlock();
3335
Jeff Brown01ce2e92010-09-26 22:20:12 -07003336 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07003337
3338 mLock.lock();
3339}
3340
Jeff Brown3915bb82010-11-05 15:02:16 -07003341void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
3342 event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3343 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3344 entry->downTime, entry->eventTime);
3345}
3346
Jeff Brown519e0242010-09-15 15:18:56 -07003347void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3348 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3349 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07003350}
3351
3352void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f48712010-10-01 17:46:21 -07003353 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003354 dumpDispatchStateLocked(dump);
3355}
3356
Jeff Brown9c3cda02010-06-15 01:31:58 -07003357
Jeff Brown519e0242010-09-15 15:18:56 -07003358// --- InputDispatcher::Queue ---
3359
3360template <typename T>
3361uint32_t InputDispatcher::Queue<T>::count() const {
3362 uint32_t result = 0;
3363 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3364 result += 1;
3365 }
3366 return result;
3367}
3368
3369
Jeff Brown46b9ac02010-04-22 18:58:52 -07003370// --- InputDispatcher::Allocator ---
3371
3372InputDispatcher::Allocator::Allocator() {
3373}
3374
Jeff Brown01ce2e92010-09-26 22:20:12 -07003375InputDispatcher::InjectionState*
3376InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3377 InjectionState* injectionState = mInjectionStatePool.alloc();
3378 injectionState->refCount = 1;
3379 injectionState->injectorPid = injectorPid;
3380 injectionState->injectorUid = injectorUid;
3381 injectionState->injectionIsAsync = false;
3382 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3383 injectionState->pendingForegroundDispatches = 0;
3384 return injectionState;
3385}
3386
Jeff Brown7fbdc842010-06-17 20:52:56 -07003387void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brownb6997262010-10-08 22:31:17 -07003388 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003389 entry->type = type;
3390 entry->refCount = 1;
3391 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07003392 entry->eventTime = eventTime;
Jeff Brownb6997262010-10-08 22:31:17 -07003393 entry->policyFlags = policyFlags;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003394 entry->injectionState = NULL;
3395}
3396
3397void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3398 if (entry->injectionState) {
3399 releaseInjectionState(entry->injectionState);
3400 entry->injectionState = NULL;
3401 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07003402}
3403
Jeff Brown46b9ac02010-04-22 18:58:52 -07003404InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07003405InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003406 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003407 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003408 return entry;
3409}
3410
Jeff Brown7fbdc842010-06-17 20:52:56 -07003411InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown58a2da82011-01-25 16:02:22 -08003412 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003413 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3414 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003415 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003416 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003417
3418 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003419 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003420 entry->action = action;
3421 entry->flags = flags;
3422 entry->keyCode = keyCode;
3423 entry->scanCode = scanCode;
3424 entry->metaState = metaState;
3425 entry->repeatCount = repeatCount;
3426 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003427 entry->syntheticRepeat = false;
3428 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003429 return entry;
3430}
3431
Jeff Brown7fbdc842010-06-17 20:52:56 -07003432InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown58a2da82011-01-25 16:02:22 -08003433 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003434 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3435 nsecs_t downTime, uint32_t pointerCount,
3436 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003437 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003438 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003439
3440 entry->eventTime = eventTime;
3441 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003442 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003443 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07003444 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003445 entry->metaState = metaState;
3446 entry->edgeFlags = edgeFlags;
3447 entry->xPrecision = xPrecision;
3448 entry->yPrecision = yPrecision;
3449 entry->downTime = downTime;
3450 entry->pointerCount = pointerCount;
3451 entry->firstSample.eventTime = eventTime;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003452 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003453 entry->lastSample = & entry->firstSample;
3454 for (uint32_t i = 0; i < pointerCount; i++) {
3455 entry->pointerIds[i] = pointerIds[i];
3456 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3457 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07003458 return entry;
3459}
3460
3461InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07003462 EventEntry* eventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07003463 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003464 DispatchEntry* entry = mDispatchEntryPool.alloc();
3465 entry->eventEntry = eventEntry;
3466 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07003467 entry->targetFlags = targetFlags;
3468 entry->xOffset = xOffset;
3469 entry->yOffset = yOffset;
Jeff Brownb88102f2010-09-08 11:49:43 -07003470 entry->inProgress = false;
3471 entry->headMotionSample = NULL;
3472 entry->tailMotionSample = NULL;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003473 return entry;
3474}
3475
Jeff Brown9c3cda02010-06-15 01:31:58 -07003476InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3477 CommandEntry* entry = mCommandEntryPool.alloc();
3478 entry->command = command;
3479 return entry;
3480}
3481
Jeff Brown01ce2e92010-09-26 22:20:12 -07003482void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3483 injectionState->refCount -= 1;
3484 if (injectionState->refCount == 0) {
3485 mInjectionStatePool.free(injectionState);
3486 } else {
3487 assert(injectionState->refCount > 0);
3488 }
3489}
3490
Jeff Brown46b9ac02010-04-22 18:58:52 -07003491void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3492 switch (entry->type) {
3493 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3494 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3495 break;
3496 case EventEntry::TYPE_KEY:
3497 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3498 break;
3499 case EventEntry::TYPE_MOTION:
3500 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3501 break;
3502 default:
3503 assert(false);
3504 break;
3505 }
3506}
3507
3508void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3509 ConfigurationChangedEntry* entry) {
3510 entry->refCount -= 1;
3511 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003512 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003513 mConfigurationChangeEntryPool.free(entry);
3514 } else {
3515 assert(entry->refCount > 0);
3516 }
3517}
3518
3519void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3520 entry->refCount -= 1;
3521 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003522 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003523 mKeyEntryPool.free(entry);
3524 } else {
3525 assert(entry->refCount > 0);
3526 }
3527}
3528
3529void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3530 entry->refCount -= 1;
3531 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003532 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003533 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3534 MotionSample* next = sample->next;
3535 mMotionSamplePool.free(sample);
3536 sample = next;
3537 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07003538 mMotionEntryPool.free(entry);
3539 } else {
3540 assert(entry->refCount > 0);
3541 }
3542}
3543
3544void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3545 releaseEventEntry(entry->eventEntry);
3546 mDispatchEntryPool.free(entry);
3547}
3548
Jeff Brown9c3cda02010-06-15 01:31:58 -07003549void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3550 mCommandEntryPool.free(entry);
3551}
3552
Jeff Brown46b9ac02010-04-22 18:58:52 -07003553void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003554 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003555 MotionSample* sample = mMotionSamplePool.alloc();
3556 sample->eventTime = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003557 uint32_t pointerCount = motionEntry->pointerCount;
3558 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003559 sample->pointerCoords[i] = pointerCoords[i];
3560 }
3561
3562 sample->next = NULL;
3563 motionEntry->lastSample->next = sample;
3564 motionEntry->lastSample = sample;
3565}
3566
Jeff Brown01ce2e92010-09-26 22:20:12 -07003567void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3568 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003569
Jeff Brown01ce2e92010-09-26 22:20:12 -07003570 keyEntry->dispatchInProgress = false;
3571 keyEntry->syntheticRepeat = false;
3572 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003573}
3574
3575
Jeff Brownae9fc032010-08-18 15:51:08 -07003576// --- InputDispatcher::MotionEntry ---
3577
3578uint32_t InputDispatcher::MotionEntry::countSamples() const {
3579 uint32_t count = 1;
3580 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3581 count += 1;
3582 }
3583 return count;
3584}
3585
Jeff Brownb88102f2010-09-08 11:49:43 -07003586
3587// --- InputDispatcher::InputState ---
3588
Jeff Brownb6997262010-10-08 22:31:17 -07003589InputDispatcher::InputState::InputState() {
Jeff Brownb88102f2010-09-08 11:49:43 -07003590}
3591
3592InputDispatcher::InputState::~InputState() {
3593}
3594
3595bool InputDispatcher::InputState::isNeutral() const {
3596 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3597}
3598
Jeff Browncc0c1592011-02-19 05:07:28 -08003599void InputDispatcher::InputState::trackEvent(
Jeff Brownb88102f2010-09-08 11:49:43 -07003600 const EventEntry* entry) {
3601 switch (entry->type) {
3602 case EventEntry::TYPE_KEY:
Jeff Browncc0c1592011-02-19 05:07:28 -08003603 trackKey(static_cast<const KeyEntry*>(entry));
3604 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07003605
3606 case EventEntry::TYPE_MOTION:
Jeff Browncc0c1592011-02-19 05:07:28 -08003607 trackMotion(static_cast<const MotionEntry*>(entry));
3608 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07003609 }
3610}
3611
Jeff Browncc0c1592011-02-19 05:07:28 -08003612void InputDispatcher::InputState::trackKey(
Jeff Brownb88102f2010-09-08 11:49:43 -07003613 const KeyEntry* entry) {
3614 int32_t action = entry->action;
3615 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3616 KeyMemento& memento = mKeyMementos.editItemAt(i);
3617 if (memento.deviceId == entry->deviceId
3618 && memento.source == entry->source
3619 && memento.keyCode == entry->keyCode
3620 && memento.scanCode == entry->scanCode) {
3621 switch (action) {
3622 case AKEY_EVENT_ACTION_UP:
3623 mKeyMementos.removeAt(i);
Jeff Browncc0c1592011-02-19 05:07:28 -08003624 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003625
3626 case AKEY_EVENT_ACTION_DOWN:
Jeff Browncc0c1592011-02-19 05:07:28 -08003627 mKeyMementos.removeAt(i);
3628 goto Found;
Jeff Brownb88102f2010-09-08 11:49:43 -07003629
3630 default:
Jeff Browncc0c1592011-02-19 05:07:28 -08003631 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003632 }
3633 }
3634 }
3635
Jeff Browncc0c1592011-02-19 05:07:28 -08003636Found:
3637 if (action == AKEY_EVENT_ACTION_DOWN) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003638 mKeyMementos.push();
3639 KeyMemento& memento = mKeyMementos.editTop();
3640 memento.deviceId = entry->deviceId;
3641 memento.source = entry->source;
3642 memento.keyCode = entry->keyCode;
3643 memento.scanCode = entry->scanCode;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003644 memento.flags = entry->flags;
Jeff Brownb88102f2010-09-08 11:49:43 -07003645 memento.downTime = entry->downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003646 }
3647}
3648
Jeff Browncc0c1592011-02-19 05:07:28 -08003649void InputDispatcher::InputState::trackMotion(
Jeff Brownb88102f2010-09-08 11:49:43 -07003650 const MotionEntry* entry) {
3651 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3652 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3653 MotionMemento& memento = mMotionMementos.editItemAt(i);
3654 if (memento.deviceId == entry->deviceId
3655 && memento.source == entry->source) {
3656 switch (action) {
3657 case AMOTION_EVENT_ACTION_UP:
3658 case AMOTION_EVENT_ACTION_CANCEL:
Jeff Browncc0c1592011-02-19 05:07:28 -08003659 case AMOTION_EVENT_ACTION_HOVER_MOVE:
Jeff Brownb88102f2010-09-08 11:49:43 -07003660 mMotionMementos.removeAt(i);
Jeff Browncc0c1592011-02-19 05:07:28 -08003661 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003662
3663 case AMOTION_EVENT_ACTION_DOWN:
Jeff Browncc0c1592011-02-19 05:07:28 -08003664 mMotionMementos.removeAt(i);
3665 goto Found;
Jeff Brownb88102f2010-09-08 11:49:43 -07003666
3667 case AMOTION_EVENT_ACTION_POINTER_UP:
Jeff Browncc0c1592011-02-19 05:07:28 -08003668 case AMOTION_EVENT_ACTION_POINTER_DOWN:
Jeff Brownb88102f2010-09-08 11:49:43 -07003669 case AMOTION_EVENT_ACTION_MOVE:
Jeff Browncc0c1592011-02-19 05:07:28 -08003670 memento.setPointers(entry);
3671 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003672
3673 default:
Jeff Browncc0c1592011-02-19 05:07:28 -08003674 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003675 }
3676 }
3677 }
3678
Jeff Browncc0c1592011-02-19 05:07:28 -08003679Found:
3680 if (action == AMOTION_EVENT_ACTION_DOWN) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003681 mMotionMementos.push();
3682 MotionMemento& memento = mMotionMementos.editTop();
3683 memento.deviceId = entry->deviceId;
3684 memento.source = entry->source;
3685 memento.xPrecision = entry->xPrecision;
3686 memento.yPrecision = entry->yPrecision;
3687 memento.downTime = entry->downTime;
3688 memento.setPointers(entry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003689 }
3690}
3691
3692void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3693 pointerCount = entry->pointerCount;
3694 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3695 pointerIds[i] = entry->pointerIds[i];
3696 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3697 }
3698}
3699
Jeff Brownb6997262010-10-08 22:31:17 -07003700void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3701 Allocator* allocator, Vector<EventEntry*>& outEvents,
3702 CancelationOptions options) {
3703 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003704 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003705 if (shouldCancelKey(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003706 outEvents.push(allocator->obtainKeyEntry(currentTime,
3707 memento.deviceId, memento.source, 0,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003708 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
Jeff Brownb6997262010-10-08 22:31:17 -07003709 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3710 mKeyMementos.removeAt(i);
3711 } else {
3712 i += 1;
3713 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003714 }
3715
Jeff Browna1160a72010-10-11 18:22:53 -07003716 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003717 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003718 if (shouldCancelMotion(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003719 outEvents.push(allocator->obtainMotionEntry(currentTime,
3720 memento.deviceId, memento.source, 0,
3721 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3722 memento.xPrecision, memento.yPrecision, memento.downTime,
3723 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3724 mMotionMementos.removeAt(i);
3725 } else {
3726 i += 1;
3727 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003728 }
3729}
3730
3731void InputDispatcher::InputState::clear() {
3732 mKeyMementos.clear();
3733 mMotionMementos.clear();
Jeff Brownb6997262010-10-08 22:31:17 -07003734}
3735
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003736void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3737 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3738 const MotionMemento& memento = mMotionMementos.itemAt(i);
3739 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3740 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3741 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3742 if (memento.deviceId == otherMemento.deviceId
3743 && memento.source == otherMemento.source) {
3744 other.mMotionMementos.removeAt(j);
3745 } else {
3746 j += 1;
3747 }
3748 }
3749 other.mMotionMementos.push(memento);
3750 }
3751 }
3752}
3753
Jeff Brown49ed71d2010-12-06 17:13:33 -08003754bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
Jeff Brownb6997262010-10-08 22:31:17 -07003755 CancelationOptions options) {
3756 switch (options) {
Jeff Brown49ed71d2010-12-06 17:13:33 -08003757 case CANCEL_ALL_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003758 case CANCEL_NON_POINTER_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003759 return true;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003760 case CANCEL_FALLBACK_EVENTS:
3761 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
3762 default:
3763 return false;
3764 }
3765}
3766
3767bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
3768 CancelationOptions options) {
3769 switch (options) {
3770 case CANCEL_ALL_EVENTS:
3771 return true;
3772 case CANCEL_POINTER_EVENTS:
3773 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
3774 case CANCEL_NON_POINTER_EVENTS:
3775 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
3776 default:
3777 return false;
Jeff Brownb6997262010-10-08 22:31:17 -07003778 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003779}
3780
3781
Jeff Brown46b9ac02010-04-22 18:58:52 -07003782// --- InputDispatcher::Connection ---
3783
Jeff Brown928e0542011-01-10 11:17:36 -08003784InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
3785 const sp<InputWindowHandle>& inputWindowHandle) :
3786 status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
3787 inputPublisher(inputChannel),
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003788 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX),
3789 originalKeyCodeForFallback(-1) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003790}
3791
3792InputDispatcher::Connection::~Connection() {
3793}
3794
3795status_t InputDispatcher::Connection::initialize() {
3796 return inputPublisher.initialize();
3797}
3798
Jeff Brown9c3cda02010-06-15 01:31:58 -07003799const char* InputDispatcher::Connection::getStatusLabel() const {
3800 switch (status) {
3801 case STATUS_NORMAL:
3802 return "NORMAL";
3803
3804 case STATUS_BROKEN:
3805 return "BROKEN";
3806
Jeff Brown9c3cda02010-06-15 01:31:58 -07003807 case STATUS_ZOMBIE:
3808 return "ZOMBIE";
3809
3810 default:
3811 return "UNKNOWN";
3812 }
3813}
3814
Jeff Brown46b9ac02010-04-22 18:58:52 -07003815InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3816 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07003817 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3818 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003819 if (dispatchEntry->eventEntry == eventEntry) {
3820 return dispatchEntry;
3821 }
3822 }
3823 return NULL;
3824}
3825
Jeff Brownb88102f2010-09-08 11:49:43 -07003826
Jeff Brown9c3cda02010-06-15 01:31:58 -07003827// --- InputDispatcher::CommandEntry ---
3828
Jeff Brownb88102f2010-09-08 11:49:43 -07003829InputDispatcher::CommandEntry::CommandEntry() :
3830 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003831}
3832
3833InputDispatcher::CommandEntry::~CommandEntry() {
3834}
3835
Jeff Brown46b9ac02010-04-22 18:58:52 -07003836
Jeff Brown01ce2e92010-09-26 22:20:12 -07003837// --- InputDispatcher::TouchState ---
3838
3839InputDispatcher::TouchState::TouchState() :
Jeff Brown58a2da82011-01-25 16:02:22 -08003840 down(false), split(false), deviceId(-1), source(0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003841}
3842
3843InputDispatcher::TouchState::~TouchState() {
3844}
3845
3846void InputDispatcher::TouchState::reset() {
3847 down = false;
3848 split = false;
Jeff Brown95712852011-01-04 19:41:59 -08003849 deviceId = -1;
Jeff Brown58a2da82011-01-25 16:02:22 -08003850 source = 0;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003851 windows.clear();
3852}
3853
3854void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3855 down = other.down;
3856 split = other.split;
Jeff Brown95712852011-01-04 19:41:59 -08003857 deviceId = other.deviceId;
Jeff Brown58a2da82011-01-25 16:02:22 -08003858 source = other.source;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003859 windows.clear();
3860 windows.appendVector(other.windows);
3861}
3862
3863void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3864 int32_t targetFlags, BitSet32 pointerIds) {
3865 if (targetFlags & InputTarget::FLAG_SPLIT) {
3866 split = true;
3867 }
3868
3869 for (size_t i = 0; i < windows.size(); i++) {
3870 TouchedWindow& touchedWindow = windows.editItemAt(i);
3871 if (touchedWindow.window == window) {
3872 touchedWindow.targetFlags |= targetFlags;
3873 touchedWindow.pointerIds.value |= pointerIds.value;
3874 return;
3875 }
3876 }
3877
3878 windows.push();
3879
3880 TouchedWindow& touchedWindow = windows.editTop();
3881 touchedWindow.window = window;
3882 touchedWindow.targetFlags = targetFlags;
3883 touchedWindow.pointerIds = pointerIds;
3884 touchedWindow.channel = window->inputChannel;
3885}
3886
3887void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3888 for (size_t i = 0 ; i < windows.size(); ) {
3889 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3890 windows.removeAt(i);
3891 } else {
3892 i += 1;
3893 }
3894 }
3895}
3896
3897const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3898 for (size_t i = 0; i < windows.size(); i++) {
3899 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3900 return windows[i].window;
3901 }
3902 }
3903 return NULL;
3904}
3905
3906
Jeff Brown46b9ac02010-04-22 18:58:52 -07003907// --- InputDispatcherThread ---
3908
3909InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3910 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3911}
3912
3913InputDispatcherThread::~InputDispatcherThread() {
3914}
3915
3916bool InputDispatcherThread::threadLoop() {
3917 mDispatcher->dispatchOnce();
3918 return true;
3919}
3920
3921} // namespace android