blob: 5ea12c7ec61062d99efed87e1ffce694c5eaa36d [file] [log] [blame]
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070017#define LOG_TAG "InputDispatcher"
18
19//#define LOG_NDEBUG 0
20
21// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070022#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070023
24// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070025#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070026
27// Log debug messages about batching.
Jeff Brown349703e2010-06-22 01:27:15 -070028#define DEBUG_BATCHING 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070029
30// Log debug messages about the dispatch cycle.
Jeff Brown349703e2010-06-22 01:27:15 -070031#define DEBUG_DISPATCH_CYCLE 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070032
Jeff Brown9c3cda02010-06-15 01:31:58 -070033// Log debug messages about registrations.
Jeff Brown349703e2010-06-22 01:27:15 -070034#define DEBUG_REGISTRATION 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070035
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070036// Log debug messages about performance statistics.
Jeff Brown349703e2010-06-22 01:27:15 -070037#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070038
Jeff Brown7fbdc842010-06-17 20:52:56 -070039// Log debug messages about input event injection.
Jeff Brown349703e2010-06-22 01:27:15 -070040#define DEBUG_INJECTION 0
Jeff Brown7fbdc842010-06-17 20:52:56 -070041
Jeff Brownae9fc032010-08-18 15:51:08 -070042// Log debug messages about input event throttling.
43#define DEBUG_THROTTLING 0
44
Jeff Brownb88102f2010-09-08 11:49:43 -070045// Log debug messages about input focus tracking.
46#define DEBUG_FOCUS 0
47
48// Log debug messages about the app switch latency optimization.
49#define DEBUG_APP_SWITCH 0
50
Jeff Brownb4ff35d2011-01-02 16:37:43 -080051#include "InputDispatcher.h"
52
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070053#include <cutils/log.h>
Jeff Brownb88102f2010-09-08 11:49:43 -070054#include <ui/PowerManager.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070055
56#include <stddef.h>
57#include <unistd.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070058#include <errno.h>
59#include <limits.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070060
Jeff Brownf2f487182010-10-01 17:46:21 -070061#define INDENT " "
62#define INDENT2 " "
63
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070064namespace android {
65
Jeff Brownb88102f2010-09-08 11:49:43 -070066// Default input dispatching timeout if there is no focused application or paused window
67// from which to determine an appropriate dispatching timeout.
68const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
69
70// Amount of time to allow for all pending events to be processed when an app switch
71// key is on the way. This is used to preempt input dispatch and drop input events
72// when an application takes too long to respond and the user has pressed an app switch key.
73const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
74
Jeff Brown928e0542011-01-10 11:17:36 -080075// Amount of time to allow for an event to be dispatched (measured since its eventTime)
76// before considering it stale and dropping it.
77const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
78
Jeff Brown5ced76a2011-05-24 11:23:27 -070079// Motion samples that are received within this amount of time are simply coalesced
80// when batched instead of being appended. This is done because some drivers update
81// the location of pointers one at a time instead of all at once.
82// For example, when there are 10 fingers down, the input dispatcher may receive 10
83// samples in quick succession with only one finger's location changed in each sample.
84//
85// This value effectively imposes an upper bound on the touch sampling rate.
86// Touch sensors typically have a 50Hz - 200Hz sampling rate, so we expect distinct
87// samples to become available 5-20ms apart but individual finger reports can trickle
88// in over a period of 2-4ms or so.
89//
90// Empirical testing shows that a 2ms coalescing interval (500Hz) is not enough,
91// a 3ms coalescing interval (333Hz) works well most of the time and doesn't introduce
92// significant quantization noise on current hardware.
93const nsecs_t MOTION_SAMPLE_COALESCE_INTERVAL = 3 * 1000000LL; // 3ms, 333Hz
94
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070095
Jeff Brown7fbdc842010-06-17 20:52:56 -070096static inline nsecs_t now() {
97 return systemTime(SYSTEM_TIME_MONOTONIC);
98}
99
Jeff Brownb88102f2010-09-08 11:49:43 -0700100static inline const char* toString(bool value) {
101 return value ? "true" : "false";
102}
103
Jeff Brown01ce2e92010-09-26 22:20:12 -0700104static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
105 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
106 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
107}
108
109static bool isValidKeyAction(int32_t action) {
110 switch (action) {
111 case AKEY_EVENT_ACTION_DOWN:
112 case AKEY_EVENT_ACTION_UP:
113 return true;
114 default:
115 return false;
116 }
117}
118
119static bool validateKeyEvent(int32_t action) {
120 if (! isValidKeyAction(action)) {
121 LOGE("Key event has invalid action code 0x%x", action);
122 return false;
123 }
124 return true;
125}
126
Jeff Brownb6997262010-10-08 22:31:17 -0700127static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700128 switch (action & AMOTION_EVENT_ACTION_MASK) {
129 case AMOTION_EVENT_ACTION_DOWN:
130 case AMOTION_EVENT_ACTION_UP:
131 case AMOTION_EVENT_ACTION_CANCEL:
132 case AMOTION_EVENT_ACTION_MOVE:
Jeff Brown01ce2e92010-09-26 22:20:12 -0700133 case AMOTION_EVENT_ACTION_OUTSIDE:
Jeff Browncc0c1592011-02-19 05:07:28 -0800134 case AMOTION_EVENT_ACTION_HOVER_MOVE:
Jeff Brown33bbfd22011-02-24 20:55:35 -0800135 case AMOTION_EVENT_ACTION_SCROLL:
Jeff Brown01ce2e92010-09-26 22:20:12 -0700136 return true;
Jeff Brownb6997262010-10-08 22:31:17 -0700137 case AMOTION_EVENT_ACTION_POINTER_DOWN:
138 case AMOTION_EVENT_ACTION_POINTER_UP: {
139 int32_t index = getMotionEventActionPointerIndex(action);
140 return index >= 0 && size_t(index) < pointerCount;
141 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700142 default:
143 return false;
144 }
145}
146
147static bool validateMotionEvent(int32_t action, size_t pointerCount,
148 const int32_t* pointerIds) {
Jeff Brownb6997262010-10-08 22:31:17 -0700149 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700150 LOGE("Motion event has invalid action code 0x%x", action);
151 return false;
152 }
153 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
154 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
155 pointerCount, MAX_POINTERS);
156 return false;
157 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700158 BitSet32 pointerIdBits;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700159 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownc3db8582010-10-20 15:33:38 -0700160 int32_t id = pointerIds[i];
161 if (id < 0 || id > MAX_POINTER_ID) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700162 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
Jeff Brownc3db8582010-10-20 15:33:38 -0700163 id, MAX_POINTER_ID);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700164 return false;
165 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700166 if (pointerIdBits.hasBit(id)) {
167 LOGE("Motion event has duplicate pointer id %d", id);
168 return false;
169 }
170 pointerIdBits.markBit(id);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700171 }
172 return true;
173}
174
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400175static void scalePointerCoords(const PointerCoords* inCoords, size_t count, float scaleFactor,
176 PointerCoords* outCoords) {
177 for (size_t i = 0; i < count; i++) {
178 outCoords[i] = inCoords[i];
179 outCoords[i].scale(scaleFactor);
180 }
181}
182
Jeff Brownfbf09772011-01-16 14:06:57 -0800183static void dumpRegion(String8& dump, const SkRegion& region) {
184 if (region.isEmpty()) {
185 dump.append("<empty>");
186 return;
187 }
188
189 bool first = true;
190 for (SkRegion::Iterator it(region); !it.done(); it.next()) {
191 if (first) {
192 first = false;
193 } else {
194 dump.append("|");
195 }
196 const SkIRect& rect = it.rect();
197 dump.appendFormat("[%d,%d][%d,%d]", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
198 }
199}
200
Jeff Brownb88102f2010-09-08 11:49:43 -0700201
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700202// --- InputDispatcher ---
203
Jeff Brown9c3cda02010-06-15 01:31:58 -0700204InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Brownb88102f2010-09-08 11:49:43 -0700205 mPolicy(policy),
Jeff Brown928e0542011-01-10 11:17:36 -0800206 mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
207 mNextUnblockedEvent(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700208 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brown01ce2e92010-09-26 22:20:12 -0700209 mFocusedWindow(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700210 mFocusedApplication(NULL),
211 mCurrentInputTargetsValid(false),
212 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700213 mLooper = new Looper(false);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700214
Jeff Brownb88102f2010-09-08 11:49:43 -0700215 mInboundQueue.headSentinel.refCount = -1;
216 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
217 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700218
Jeff Brownb88102f2010-09-08 11:49:43 -0700219 mInboundQueue.tailSentinel.refCount = -1;
220 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
221 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700222
223 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700224
Jeff Brown214eaf42011-05-26 19:17:02 -0700225 policy->getDispatcherConfiguration(&mConfig);
226
227 mThrottleState.minTimeBetweenEvents = 1000000000LL / mConfig.maxEventsPerSecond;
Jeff Brownae9fc032010-08-18 15:51:08 -0700228 mThrottleState.lastDeviceId = -1;
229
230#if DEBUG_THROTTLING
231 mThrottleState.originalSampleCount = 0;
Jeff Brown214eaf42011-05-26 19:17:02 -0700232 LOGD("Throttling - Max events per second = %d", mConfig.maxEventsPerSecond);
Jeff Brownae9fc032010-08-18 15:51:08 -0700233#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700234}
235
236InputDispatcher::~InputDispatcher() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700237 { // acquire lock
238 AutoMutex _l(mLock);
239
240 resetKeyRepeatLocked();
Jeff Brown54a18252010-09-16 14:07:33 -0700241 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700242 drainInboundQueueLocked();
243 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700244
245 while (mConnectionsByReceiveFd.size() != 0) {
246 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
247 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700248}
249
250void InputDispatcher::dispatchOnce() {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700251 nsecs_t nextWakeupTime = LONG_LONG_MAX;
252 { // acquire lock
253 AutoMutex _l(mLock);
Jeff Brown214eaf42011-05-26 19:17:02 -0700254 dispatchOnceInnerLocked(&nextWakeupTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700255
Jeff Brownb88102f2010-09-08 11:49:43 -0700256 if (runCommandsLockedInterruptible()) {
257 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700258 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700259 } // release lock
260
Jeff Brownb88102f2010-09-08 11:49:43 -0700261 // Wait for callback or timeout or wake. (make sure we round up, not down)
262 nsecs_t currentTime = now();
Jeff Brown68d60752011-03-17 01:34:19 -0700263 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700264 mLooper->pollOnce(timeoutMillis);
Jeff Brownb88102f2010-09-08 11:49:43 -0700265}
266
Jeff Brown214eaf42011-05-26 19:17:02 -0700267void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700268 nsecs_t currentTime = now();
269
270 // Reset the key repeat timer whenever we disallow key events, even if the next event
271 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
272 // out of sleep.
Jeff Brown214eaf42011-05-26 19:17:02 -0700273 if (!mPolicy->isKeyRepeatEnabled()) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700274 resetKeyRepeatLocked();
275 }
276
Jeff Brownb88102f2010-09-08 11:49:43 -0700277 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
278 if (mDispatchFrozen) {
279#if DEBUG_FOCUS
280 LOGD("Dispatch frozen. Waiting some more.");
281#endif
282 return;
283 }
284
285 // Optimize latency of app switches.
286 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
287 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
288 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
289 if (mAppSwitchDueTime < *nextWakeupTime) {
290 *nextWakeupTime = mAppSwitchDueTime;
291 }
292
Jeff Brownb88102f2010-09-08 11:49:43 -0700293 // Ready to start a new event.
294 // If we don't already have a pending event, go grab one.
295 if (! mPendingEvent) {
296 if (mInboundQueue.isEmpty()) {
297 if (isAppSwitchDue) {
298 // The inbound queue is empty so the app switch key we were waiting
299 // for will never arrive. Stop waiting for it.
300 resetPendingAppSwitchLocked(false);
301 isAppSwitchDue = false;
302 }
303
304 // Synthesize a key repeat if appropriate.
305 if (mKeyRepeatState.lastKeyEntry) {
306 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
Jeff Brown214eaf42011-05-26 19:17:02 -0700307 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700308 } else {
309 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
310 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
311 }
312 }
313 }
314 if (! mPendingEvent) {
315 return;
316 }
317 } else {
318 // Inbound queue has at least one entry.
319 EventEntry* entry = mInboundQueue.headSentinel.next;
320
321 // Throttle the entry if it is a move event and there are no
322 // other events behind it in the queue. Due to movement batching, additional
323 // samples may be appended to this event by the time the throttling timeout
324 // expires.
325 // TODO Make this smarter and consider throttling per device independently.
Jeff Brownb6997262010-10-08 22:31:17 -0700326 if (entry->type == EventEntry::TYPE_MOTION
327 && !isAppSwitchDue
328 && mDispatchEnabled
329 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
330 && !entry->isInjected()) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700331 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
332 int32_t deviceId = motionEntry->deviceId;
333 uint32_t source = motionEntry->source;
334 if (! isAppSwitchDue
335 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
Jeff Browncc0c1592011-02-19 05:07:28 -0800336 && (motionEntry->action == AMOTION_EVENT_ACTION_MOVE
337 || motionEntry->action == AMOTION_EVENT_ACTION_HOVER_MOVE)
Jeff Brownb88102f2010-09-08 11:49:43 -0700338 && deviceId == mThrottleState.lastDeviceId
339 && source == mThrottleState.lastSource) {
340 nsecs_t nextTime = mThrottleState.lastEventTime
341 + mThrottleState.minTimeBetweenEvents;
342 if (currentTime < nextTime) {
343 // Throttle it!
344#if DEBUG_THROTTLING
345 LOGD("Throttling - Delaying motion event for "
Jeff Brown90655042010-12-02 13:50:46 -0800346 "device %d, source 0x%08x by up to %0.3fms.",
Jeff Brownb88102f2010-09-08 11:49:43 -0700347 deviceId, source, (nextTime - currentTime) * 0.000001);
348#endif
349 if (nextTime < *nextWakeupTime) {
350 *nextWakeupTime = nextTime;
351 }
352 if (mThrottleState.originalSampleCount == 0) {
353 mThrottleState.originalSampleCount =
354 motionEntry->countSamples();
355 }
356 return;
357 }
358 }
359
360#if DEBUG_THROTTLING
361 if (mThrottleState.originalSampleCount != 0) {
362 uint32_t count = motionEntry->countSamples();
363 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
364 count - mThrottleState.originalSampleCount,
365 mThrottleState.originalSampleCount, count);
366 mThrottleState.originalSampleCount = 0;
367 }
368#endif
369
makarand.karvekarf634ded2011-03-02 15:41:03 -0600370 mThrottleState.lastEventTime = currentTime;
Jeff Brownb88102f2010-09-08 11:49:43 -0700371 mThrottleState.lastDeviceId = deviceId;
372 mThrottleState.lastSource = source;
373 }
374
375 mInboundQueue.dequeue(entry);
376 mPendingEvent = entry;
377 }
Jeff Browne2fe69e2010-10-18 13:21:23 -0700378
379 // Poke user activity for this event.
380 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
381 pokeUserActivityLocked(mPendingEvent);
382 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700383 }
384
385 // Now we have an event to dispatch.
Jeff Brown928e0542011-01-10 11:17:36 -0800386 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Jeff Brownb88102f2010-09-08 11:49:43 -0700387 assert(mPendingEvent != NULL);
Jeff Brown54a18252010-09-16 14:07:33 -0700388 bool done = false;
Jeff Brownb6997262010-10-08 22:31:17 -0700389 DropReason dropReason = DROP_REASON_NOT_DROPPED;
390 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
391 dropReason = DROP_REASON_POLICY;
392 } else if (!mDispatchEnabled) {
393 dropReason = DROP_REASON_DISABLED;
394 }
Jeff Brown928e0542011-01-10 11:17:36 -0800395
396 if (mNextUnblockedEvent == mPendingEvent) {
397 mNextUnblockedEvent = NULL;
398 }
399
Jeff Brownb88102f2010-09-08 11:49:43 -0700400 switch (mPendingEvent->type) {
401 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
402 ConfigurationChangedEntry* typedEntry =
403 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700404 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brownb6997262010-10-08 22:31:17 -0700405 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Brownb88102f2010-09-08 11:49:43 -0700406 break;
407 }
408
409 case EventEntry::TYPE_KEY: {
410 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700411 if (isAppSwitchDue) {
412 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700413 resetPendingAppSwitchLocked(true);
Jeff Brownb6997262010-10-08 22:31:17 -0700414 isAppSwitchDue = false;
415 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
416 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700417 }
418 }
Jeff Brown928e0542011-01-10 11:17:36 -0800419 if (dropReason == DROP_REASON_NOT_DROPPED
420 && isStaleEventLocked(currentTime, typedEntry)) {
421 dropReason = DROP_REASON_STALE;
422 }
423 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
424 dropReason = DROP_REASON_BLOCKED;
425 }
Jeff Brown214eaf42011-05-26 19:17:02 -0700426 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700427 break;
428 }
429
430 case EventEntry::TYPE_MOTION: {
431 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700432 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
433 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700434 }
Jeff Brown928e0542011-01-10 11:17:36 -0800435 if (dropReason == DROP_REASON_NOT_DROPPED
436 && isStaleEventLocked(currentTime, typedEntry)) {
437 dropReason = DROP_REASON_STALE;
438 }
439 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
440 dropReason = DROP_REASON_BLOCKED;
441 }
Jeff Brownb6997262010-10-08 22:31:17 -0700442 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Browne20c9e02010-10-11 14:20:19 -0700443 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700444 break;
445 }
446
447 default:
448 assert(false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700449 break;
450 }
451
Jeff Brown54a18252010-09-16 14:07:33 -0700452 if (done) {
Jeff Brownb6997262010-10-08 22:31:17 -0700453 if (dropReason != DROP_REASON_NOT_DROPPED) {
454 dropInboundEventLocked(mPendingEvent, dropReason);
455 }
456
Jeff Brown54a18252010-09-16 14:07:33 -0700457 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700458 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
459 }
460}
461
462bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
463 bool needWake = mInboundQueue.isEmpty();
464 mInboundQueue.enqueueAtTail(entry);
465
466 switch (entry->type) {
Jeff Brownb6997262010-10-08 22:31:17 -0700467 case EventEntry::TYPE_KEY: {
Jeff Brown928e0542011-01-10 11:17:36 -0800468 // Optimize app switch latency.
469 // If the application takes too long to catch up then we drop all events preceding
470 // the app switch key.
Jeff Brownb6997262010-10-08 22:31:17 -0700471 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
472 if (isAppSwitchKeyEventLocked(keyEntry)) {
473 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
474 mAppSwitchSawKeyDown = true;
475 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
476 if (mAppSwitchSawKeyDown) {
477#if DEBUG_APP_SWITCH
478 LOGD("App switch is pending!");
479#endif
480 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
481 mAppSwitchSawKeyDown = false;
482 needWake = true;
483 }
484 }
485 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700486 break;
487 }
Jeff Brown928e0542011-01-10 11:17:36 -0800488
489 case EventEntry::TYPE_MOTION: {
490 // Optimize case where the current application is unresponsive and the user
491 // decides to touch a window in a different application.
492 // If the application takes too long to catch up then we drop all events preceding
493 // the touch into the other window.
494 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
Jeff Brown33bbfd22011-02-24 20:55:35 -0800495 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
Jeff Brown928e0542011-01-10 11:17:36 -0800496 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
497 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
498 && mInputTargetWaitApplication != NULL) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800499 int32_t x = int32_t(motionEntry->firstSample.pointerCoords[0].
Jeff Brownebbd5d12011-02-17 13:01:34 -0800500 getAxisValue(AMOTION_EVENT_AXIS_X));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800501 int32_t y = int32_t(motionEntry->firstSample.pointerCoords[0].
Jeff Brownebbd5d12011-02-17 13:01:34 -0800502 getAxisValue(AMOTION_EVENT_AXIS_Y));
Jeff Brown928e0542011-01-10 11:17:36 -0800503 const InputWindow* touchedWindow = findTouchedWindowAtLocked(x, y);
504 if (touchedWindow
505 && touchedWindow->inputWindowHandle != NULL
506 && touchedWindow->inputWindowHandle->getInputApplicationHandle()
507 != mInputTargetWaitApplication) {
508 // User touched a different application than the one we are waiting on.
509 // Flag the event, and start pruning the input queue.
510 mNextUnblockedEvent = motionEntry;
511 needWake = true;
512 }
513 }
514 break;
515 }
Jeff Brownb6997262010-10-08 22:31:17 -0700516 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700517
518 return needWake;
519}
520
Jeff Brown928e0542011-01-10 11:17:36 -0800521const InputWindow* InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
522 // Traverse windows from front to back to find touched window.
523 size_t numWindows = mWindows.size();
524 for (size_t i = 0; i < numWindows; i++) {
525 const InputWindow* window = & mWindows.editItemAt(i);
526 int32_t flags = window->layoutParamsFlags;
527
528 if (window->visible) {
529 if (!(flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
530 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
531 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
Jeff Brownfbf09772011-01-16 14:06:57 -0800532 if (isTouchModal || window->touchableRegionContainsPoint(x, y)) {
Jeff Brown928e0542011-01-10 11:17:36 -0800533 // Found window.
534 return window;
535 }
536 }
537 }
538
539 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
540 // Error window is on top but not visible, so touch is dropped.
541 return NULL;
542 }
543 }
544 return NULL;
545}
546
Jeff Brownb6997262010-10-08 22:31:17 -0700547void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
548 const char* reason;
549 switch (dropReason) {
550 case DROP_REASON_POLICY:
Jeff Browne20c9e02010-10-11 14:20:19 -0700551#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown3122e442010-10-11 23:32:49 -0700552 LOGD("Dropped event because policy consumed it.");
Jeff Browne20c9e02010-10-11 14:20:19 -0700553#endif
Jeff Brown3122e442010-10-11 23:32:49 -0700554 reason = "inbound event was dropped because the policy consumed it";
Jeff Brownb6997262010-10-08 22:31:17 -0700555 break;
556 case DROP_REASON_DISABLED:
557 LOGI("Dropped event because input dispatch is disabled.");
558 reason = "inbound event was dropped because input dispatch is disabled";
559 break;
560 case DROP_REASON_APP_SWITCH:
561 LOGI("Dropped event because of pending overdue app switch.");
562 reason = "inbound event was dropped because of pending overdue app switch";
563 break;
Jeff Brown928e0542011-01-10 11:17:36 -0800564 case DROP_REASON_BLOCKED:
565 LOGI("Dropped event because the current application is not responding and the user "
566 "has started interating with a different application.");
567 reason = "inbound event was dropped because the current application is not responding "
568 "and the user has started interating with a different application";
569 break;
570 case DROP_REASON_STALE:
571 LOGI("Dropped event because it is stale.");
572 reason = "inbound event was dropped because it is stale";
573 break;
Jeff Brownb6997262010-10-08 22:31:17 -0700574 default:
575 assert(false);
576 return;
577 }
578
579 switch (entry->type) {
Jeff Brown524ee642011-03-29 15:11:34 -0700580 case EventEntry::TYPE_KEY: {
581 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
582 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Brownb6997262010-10-08 22:31:17 -0700583 break;
Jeff Brown524ee642011-03-29 15:11:34 -0700584 }
Jeff Brownb6997262010-10-08 22:31:17 -0700585 case EventEntry::TYPE_MOTION: {
586 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
587 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
Jeff Brown524ee642011-03-29 15:11:34 -0700588 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
589 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Brownb6997262010-10-08 22:31:17 -0700590 } else {
Jeff Brown524ee642011-03-29 15:11:34 -0700591 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
592 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Brownb6997262010-10-08 22:31:17 -0700593 }
594 break;
595 }
596 }
597}
598
599bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700600 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
601}
602
Jeff Brownb6997262010-10-08 22:31:17 -0700603bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
604 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
605 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Browne20c9e02010-10-11 14:20:19 -0700606 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brownb6997262010-10-08 22:31:17 -0700607 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
608}
609
Jeff Brownb88102f2010-09-08 11:49:43 -0700610bool InputDispatcher::isAppSwitchPendingLocked() {
611 return mAppSwitchDueTime != LONG_LONG_MAX;
612}
613
Jeff Brownb88102f2010-09-08 11:49:43 -0700614void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
615 mAppSwitchDueTime = LONG_LONG_MAX;
616
617#if DEBUG_APP_SWITCH
618 if (handled) {
619 LOGD("App switch has arrived.");
620 } else {
621 LOGD("App switch was abandoned.");
622 }
623#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700624}
625
Jeff Brown928e0542011-01-10 11:17:36 -0800626bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
627 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
628}
629
Jeff Brown9c3cda02010-06-15 01:31:58 -0700630bool InputDispatcher::runCommandsLockedInterruptible() {
631 if (mCommandQueue.isEmpty()) {
632 return false;
633 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700634
Jeff Brown9c3cda02010-06-15 01:31:58 -0700635 do {
636 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
637
638 Command command = commandEntry->command;
639 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
640
Jeff Brown7fbdc842010-06-17 20:52:56 -0700641 commandEntry->connection.clear();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700642 mAllocator.releaseCommandEntry(commandEntry);
643 } while (! mCommandQueue.isEmpty());
644 return true;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700645}
646
Jeff Brown9c3cda02010-06-15 01:31:58 -0700647InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
648 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
649 mCommandQueue.enqueueAtTail(commandEntry);
650 return commandEntry;
651}
652
Jeff Brownb88102f2010-09-08 11:49:43 -0700653void InputDispatcher::drainInboundQueueLocked() {
654 while (! mInboundQueue.isEmpty()) {
655 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700656 releaseInboundEventLocked(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700657 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700658}
659
Jeff Brown54a18252010-09-16 14:07:33 -0700660void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700661 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700662 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700663 mPendingEvent = NULL;
664 }
665}
666
Jeff Brown54a18252010-09-16 14:07:33 -0700667void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700668 InjectionState* injectionState = entry->injectionState;
669 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700670#if DEBUG_DISPATCH_CYCLE
Jeff Brown01ce2e92010-09-26 22:20:12 -0700671 LOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700672#endif
673 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
674 }
675 mAllocator.releaseEventEntry(entry);
676}
677
Jeff Brownb88102f2010-09-08 11:49:43 -0700678void InputDispatcher::resetKeyRepeatLocked() {
679 if (mKeyRepeatState.lastKeyEntry) {
680 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
681 mKeyRepeatState.lastKeyEntry = NULL;
682 }
683}
684
Jeff Brown214eaf42011-05-26 19:17:02 -0700685InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
Jeff Brown349703e2010-06-22 01:27:15 -0700686 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
687
Jeff Brown349703e2010-06-22 01:27:15 -0700688 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Browne20c9e02010-10-11 14:20:19 -0700689 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
690 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700691 if (entry->refCount == 1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700692 mAllocator.recycleKeyEntry(entry);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700693 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700694 entry->policyFlags = policyFlags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700695 entry->repeatCount += 1;
696 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700697 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700698 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700699 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700700 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700701
702 mKeyRepeatState.lastKeyEntry = newEntry;
703 mAllocator.releaseKeyEntry(entry);
704
705 entry = newEntry;
706 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700707 entry->syntheticRepeat = true;
708
709 // Increment reference count since we keep a reference to the event in
710 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
711 entry->refCount += 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700712
Jeff Brown214eaf42011-05-26 19:17:02 -0700713 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700714 return entry;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700715}
716
Jeff Brownb88102f2010-09-08 11:49:43 -0700717bool InputDispatcher::dispatchConfigurationChangedLocked(
718 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700719#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownb88102f2010-09-08 11:49:43 -0700720 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
721#endif
722
723 // Reset key repeating in case a keyboard device was added or removed or something.
724 resetKeyRepeatLocked();
725
726 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
727 CommandEntry* commandEntry = postCommandLocked(
728 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
729 commandEntry->eventTime = entry->eventTime;
730 return true;
731}
732
Jeff Brown214eaf42011-05-26 19:17:02 -0700733bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
Jeff Browne20c9e02010-10-11 14:20:19 -0700734 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700735 // Preprocessing.
736 if (! entry->dispatchInProgress) {
737 if (entry->repeatCount == 0
738 && entry->action == AKEY_EVENT_ACTION_DOWN
739 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
740 && !entry->isInjected()) {
741 if (mKeyRepeatState.lastKeyEntry
742 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
743 // We have seen two identical key downs in a row which indicates that the device
744 // driver is automatically generating key repeats itself. We take note of the
745 // repeat here, but we disable our own next key repeat timer since it is clear that
746 // we will not need to synthesize key repeats ourselves.
747 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
748 resetKeyRepeatLocked();
749 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
750 } else {
751 // Not a repeat. Save key down state in case we do see a repeat later.
752 resetKeyRepeatLocked();
Jeff Brown214eaf42011-05-26 19:17:02 -0700753 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
Jeff Browne46a0a42010-11-02 17:58:22 -0700754 }
755 mKeyRepeatState.lastKeyEntry = entry;
756 entry->refCount += 1;
757 } else if (! entry->syntheticRepeat) {
758 resetKeyRepeatLocked();
759 }
760
Jeff Browne2e01262011-03-02 20:34:30 -0800761 if (entry->repeatCount == 1) {
762 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
763 } else {
764 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
765 }
766
Jeff Browne46a0a42010-11-02 17:58:22 -0700767 entry->dispatchInProgress = true;
768 resetTargetsLocked();
769
770 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
771 }
772
Jeff Brown54a18252010-09-16 14:07:33 -0700773 // Give the policy a chance to intercept the key.
774 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700775 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brown54a18252010-09-16 14:07:33 -0700776 CommandEntry* commandEntry = postCommandLocked(
777 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Browne20c9e02010-10-11 14:20:19 -0700778 if (mFocusedWindow) {
Jeff Brown928e0542011-01-10 11:17:36 -0800779 commandEntry->inputWindowHandle = mFocusedWindow->inputWindowHandle;
Jeff Brown54a18252010-09-16 14:07:33 -0700780 }
781 commandEntry->keyEntry = entry;
782 entry->refCount += 1;
783 return false; // wait for the command to run
784 } else {
785 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
786 }
787 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700788 if (*dropReason == DROP_REASON_NOT_DROPPED) {
789 *dropReason = DROP_REASON_POLICY;
790 }
Jeff Brown54a18252010-09-16 14:07:33 -0700791 }
792
793 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700794 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700795 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700796 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
797 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700798 return true;
799 }
800
Jeff Brownb88102f2010-09-08 11:49:43 -0700801 // Identify targets.
802 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700803 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
804 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700805 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
806 return false;
807 }
808
809 setInjectionResultLocked(entry, injectionResult);
810 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
811 return true;
812 }
813
814 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700815 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700816 }
817
818 // Dispatch the key.
819 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700820 return true;
821}
822
823void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
824#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800825 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brownb88102f2010-09-08 11:49:43 -0700826 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
Jeff Browne46a0a42010-11-02 17:58:22 -0700827 "repeatCount=%d, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700828 prefix,
829 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
830 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Jeff Browne46a0a42010-11-02 17:58:22 -0700831 entry->repeatCount, entry->downTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700832#endif
833}
834
835bool InputDispatcher::dispatchMotionLocked(
Jeff Browne20c9e02010-10-11 14:20:19 -0700836 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700837 // Preprocessing.
838 if (! entry->dispatchInProgress) {
839 entry->dispatchInProgress = true;
840 resetTargetsLocked();
841
842 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
843 }
844
Jeff Brown54a18252010-09-16 14:07:33 -0700845 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700846 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700847 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700848 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
849 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700850 return true;
851 }
852
Jeff Brownb88102f2010-09-08 11:49:43 -0700853 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
854
855 // Identify targets.
Jeff Browncc0c1592011-02-19 05:07:28 -0800856 bool conflictingPointerActions = false;
Jeff Brownb88102f2010-09-08 11:49:43 -0700857 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700858 int32_t injectionResult;
859 if (isPointerEvent) {
860 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700861 injectionResult = findTouchedWindowTargetsLocked(currentTime,
Jeff Browncc0c1592011-02-19 05:07:28 -0800862 entry, nextWakeupTime, &conflictingPointerActions);
Jeff Brownb88102f2010-09-08 11:49:43 -0700863 } else {
864 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700865 injectionResult = findFocusedWindowTargetsLocked(currentTime,
866 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700867 }
868 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
869 return false;
870 }
871
872 setInjectionResultLocked(entry, injectionResult);
873 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
874 return true;
875 }
876
877 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700878 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700879 }
880
881 // Dispatch the motion.
Jeff Browncc0c1592011-02-19 05:07:28 -0800882 if (conflictingPointerActions) {
Jeff Brown524ee642011-03-29 15:11:34 -0700883 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
884 "conflicting pointer actions");
885 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Browncc0c1592011-02-19 05:07:28 -0800886 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700887 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700888 return true;
889}
890
891
892void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
893#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800894 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700895 "action=0x%x, flags=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700896 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700897 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700898 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
899 entry->action, entry->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700900 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
901 entry->downTime);
902
903 // Print the most recent sample that we have available, this may change due to batching.
904 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700905 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700906 for (; sample->next != NULL; sample = sample->next) {
907 sampleCount += 1;
908 }
909 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -0700910 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700911 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700912 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700913 i, entry->pointerIds[i],
Jeff Brownebbd5d12011-02-17 13:01:34 -0800914 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
915 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
916 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
917 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
918 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
919 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
920 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
921 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
922 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700923 }
924
925 // Keep in mind that due to batching, it is possible for the number of samples actually
926 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700927 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700928 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
929 }
930#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700931}
932
933void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
934 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
935#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -0700936 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700937 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700938 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700939#endif
940
Jeff Brown9c3cda02010-06-15 01:31:58 -0700941 assert(eventEntry->dispatchInProgress); // should already have been set to true
942
Jeff Browne2fe69e2010-10-18 13:21:23 -0700943 pokeUserActivityLocked(eventEntry);
944
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700945 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
946 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
947
Jeff Brown519e0242010-09-15 15:18:56 -0700948 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700949 if (connectionIndex >= 0) {
950 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700951 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700952 resumeWithAppendedMotionSample);
953 } else {
Jeff Brownb6997262010-10-08 22:31:17 -0700954#if DEBUG_FOCUS
955 LOGD("Dropping event delivery to target with channel '%s' because it "
956 "is no longer registered with the input dispatcher.",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700957 inputTarget.inputChannel->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -0700958#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700959 }
960 }
961}
962
Jeff Brown54a18252010-09-16 14:07:33 -0700963void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700964 mCurrentInputTargetsValid = false;
965 mCurrentInputTargets.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700966 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Jeff Brown928e0542011-01-10 11:17:36 -0800967 mInputTargetWaitApplication.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700968}
969
Jeff Brown01ce2e92010-09-26 22:20:12 -0700970void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700971 mCurrentInputTargetsValid = true;
972}
973
974int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
975 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
976 nsecs_t* nextWakeupTime) {
977 if (application == NULL && window == NULL) {
978 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
979#if DEBUG_FOCUS
980 LOGD("Waiting for system to become ready for input.");
981#endif
982 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
983 mInputTargetWaitStartTime = currentTime;
984 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
985 mInputTargetWaitTimeoutExpired = false;
Jeff Brown928e0542011-01-10 11:17:36 -0800986 mInputTargetWaitApplication.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700987 }
988 } else {
989 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
990#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700991 LOGD("Waiting for application to become ready for input: %s",
992 getApplicationWindowLabelLocked(application, window).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700993#endif
994 nsecs_t timeout = window ? window->dispatchingTimeout :
995 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
996
997 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
998 mInputTargetWaitStartTime = currentTime;
999 mInputTargetWaitTimeoutTime = currentTime + timeout;
1000 mInputTargetWaitTimeoutExpired = false;
Jeff Brown928e0542011-01-10 11:17:36 -08001001 mInputTargetWaitApplication.clear();
1002
1003 if (window && window->inputWindowHandle != NULL) {
1004 mInputTargetWaitApplication =
1005 window->inputWindowHandle->getInputApplicationHandle();
1006 }
1007 if (mInputTargetWaitApplication == NULL && application) {
1008 mInputTargetWaitApplication = application->inputApplicationHandle;
1009 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001010 }
1011 }
1012
1013 if (mInputTargetWaitTimeoutExpired) {
1014 return INPUT_EVENT_INJECTION_TIMED_OUT;
1015 }
1016
1017 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown519e0242010-09-15 15:18:56 -07001018 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001019
1020 // Force poll loop to wake up immediately on next iteration once we get the
1021 // ANR response back from the policy.
1022 *nextWakeupTime = LONG_LONG_MIN;
1023 return INPUT_EVENT_INJECTION_PENDING;
1024 } else {
1025 // Force poll loop to wake up when timeout is due.
1026 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1027 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1028 }
1029 return INPUT_EVENT_INJECTION_PENDING;
1030 }
1031}
1032
Jeff Brown519e0242010-09-15 15:18:56 -07001033void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1034 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001035 if (newTimeout > 0) {
1036 // Extend the timeout.
1037 mInputTargetWaitTimeoutTime = now() + newTimeout;
1038 } else {
1039 // Give up.
1040 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -07001041
Jeff Brown01ce2e92010-09-26 22:20:12 -07001042 // Release the touch targets.
1043 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07001044
Jeff Brown519e0242010-09-15 15:18:56 -07001045 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -07001046 if (inputChannel.get()) {
1047 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1048 if (connectionIndex >= 0) {
1049 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown00045a72010-12-09 18:10:30 -08001050 if (connection->status == Connection::STATUS_NORMAL) {
Jeff Brown524ee642011-03-29 15:11:34 -07001051 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
Jeff Brown00045a72010-12-09 18:10:30 -08001052 "application not responding");
Jeff Brown524ee642011-03-29 15:11:34 -07001053 synthesizeCancelationEventsForConnectionLocked(connection, options);
Jeff Brown00045a72010-12-09 18:10:30 -08001054 }
Jeff Browndc3e0052010-09-16 11:02:16 -07001055 }
Jeff Brown519e0242010-09-15 15:18:56 -07001056 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001057 }
1058}
1059
Jeff Brown519e0242010-09-15 15:18:56 -07001060nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -07001061 nsecs_t currentTime) {
1062 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1063 return currentTime - mInputTargetWaitStartTime;
1064 }
1065 return 0;
1066}
1067
1068void InputDispatcher::resetANRTimeoutsLocked() {
1069#if DEBUG_FOCUS
1070 LOGD("Resetting ANR timeouts.");
1071#endif
1072
Jeff Brownb88102f2010-09-08 11:49:43 -07001073 // Reset input target wait timeout.
1074 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
1075}
1076
Jeff Brown01ce2e92010-09-26 22:20:12 -07001077int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
1078 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001079 mCurrentInputTargets.clear();
1080
1081 int32_t injectionResult;
1082
1083 // If there is no currently focused window and no focused application
1084 // then drop the event.
1085 if (! mFocusedWindow) {
1086 if (mFocusedApplication) {
1087#if DEBUG_FOCUS
1088 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001089 "focused application that may eventually add a window: %s.",
1090 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001091#endif
1092 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1093 mFocusedApplication, NULL, nextWakeupTime);
1094 goto Unresponsive;
1095 }
1096
1097 LOGI("Dropping event because there is no focused window or focused application.");
1098 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1099 goto Failed;
1100 }
1101
1102 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001103 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001104 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1105 goto Failed;
1106 }
1107
1108 // If the currently focused window is paused then keep waiting.
1109 if (mFocusedWindow->paused) {
1110#if DEBUG_FOCUS
1111 LOGD("Waiting because focused window is paused.");
1112#endif
1113 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1114 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1115 goto Unresponsive;
1116 }
1117
Jeff Brown519e0242010-09-15 15:18:56 -07001118 // If the currently focused window is still working on previous events then keep waiting.
1119 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
1120#if DEBUG_FOCUS
1121 LOGD("Waiting because focused window still processing previous input.");
1122#endif
1123 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1124 mFocusedApplication, mFocusedWindow, nextWakeupTime);
1125 goto Unresponsive;
1126 }
1127
Jeff Brownb88102f2010-09-08 11:49:43 -07001128 // Success! Output targets.
1129 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001130 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001131
1132 // Done.
1133Failed:
1134Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001135 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1136 updateDispatchStatisticsLocked(currentTime, entry,
1137 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001138#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -07001139 LOGD("findFocusedWindow finished: injectionResult=%d, "
1140 "timeSpendWaitingForApplication=%0.1fms",
1141 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001142#endif
1143 return injectionResult;
1144}
1145
Jeff Brown01ce2e92010-09-26 22:20:12 -07001146int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Jeff Browncc0c1592011-02-19 05:07:28 -08001147 const MotionEntry* entry, nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001148 enum InjectionPermission {
1149 INJECTION_PERMISSION_UNKNOWN,
1150 INJECTION_PERMISSION_GRANTED,
1151 INJECTION_PERMISSION_DENIED
1152 };
1153
Jeff Brownb88102f2010-09-08 11:49:43 -07001154 mCurrentInputTargets.clear();
1155
1156 nsecs_t startTime = now();
1157
1158 // For security reasons, we defer updating the touch state until we are sure that
1159 // event injection will be allowed.
1160 //
1161 // FIXME In the original code, screenWasOff could never be set to true.
1162 // The reason is that the POLICY_FLAG_WOKE_HERE
1163 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1164 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1165 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1166 // events upon which no preprocessing took place. So policyFlags was always 0.
1167 // In the new native input dispatcher we're a bit more careful about event
1168 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1169 // Unfortunately we obtain undesirable behavior.
1170 //
1171 // Here's what happens:
1172 //
1173 // When the device dims in anticipation of going to sleep, touches
1174 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1175 // the device to brighten and reset the user activity timer.
1176 // Touches on other windows (such as the launcher window)
1177 // are dropped. Then after a moment, the device goes to sleep. Oops.
1178 //
1179 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1180 // instead of POLICY_FLAG_WOKE_HERE...
1181 //
1182 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1183
1184 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001185 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001186
1187 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001188 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1189 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Jeff Browncc0c1592011-02-19 05:07:28 -08001190
1191 bool isSplit = mTouchState.split;
1192 bool wrongDevice = mTouchState.down
1193 && (mTouchState.deviceId != entry->deviceId
1194 || mTouchState.source != entry->source);
1195 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
Jeff Brown33bbfd22011-02-24 20:55:35 -08001196 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1197 || maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
Jeff Browncc0c1592011-02-19 05:07:28 -08001198 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
1199 if (wrongDevice && !down) {
1200 mTempTouchState.copyFrom(mTouchState);
1201 } else {
1202 mTempTouchState.reset();
1203 mTempTouchState.down = down;
1204 mTempTouchState.deviceId = entry->deviceId;
1205 mTempTouchState.source = entry->source;
1206 isSplit = false;
1207 wrongDevice = false;
1208 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001209 } else {
1210 mTempTouchState.copyFrom(mTouchState);
Jeff Browncc0c1592011-02-19 05:07:28 -08001211 }
1212 if (wrongDevice) {
Jeff Brown22d789d2011-03-25 11:58:46 -07001213#if DEBUG_FOCUS
Jeff Browncc0c1592011-02-19 05:07:28 -08001214 LOGD("Dropping event because a pointer for a different device is already down.");
Jeff Brown95712852011-01-04 19:41:59 -08001215#endif
Jeff Browncc0c1592011-02-19 05:07:28 -08001216 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1217 goto Failed;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001218 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001219
Jeff Brown01ce2e92010-09-26 22:20:12 -07001220 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
Jeff Browncc0c1592011-02-19 05:07:28 -08001221 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)
Jeff Brown33bbfd22011-02-24 20:55:35 -08001222 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1223 || maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1224 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001225
Jeff Brown01ce2e92010-09-26 22:20:12 -07001226 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Jeff Brown91c69ab2011-02-14 17:03:18 -08001227 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].
Jeff Brownebbd5d12011-02-17 13:01:34 -08001228 getAxisValue(AMOTION_EVENT_AXIS_X));
Jeff Brown91c69ab2011-02-14 17:03:18 -08001229 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].
Jeff Brownebbd5d12011-02-17 13:01:34 -08001230 getAxisValue(AMOTION_EVENT_AXIS_Y));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001231 const InputWindow* newTouchedWindow = NULL;
1232 const InputWindow* topErrorWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07001233
1234 // Traverse windows from front to back to find touched window and outside targets.
1235 size_t numWindows = mWindows.size();
1236 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001237 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001238 int32_t flags = window->layoutParamsFlags;
1239
1240 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1241 if (! topErrorWindow) {
1242 topErrorWindow = window;
1243 }
1244 }
1245
1246 if (window->visible) {
1247 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1248 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1249 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
Jeff Brownfbf09772011-01-16 14:06:57 -08001250 if (isTouchModal || window->touchableRegionContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001251 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1252 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001253 }
1254 break; // found touched window, exit window loop
1255 }
1256 }
1257
Jeff Brown01ce2e92010-09-26 22:20:12 -07001258 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1259 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001260 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1261 if (isWindowObscuredAtPointLocked(window, x, y)) {
1262 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1263 }
1264
1265 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001266 }
1267 }
1268 }
1269
1270 // If there is an error window but it is not taking focus (typically because
1271 // it is invisible) then wait for it. Any other focused window may in
1272 // fact be in ANR state.
1273 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1274#if DEBUG_FOCUS
1275 LOGD("Waiting because system error window is pending.");
1276#endif
1277 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1278 NULL, NULL, nextWakeupTime);
1279 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1280 goto Unresponsive;
1281 }
1282
Jeff Brown01ce2e92010-09-26 22:20:12 -07001283 // Figure out whether splitting will be allowed for this window.
Jeff Brown46e75292010-11-10 16:53:45 -08001284 if (newTouchedWindow && newTouchedWindow->supportsSplitTouch()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001285 // New window supports splitting.
1286 isSplit = true;
1287 } else if (isSplit) {
1288 // New window does not support splitting but we have already split events.
1289 // Assign the pointer to the first foreground window we find.
1290 // (May be NULL which is why we put this code block before the next check.)
1291 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1292 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001293
Jeff Brownb88102f2010-09-08 11:49:43 -07001294 // If we did not find a touched window then fail.
1295 if (! newTouchedWindow) {
1296 if (mFocusedApplication) {
1297#if DEBUG_FOCUS
1298 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001299 "focused application that may eventually add a new window: %s.",
1300 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001301#endif
1302 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1303 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001304 goto Unresponsive;
1305 }
1306
1307 LOGI("Dropping event because there is no touched window or focused application.");
1308 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001309 goto Failed;
1310 }
1311
Jeff Brown19dfc832010-10-05 12:26:23 -07001312 // Set target flags.
1313 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1314 if (isSplit) {
1315 targetFlags |= InputTarget::FLAG_SPLIT;
1316 }
1317 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1318 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1319 }
1320
Jeff Brown01ce2e92010-09-26 22:20:12 -07001321 // Update the temporary touch state.
1322 BitSet32 pointerIds;
1323 if (isSplit) {
1324 uint32_t pointerId = entry->pointerIds[pointerIndex];
1325 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001326 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001327 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001328 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001329 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001330
1331 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001332 if (! mTempTouchState.down) {
Jeff Brown22d789d2011-03-25 11:58:46 -07001333#if DEBUG_FOCUS
Jeff Brown76860e32010-10-25 17:37:46 -07001334 LOGD("Dropping event because the pointer is not down or we previously "
1335 "dropped the pointer down event.");
1336#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001337 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001338 goto Failed;
1339 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001340 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001341
Jeff Brown01ce2e92010-09-26 22:20:12 -07001342 // Check permission to inject into all touched foreground windows and ensure there
1343 // is at least one touched foreground window.
1344 {
1345 bool haveForegroundWindow = false;
1346 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1347 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1348 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1349 haveForegroundWindow = true;
1350 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1351 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1352 injectionPermission = INJECTION_PERMISSION_DENIED;
1353 goto Failed;
1354 }
1355 }
1356 }
1357 if (! haveForegroundWindow) {
Jeff Brown22d789d2011-03-25 11:58:46 -07001358#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001359 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001360#endif
1361 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001362 goto Failed;
1363 }
1364
Jeff Brown01ce2e92010-09-26 22:20:12 -07001365 // Permission granted to injection into all touched foreground windows.
1366 injectionPermission = INJECTION_PERMISSION_GRANTED;
1367 }
Jeff Brown519e0242010-09-15 15:18:56 -07001368
Jeff Brown01ce2e92010-09-26 22:20:12 -07001369 // Ensure all touched foreground windows are ready for new input.
1370 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1371 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1372 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1373 // If the touched window is paused then keep waiting.
1374 if (touchedWindow.window->paused) {
Jeff Brown22d789d2011-03-25 11:58:46 -07001375#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001376 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001377#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001378 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1379 NULL, touchedWindow.window, nextWakeupTime);
1380 goto Unresponsive;
1381 }
1382
1383 // If the touched window is still working on previous events then keep waiting.
1384 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1385#if DEBUG_FOCUS
1386 LOGD("Waiting because touched window still processing previous input.");
1387#endif
1388 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1389 NULL, touchedWindow.window, nextWakeupTime);
1390 goto Unresponsive;
1391 }
1392 }
1393 }
1394
1395 // If this is the first pointer going down and the touched window has a wallpaper
1396 // then also add the touched wallpaper windows so they are locked in for the duration
1397 // of the touch gesture.
Jeff Brown33bbfd22011-02-24 20:55:35 -08001398 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1399 // engine only supports touch events. We would need to add a mechanism similar
1400 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1401 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001402 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1403 if (foregroundWindow->hasWallpaper) {
1404 for (size_t i = 0; i < mWindows.size(); i++) {
1405 const InputWindow* window = & mWindows[i];
1406 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001407 mTempTouchState.addOrUpdateWindow(window,
1408 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001409 }
1410 }
1411 }
1412 }
1413
Jeff Brownb88102f2010-09-08 11:49:43 -07001414 // Success! Output targets.
1415 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001416
Jeff Brown01ce2e92010-09-26 22:20:12 -07001417 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1418 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1419 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1420 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001421 }
1422
Jeff Brown01ce2e92010-09-26 22:20:12 -07001423 // Drop the outside touch window since we will not care about them in the next iteration.
1424 mTempTouchState.removeOutsideTouchWindows();
1425
Jeff Brownb88102f2010-09-08 11:49:43 -07001426Failed:
1427 // Check injection permission once and for all.
1428 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001429 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001430 injectionPermission = INJECTION_PERMISSION_GRANTED;
1431 } else {
1432 injectionPermission = INJECTION_PERMISSION_DENIED;
1433 }
1434 }
1435
1436 // Update final pieces of touch state if the injector had permission.
1437 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown95712852011-01-04 19:41:59 -08001438 if (!wrongDevice) {
1439 if (maskedAction == AMOTION_EVENT_ACTION_UP
Jeff Browncc0c1592011-02-19 05:07:28 -08001440 || maskedAction == AMOTION_EVENT_ACTION_CANCEL
1441 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brown95712852011-01-04 19:41:59 -08001442 // All pointers up or canceled.
Jeff Brown33bbfd22011-02-24 20:55:35 -08001443 mTouchState.reset();
Jeff Brown95712852011-01-04 19:41:59 -08001444 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1445 // First pointer went down.
1446 if (mTouchState.down) {
Jeff Browncc0c1592011-02-19 05:07:28 -08001447 *outConflictingPointerActions = true;
Jeff Brownb6997262010-10-08 22:31:17 -07001448#if DEBUG_FOCUS
Jeff Brown95712852011-01-04 19:41:59 -08001449 LOGD("Pointer down received while already down.");
Jeff Brownb6997262010-10-08 22:31:17 -07001450#endif
Jeff Brown95712852011-01-04 19:41:59 -08001451 }
Jeff Brown33bbfd22011-02-24 20:55:35 -08001452 mTouchState.copyFrom(mTempTouchState);
Jeff Brown95712852011-01-04 19:41:59 -08001453 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1454 // One pointer went up.
1455 if (isSplit) {
1456 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1457 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001458
Jeff Brown95712852011-01-04 19:41:59 -08001459 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1460 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1461 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1462 touchedWindow.pointerIds.clearBit(pointerId);
1463 if (touchedWindow.pointerIds.isEmpty()) {
1464 mTempTouchState.windows.removeAt(i);
1465 continue;
1466 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001467 }
Jeff Brown95712852011-01-04 19:41:59 -08001468 i += 1;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001469 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001470 }
Jeff Brown33bbfd22011-02-24 20:55:35 -08001471 mTouchState.copyFrom(mTempTouchState);
1472 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1473 // Discard temporary touch state since it was only valid for this action.
1474 } else {
1475 // Save changes to touch state as-is for all other actions.
1476 mTouchState.copyFrom(mTempTouchState);
Jeff Brownb88102f2010-09-08 11:49:43 -07001477 }
Jeff Brown95712852011-01-04 19:41:59 -08001478 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001479 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001480#if DEBUG_FOCUS
1481 LOGD("Not updating touch focus because injection was denied.");
1482#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001483 }
1484
1485Unresponsive:
Jeff Brown120a4592010-10-27 18:43:51 -07001486 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1487 mTempTouchState.reset();
1488
Jeff Brown519e0242010-09-15 15:18:56 -07001489 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1490 updateDispatchStatisticsLocked(currentTime, entry,
1491 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001492#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001493 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1494 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001495 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001496#endif
1497 return injectionResult;
1498}
1499
Jeff Brown01ce2e92010-09-26 22:20:12 -07001500void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1501 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001502 mCurrentInputTargets.push();
1503
1504 InputTarget& target = mCurrentInputTargets.editTop();
1505 target.inputChannel = window->inputChannel;
1506 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001507 target.xOffset = - window->frameLeft;
1508 target.yOffset = - window->frameTop;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001509 target.scaleFactor = window->scaleFactor;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001510 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001511}
1512
1513void InputDispatcher::addMonitoringTargetsLocked() {
1514 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1515 mCurrentInputTargets.push();
1516
1517 InputTarget& target = mCurrentInputTargets.editTop();
1518 target.inputChannel = mMonitoringChannels[i];
1519 target.flags = 0;
Jeff Brownb88102f2010-09-08 11:49:43 -07001520 target.xOffset = 0;
1521 target.yOffset = 0;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001522 target.scaleFactor = 1.0f;
Jeff Brownb88102f2010-09-08 11:49:43 -07001523 }
1524}
1525
1526bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001527 const InjectionState* injectionState) {
1528 if (injectionState
Jeff Brownb6997262010-10-08 22:31:17 -07001529 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1530 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1531 if (window) {
1532 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1533 "with input channel %s owned by uid %d",
1534 injectionState->injectorPid, injectionState->injectorUid,
1535 window->inputChannel->getName().string(),
1536 window->ownerUid);
1537 } else {
1538 LOGW("Permission denied: injecting event from pid %d uid %d",
1539 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001540 }
Jeff Brownb6997262010-10-08 22:31:17 -07001541 return false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001542 }
1543 return true;
1544}
1545
Jeff Brown19dfc832010-10-05 12:26:23 -07001546bool InputDispatcher::isWindowObscuredAtPointLocked(
1547 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07001548 size_t numWindows = mWindows.size();
1549 for (size_t i = 0; i < numWindows; i++) {
1550 const InputWindow* other = & mWindows.itemAt(i);
1551 if (other == window) {
1552 break;
1553 }
Jeff Brown19dfc832010-10-05 12:26:23 -07001554 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001555 return true;
1556 }
1557 }
1558 return false;
1559}
1560
Jeff Brown519e0242010-09-15 15:18:56 -07001561bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1562 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1563 if (connectionIndex >= 0) {
1564 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1565 return connection->outboundQueue.isEmpty();
1566 } else {
1567 return true;
1568 }
1569}
1570
1571String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1572 const InputWindow* window) {
1573 if (application) {
1574 if (window) {
1575 String8 label(application->name);
1576 label.append(" - ");
1577 label.append(window->name);
1578 return label;
1579 } else {
1580 return application->name;
1581 }
1582 } else if (window) {
1583 return window->name;
1584 } else {
1585 return String8("<unknown application or window>");
1586 }
1587}
1588
Jeff Browne2fe69e2010-10-18 13:21:23 -07001589void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
Jeff Brown56194eb2011-03-02 19:23:13 -08001590 int32_t eventType = POWER_MANAGER_OTHER_EVENT;
Jeff Brown4d396052010-10-29 21:50:21 -07001591 switch (eventEntry->type) {
1592 case EventEntry::TYPE_MOTION: {
Jeff Browne2fe69e2010-10-18 13:21:23 -07001593 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Brown4d396052010-10-29 21:50:21 -07001594 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1595 return;
1596 }
1597
Jeff Brown56194eb2011-03-02 19:23:13 -08001598 if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
Joe Onorato1a542c72010-11-08 09:48:20 -08001599 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001600 }
Jeff Brown4d396052010-10-29 21:50:21 -07001601 break;
1602 }
1603 case EventEntry::TYPE_KEY: {
1604 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1605 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1606 return;
1607 }
Jeff Brown56194eb2011-03-02 19:23:13 -08001608 eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brown4d396052010-10-29 21:50:21 -07001609 break;
1610 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001611 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001612
Jeff Brownb88102f2010-09-08 11:49:43 -07001613 CommandEntry* commandEntry = postCommandLocked(
1614 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Browne2fe69e2010-10-18 13:21:23 -07001615 commandEntry->eventTime = eventEntry->eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001616 commandEntry->userActivityEventType = eventType;
1617}
1618
Jeff Brown7fbdc842010-06-17 20:52:56 -07001619void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1620 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001621 bool resumeWithAppendedMotionSample) {
1622#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001623 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001624 "xOffset=%f, yOffset=%f, scaleFactor=%f"
Jeff Brown83c09682010-12-23 17:50:18 -08001625 "pointerIds=0x%x, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001626 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001627 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001628 inputTarget->xOffset, inputTarget->yOffset,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001629 inputTarget->scaleFactor, inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001630 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001631#endif
1632
Jeff Brown01ce2e92010-09-26 22:20:12 -07001633 // Make sure we are never called for streaming when splitting across multiple windows.
1634 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1635 assert(! (resumeWithAppendedMotionSample && isSplit));
1636
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001637 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001638 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001639 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb6997262010-10-08 22:31:17 -07001640#if DEBUG_DISPATCH_CYCLE
1641 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001642 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brownb6997262010-10-08 22:31:17 -07001643#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001644 return;
1645 }
1646
Jeff Brown01ce2e92010-09-26 22:20:12 -07001647 // Split a motion event if needed.
1648 if (isSplit) {
1649 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1650
1651 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1652 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1653 MotionEntry* splitMotionEntry = splitMotionEvent(
1654 originalMotionEntry, inputTarget->pointerIds);
Jeff Brown58a2da82011-01-25 16:02:22 -08001655 if (!splitMotionEntry) {
1656 return; // split event was dropped
1657 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001658#if DEBUG_FOCUS
1659 LOGD("channel '%s' ~ Split motion event.",
1660 connection->getInputChannelName());
1661 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1662#endif
1663 eventEntry = splitMotionEntry;
1664 }
1665 }
1666
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001667 // Resume the dispatch cycle with a freshly appended motion sample.
1668 // First we check that the last dispatch entry in the outbound queue is for the same
1669 // motion event to which we appended the motion sample. If we find such a dispatch
1670 // entry, and if it is currently in progress then we try to stream the new sample.
1671 bool wasEmpty = connection->outboundQueue.isEmpty();
1672
1673 if (! wasEmpty && resumeWithAppendedMotionSample) {
1674 DispatchEntry* motionEventDispatchEntry =
1675 connection->findQueuedDispatchEntryForEvent(eventEntry);
1676 if (motionEventDispatchEntry) {
1677 // If the dispatch entry is not in progress, then we must be busy dispatching an
1678 // earlier event. Not a problem, the motion event is on the outbound queue and will
1679 // be dispatched later.
1680 if (! motionEventDispatchEntry->inProgress) {
1681#if DEBUG_BATCHING
1682 LOGD("channel '%s' ~ Not streaming because the motion event has "
1683 "not yet been dispatched. "
1684 "(Waiting for earlier events to be consumed.)",
1685 connection->getInputChannelName());
1686#endif
1687 return;
1688 }
1689
1690 // If the dispatch entry is in progress but it already has a tail of pending
1691 // motion samples, then it must mean that the shared memory buffer filled up.
1692 // Not a problem, when this dispatch cycle is finished, we will eventually start
1693 // a new dispatch cycle to process the tail and that tail includes the newly
1694 // appended motion sample.
1695 if (motionEventDispatchEntry->tailMotionSample) {
1696#if DEBUG_BATCHING
1697 LOGD("channel '%s' ~ Not streaming because no new samples can "
1698 "be appended to the motion event in this dispatch cycle. "
1699 "(Waiting for next dispatch cycle to start.)",
1700 connection->getInputChannelName());
1701#endif
1702 return;
1703 }
1704
1705 // The dispatch entry is in progress and is still potentially open for streaming.
1706 // Try to stream the new motion sample. This might fail if the consumer has already
1707 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001708 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1709 MotionSample* appendedMotionSample = motionEntry->lastSample;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001710 status_t status;
1711 if (motionEventDispatchEntry->scaleFactor == 1.0f) {
1712 status = connection->inputPublisher.appendMotionSample(
1713 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1714 } else {
1715 PointerCoords scaledCoords[MAX_POINTERS];
1716 for (size_t i = 0; i < motionEntry->pointerCount; i++) {
1717 scaledCoords[i] = appendedMotionSample->pointerCoords[i];
1718 scaledCoords[i].scale(motionEventDispatchEntry->scaleFactor);
1719 }
1720 status = connection->inputPublisher.appendMotionSample(
1721 appendedMotionSample->eventTime, scaledCoords);
1722 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001723 if (status == OK) {
1724#if DEBUG_BATCHING
1725 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1726 connection->getInputChannelName());
1727#endif
1728 return;
1729 }
1730
1731#if DEBUG_BATCHING
1732 if (status == NO_MEMORY) {
1733 LOGD("channel '%s' ~ Could not append motion sample to currently "
1734 "dispatched move event because the shared memory buffer is full. "
1735 "(Waiting for next dispatch cycle to start.)",
1736 connection->getInputChannelName());
1737 } else if (status == status_t(FAILED_TRANSACTION)) {
1738 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001739 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001740 "(Waiting for next dispatch cycle to start.)",
1741 connection->getInputChannelName());
1742 } else {
1743 LOGD("channel '%s' ~ Could not append motion sample to currently "
1744 "dispatched move event due to an error, status=%d. "
1745 "(Waiting for next dispatch cycle to start.)",
1746 connection->getInputChannelName(), status);
1747 }
1748#endif
1749 // Failed to stream. Start a new tail of pending motion samples to dispatch
1750 // in the next cycle.
1751 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1752 return;
1753 }
1754 }
1755
1756 // This is a new event.
1757 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001758 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001759 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset,
1760 inputTarget->scaleFactor);
Jeff Brown519e0242010-09-15 15:18:56 -07001761 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001762 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001763 }
1764
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001765 // Handle the case where we could not stream a new motion sample because the consumer has
1766 // already consumed the motion event (otherwise the corresponding dispatch entry would
1767 // still be in the outbound queue for this connection). We set the head motion sample
1768 // to the list starting with the newly appended motion sample.
1769 if (resumeWithAppendedMotionSample) {
1770#if DEBUG_BATCHING
1771 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1772 "that cannot be streamed because the motion event has already been consumed.",
1773 connection->getInputChannelName());
1774#endif
1775 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1776 dispatchEntry->headMotionSample = appendedMotionSample;
1777 }
1778
1779 // Enqueue the dispatch entry.
1780 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1781
1782 // If the outbound queue was previously empty, start the dispatch cycle going.
1783 if (wasEmpty) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001784 activateConnectionLocked(connection.get());
Jeff Brown519e0242010-09-15 15:18:56 -07001785 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001786 }
1787}
1788
Jeff Brown7fbdc842010-06-17 20:52:56 -07001789void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001790 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001791#if DEBUG_DISPATCH_CYCLE
1792 LOGD("channel '%s' ~ startDispatchCycle",
1793 connection->getInputChannelName());
1794#endif
1795
1796 assert(connection->status == Connection::STATUS_NORMAL);
1797 assert(! connection->outboundQueue.isEmpty());
1798
Jeff Brownb88102f2010-09-08 11:49:43 -07001799 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001800 assert(! dispatchEntry->inProgress);
1801
Jeff Brownb88102f2010-09-08 11:49:43 -07001802 // Mark the dispatch entry as in progress.
1803 dispatchEntry->inProgress = true;
1804
1805 // Update the connection's input state.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001806 EventEntry* eventEntry = dispatchEntry->eventEntry;
Jeff Browncc0c1592011-02-19 05:07:28 -08001807 connection->inputState.trackEvent(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001808
1809 // Publish the event.
1810 status_t status;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001811 switch (eventEntry->type) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001812 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001813 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001814
1815 // Apply target flags.
1816 int32_t action = keyEntry->action;
1817 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001818
1819 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001820 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001821 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1822 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1823 keyEntry->eventTime);
1824
1825 if (status) {
1826 LOGE("channel '%s' ~ Could not publish key event, "
1827 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001828 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001829 return;
1830 }
1831 break;
1832 }
1833
1834 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001835 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001836
1837 // Apply target flags.
1838 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001839 int32_t flags = motionEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001840 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001841 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001842 }
Jeff Brown85a31762010-09-01 17:01:00 -07001843 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1844 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1845 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001846
1847 // If headMotionSample is non-NULL, then it points to the first new sample that we
1848 // were unable to dispatch during the previous cycle so we resume dispatching from
1849 // that point in the list of motion samples.
1850 // Otherwise, we just start from the first sample of the motion event.
1851 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1852 if (! firstMotionSample) {
1853 firstMotionSample = & motionEntry->firstSample;
1854 }
1855
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001856 PointerCoords scaledCoords[MAX_POINTERS];
1857 const PointerCoords* usingCoords = firstMotionSample->pointerCoords;
1858
Jeff Brownd3616592010-07-16 17:21:06 -07001859 // Set the X and Y offset depending on the input source.
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001860 float xOffset, yOffset, scaleFactor;
Jeff Brownd3616592010-07-16 17:21:06 -07001861 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001862 scaleFactor = dispatchEntry->scaleFactor;
1863 xOffset = dispatchEntry->xOffset * scaleFactor;
1864 yOffset = dispatchEntry->yOffset * scaleFactor;
1865 if (scaleFactor != 1.0f) {
1866 for (size_t i = 0; i < motionEntry->pointerCount; i++) {
1867 scaledCoords[i] = firstMotionSample->pointerCoords[i];
1868 scaledCoords[i].scale(scaleFactor);
1869 }
1870 usingCoords = scaledCoords;
1871 }
Jeff Brownd3616592010-07-16 17:21:06 -07001872 } else {
1873 xOffset = 0.0f;
1874 yOffset = 0.0f;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001875 scaleFactor = 1.0f;
Jeff Brownd3616592010-07-16 17:21:06 -07001876 }
1877
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001878 // Publish the motion event and the first motion sample.
1879 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07001880 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001881 xOffset, yOffset, motionEntry->xPrecision, motionEntry->yPrecision,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001882 motionEntry->downTime, firstMotionSample->eventTime,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001883 motionEntry->pointerCount, motionEntry->pointerIds, usingCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001884
1885 if (status) {
1886 LOGE("channel '%s' ~ Could not publish motion event, "
1887 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001888 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001889 return;
1890 }
1891
1892 // Append additional motion samples.
1893 MotionSample* nextMotionSample = firstMotionSample->next;
1894 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
Dianne Hackborne7d25b72011-05-09 21:19:26 -07001895 if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) != 0 && scaleFactor != 1.0f) {
1896 for (size_t i = 0; i < motionEntry->pointerCount; i++) {
1897 scaledCoords[i] = nextMotionSample->pointerCoords[i];
1898 scaledCoords[i].scale(scaleFactor);
1899 }
1900 } else {
1901 usingCoords = nextMotionSample->pointerCoords;
1902 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001903 status = connection->inputPublisher.appendMotionSample(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001904 nextMotionSample->eventTime, usingCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001905 if (status == NO_MEMORY) {
1906#if DEBUG_DISPATCH_CYCLE
1907 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1908 "be sent in the next dispatch cycle.",
1909 connection->getInputChannelName());
1910#endif
1911 break;
1912 }
1913 if (status != OK) {
1914 LOGE("channel '%s' ~ Could not append motion sample "
1915 "for a reason other than out of memory, status=%d",
1916 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001917 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001918 return;
1919 }
1920 }
1921
1922 // Remember the next motion sample that we could not dispatch, in case we ran out
1923 // of space in the shared memory buffer.
1924 dispatchEntry->tailMotionSample = nextMotionSample;
1925 break;
1926 }
1927
1928 default: {
1929 assert(false);
1930 }
1931 }
1932
1933 // Send the dispatch signal.
1934 status = connection->inputPublisher.sendDispatchSignal();
1935 if (status) {
1936 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1937 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001938 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001939 return;
1940 }
1941
1942 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001943 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001944 connection->lastDispatchTime = currentTime;
1945
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001946 // Notify other system components.
1947 onDispatchCycleStartedLocked(currentTime, connection);
1948}
1949
Jeff Brown7fbdc842010-06-17 20:52:56 -07001950void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown3915bb82010-11-05 15:02:16 -07001951 const sp<Connection>& connection, bool handled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001952#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001953 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown3915bb82010-11-05 15:02:16 -07001954 "%01.1fms since dispatch, handled=%s",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001955 connection->getInputChannelName(),
1956 connection->getEventLatencyMillis(currentTime),
Jeff Brown3915bb82010-11-05 15:02:16 -07001957 connection->getDispatchLatencyMillis(currentTime),
1958 toString(handled));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001959#endif
1960
Jeff Brown9c3cda02010-06-15 01:31:58 -07001961 if (connection->status == Connection::STATUS_BROKEN
1962 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001963 return;
1964 }
1965
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001966 // Reset the publisher since the event has been consumed.
1967 // We do this now so that the publisher can release some of its internal resources
1968 // while waiting for the next dispatch cycle to begin.
1969 status_t status = connection->inputPublisher.reset();
1970 if (status) {
1971 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1972 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001973 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001974 return;
1975 }
1976
Jeff Brown3915bb82010-11-05 15:02:16 -07001977 // Notify other system components and prepare to start the next dispatch cycle.
1978 onDispatchCycleFinishedLocked(currentTime, connection, handled);
Jeff Brownb88102f2010-09-08 11:49:43 -07001979}
1980
1981void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1982 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001983 // Start the next dispatch cycle for this connection.
1984 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001985 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001986 if (dispatchEntry->inProgress) {
1987 // Finish or resume current event in progress.
1988 if (dispatchEntry->tailMotionSample) {
1989 // We have a tail of undispatched motion samples.
1990 // Reuse the same DispatchEntry and start a new cycle.
1991 dispatchEntry->inProgress = false;
1992 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1993 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07001994 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001995 return;
1996 }
1997 // Finished.
1998 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07001999 if (dispatchEntry->hasForegroundTarget()) {
2000 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002001 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002002 mAllocator.releaseDispatchEntry(dispatchEntry);
2003 } else {
2004 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07002005 // progress event, which means we actually aborted it.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002006 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07002007 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002008 return;
2009 }
2010 }
2011
2012 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002013 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002014}
2015
Jeff Brownb6997262010-10-08 22:31:17 -07002016void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
2017 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002018#if DEBUG_DISPATCH_CYCLE
Jeff Brown83c09682010-12-23 17:50:18 -08002019 LOGD("channel '%s' ~ abortBrokenDispatchCycle",
2020 connection->getInputChannelName());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002021#endif
2022
Jeff Brownb88102f2010-09-08 11:49:43 -07002023 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002024 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002025
Jeff Brownb6997262010-10-08 22:31:17 -07002026 // The connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002027 // Ignore already broken or zombie connections.
Jeff Brownb6997262010-10-08 22:31:17 -07002028 if (connection->status == Connection::STATUS_NORMAL) {
2029 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002030
Jeff Brownb6997262010-10-08 22:31:17 -07002031 // Notify other system components.
2032 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002033 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002034}
2035
Jeff Brown519e0242010-09-15 15:18:56 -07002036void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
2037 while (! connection->outboundQueue.isEmpty()) {
2038 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
2039 if (dispatchEntry->hasForegroundTarget()) {
2040 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07002041 }
2042 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07002043 }
2044
Jeff Brown519e0242010-09-15 15:18:56 -07002045 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07002046}
2047
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002048int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002049 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2050
2051 { // acquire lock
2052 AutoMutex _l(d->mLock);
2053
2054 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
2055 if (connectionIndex < 0) {
2056 LOGE("Received spurious receive callback for unknown input channel. "
2057 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002058 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002059 }
2060
Jeff Brown7fbdc842010-06-17 20:52:56 -07002061 nsecs_t currentTime = now();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002062
2063 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002064 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002065 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
2066 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brownb6997262010-10-08 22:31:17 -07002067 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002068 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002069 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002070 }
2071
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002072 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002073 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
2074 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002075 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002076 }
2077
Jeff Brown3915bb82010-11-05 15:02:16 -07002078 bool handled = false;
Jeff Brown49ed71d2010-12-06 17:13:33 -08002079 status_t status = connection->inputPublisher.receiveFinishedSignal(&handled);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002080 if (status) {
2081 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
2082 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07002083 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002084 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002085 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002086 }
2087
Jeff Brown3915bb82010-11-05 15:02:16 -07002088 d->finishDispatchCycleLocked(currentTime, connection, handled);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002089 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002090 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002091 } // release lock
2092}
2093
Jeff Brownb6997262010-10-08 22:31:17 -07002094void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Jeff Brown524ee642011-03-29 15:11:34 -07002095 const CancelationOptions& options) {
Jeff Brownb6997262010-10-08 22:31:17 -07002096 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
2097 synthesizeCancelationEventsForConnectionLocked(
Jeff Brown524ee642011-03-29 15:11:34 -07002098 mConnectionsByReceiveFd.valueAt(i), options);
Jeff Brownb6997262010-10-08 22:31:17 -07002099 }
2100}
2101
2102void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Jeff Brown524ee642011-03-29 15:11:34 -07002103 const sp<InputChannel>& channel, const CancelationOptions& options) {
Jeff Brownb6997262010-10-08 22:31:17 -07002104 ssize_t index = getConnectionIndexLocked(channel);
2105 if (index >= 0) {
2106 synthesizeCancelationEventsForConnectionLocked(
Jeff Brown524ee642011-03-29 15:11:34 -07002107 mConnectionsByReceiveFd.valueAt(index), options);
Jeff Brownb6997262010-10-08 22:31:17 -07002108 }
2109}
2110
2111void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
Jeff Brown524ee642011-03-29 15:11:34 -07002112 const sp<Connection>& connection, const CancelationOptions& options) {
Jeff Brownb6997262010-10-08 22:31:17 -07002113 nsecs_t currentTime = now();
2114
2115 mTempCancelationEvents.clear();
2116 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
2117 mTempCancelationEvents, options);
2118
2119 if (! mTempCancelationEvents.isEmpty()
2120 && connection->status != Connection::STATUS_BROKEN) {
2121#if DEBUG_OUTBOUND_EVENT_DETAILS
2122 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
Jeff Brown524ee642011-03-29 15:11:34 -07002123 "with reality: %s, mode=%d.",
2124 connection->getInputChannelName(), mTempCancelationEvents.size(),
2125 options.reason, options.mode);
Jeff Brownb6997262010-10-08 22:31:17 -07002126#endif
2127 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
2128 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
2129 switch (cancelationEventEntry->type) {
2130 case EventEntry::TYPE_KEY:
2131 logOutboundKeyDetailsLocked("cancel - ",
2132 static_cast<KeyEntry*>(cancelationEventEntry));
2133 break;
2134 case EventEntry::TYPE_MOTION:
2135 logOutboundMotionDetailsLocked("cancel - ",
2136 static_cast<MotionEntry*>(cancelationEventEntry));
2137 break;
2138 }
2139
2140 int32_t xOffset, yOffset;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002141 float scaleFactor;
Jeff Brownb6997262010-10-08 22:31:17 -07002142 const InputWindow* window = getWindowLocked(connection->inputChannel);
2143 if (window) {
2144 xOffset = -window->frameLeft;
2145 yOffset = -window->frameTop;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002146 scaleFactor = window->scaleFactor;
Jeff Brownb6997262010-10-08 22:31:17 -07002147 } else {
2148 xOffset = 0;
2149 yOffset = 0;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002150 scaleFactor = 1.0f;
Jeff Brownb6997262010-10-08 22:31:17 -07002151 }
2152
2153 DispatchEntry* cancelationDispatchEntry =
2154 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002155 0, xOffset, yOffset, scaleFactor);
Jeff Brownb6997262010-10-08 22:31:17 -07002156 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
2157
2158 mAllocator.releaseEventEntry(cancelationEventEntry);
2159 }
2160
2161 if (!connection->outboundQueue.headSentinel.next->inProgress) {
2162 startDispatchCycleLocked(currentTime, connection);
2163 }
2164 }
2165}
2166
Jeff Brown01ce2e92010-09-26 22:20:12 -07002167InputDispatcher::MotionEntry*
2168InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2169 assert(pointerIds.value != 0);
2170
2171 uint32_t splitPointerIndexMap[MAX_POINTERS];
2172 int32_t splitPointerIds[MAX_POINTERS];
2173 PointerCoords splitPointerCoords[MAX_POINTERS];
2174
2175 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2176 uint32_t splitPointerCount = 0;
2177
2178 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2179 originalPointerIndex++) {
2180 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
2181 if (pointerIds.hasBit(pointerId)) {
2182 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2183 splitPointerIds[splitPointerCount] = pointerId;
Jeff Brown96ad3972011-03-09 17:39:48 -08002184 splitPointerCoords[splitPointerCount].copyFrom(
2185 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex]);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002186 splitPointerCount += 1;
2187 }
2188 }
Jeff Brown58a2da82011-01-25 16:02:22 -08002189
2190 if (splitPointerCount != pointerIds.count()) {
2191 // This is bad. We are missing some of the pointers that we expected to deliver.
2192 // Most likely this indicates that we received an ACTION_MOVE events that has
2193 // different pointer ids than we expected based on the previous ACTION_DOWN
2194 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2195 // in this way.
2196 LOGW("Dropping split motion event because the pointer count is %d but "
2197 "we expected there to be %d pointers. This probably means we received "
2198 "a broken sequence of pointer ids from the input device.",
2199 splitPointerCount, pointerIds.count());
2200 return NULL;
2201 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002202
2203 int32_t action = originalMotionEntry->action;
2204 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2205 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2206 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2207 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2208 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2209 if (pointerIds.hasBit(pointerId)) {
2210 if (pointerIds.count() == 1) {
2211 // The first/last pointer went down/up.
2212 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2213 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07002214 } else {
2215 // A secondary pointer went down/up.
2216 uint32_t splitPointerIndex = 0;
2217 while (pointerId != splitPointerIds[splitPointerIndex]) {
2218 splitPointerIndex += 1;
2219 }
2220 action = maskedAction | (splitPointerIndex
2221 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002222 }
2223 } else {
2224 // An unrelated pointer changed.
2225 action = AMOTION_EVENT_ACTION_MOVE;
2226 }
2227 }
2228
2229 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2230 originalMotionEntry->eventTime,
2231 originalMotionEntry->deviceId,
2232 originalMotionEntry->source,
2233 originalMotionEntry->policyFlags,
2234 action,
2235 originalMotionEntry->flags,
2236 originalMotionEntry->metaState,
2237 originalMotionEntry->edgeFlags,
2238 originalMotionEntry->xPrecision,
2239 originalMotionEntry->yPrecision,
2240 originalMotionEntry->downTime,
2241 splitPointerCount, splitPointerIds, splitPointerCoords);
2242
2243 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2244 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2245 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2246 splitPointerIndex++) {
2247 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
Jeff Brown96ad3972011-03-09 17:39:48 -08002248 splitPointerCoords[splitPointerIndex].copyFrom(
2249 originalMotionSample->pointerCoords[originalPointerIndex]);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002250 }
2251
2252 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2253 splitPointerCoords);
2254 }
2255
2256 return splitMotionEntry;
2257}
2258
Jeff Brown9c3cda02010-06-15 01:31:58 -07002259void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002260#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07002261 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002262#endif
2263
Jeff Brownb88102f2010-09-08 11:49:43 -07002264 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002265 { // acquire lock
2266 AutoMutex _l(mLock);
2267
Jeff Brown7fbdc842010-06-17 20:52:56 -07002268 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07002269 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002270 } // release lock
2271
Jeff Brownb88102f2010-09-08 11:49:43 -07002272 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002273 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002274 }
2275}
2276
Jeff Brown58a2da82011-01-25 16:02:22 -08002277void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002278 uint32_t policyFlags, int32_t action, int32_t flags,
2279 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2280#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002281 LOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002282 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07002283 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002284 keyCode, scanCode, metaState, downTime);
2285#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002286 if (! validateKeyEvent(action)) {
2287 return;
2288 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002289
Jeff Brown1f245102010-11-18 20:53:46 -08002290 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2291 policyFlags |= POLICY_FLAG_VIRTUAL;
2292 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2293 }
Jeff Brown924c4d42011-03-07 16:40:47 -08002294 if (policyFlags & POLICY_FLAG_ALT) {
2295 metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON;
2296 }
2297 if (policyFlags & POLICY_FLAG_ALT_GR) {
2298 metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON;
2299 }
2300 if (policyFlags & POLICY_FLAG_SHIFT) {
2301 metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON;
2302 }
2303 if (policyFlags & POLICY_FLAG_CAPS_LOCK) {
2304 metaState |= AMETA_CAPS_LOCK_ON;
2305 }
2306 if (policyFlags & POLICY_FLAG_FUNCTION) {
2307 metaState |= AMETA_FUNCTION_ON;
2308 }
Jeff Brown1f245102010-11-18 20:53:46 -08002309
Jeff Browne20c9e02010-10-11 14:20:19 -07002310 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown1f245102010-11-18 20:53:46 -08002311
2312 KeyEvent event;
2313 event.initialize(deviceId, source, action, flags, keyCode, scanCode,
2314 metaState, 0, downTime, eventTime);
2315
2316 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
2317
2318 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2319 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2320 }
Jeff Brownb6997262010-10-08 22:31:17 -07002321
Jeff Brownb88102f2010-09-08 11:49:43 -07002322 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002323 { // acquire lock
2324 AutoMutex _l(mLock);
2325
Jeff Brown7fbdc842010-06-17 20:52:56 -07002326 int32_t repeatCount = 0;
2327 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002328 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002329 metaState, repeatCount, downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002330
Jeff Brownb88102f2010-09-08 11:49:43 -07002331 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002332 } // release lock
2333
Jeff Brownb88102f2010-09-08 11:49:43 -07002334 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002335 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002336 }
2337}
2338
Jeff Brown58a2da82011-01-25 16:02:22 -08002339void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002340 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002341 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2342 float xPrecision, float yPrecision, nsecs_t downTime) {
2343#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002344 LOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002345 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2346 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2347 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002348 xPrecision, yPrecision, downTime);
2349 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002350 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002351 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002352 "orientation=%f",
Jeff Brown91c69ab2011-02-14 17:03:18 -08002353 i, pointerIds[i],
Jeff Brownebbd5d12011-02-17 13:01:34 -08002354 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2355 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2356 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2357 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2358 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2359 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2360 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2361 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2362 pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002363 }
2364#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002365 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2366 return;
2367 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002368
Jeff Browne20c9e02010-10-11 14:20:19 -07002369 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown56194eb2011-03-02 19:23:13 -08002370 mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002371
Jeff Brownb88102f2010-09-08 11:49:43 -07002372 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002373 { // acquire lock
2374 AutoMutex _l(mLock);
2375
2376 // Attempt batching and streaming of move events.
Jeff Browncc0c1592011-02-19 05:07:28 -08002377 if (action == AMOTION_EVENT_ACTION_MOVE
2378 || action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002379 // BATCHING CASE
2380 //
2381 // Try to append a move sample to the tail of the inbound queue for this device.
2382 // Give up if we encounter a non-move motion event for this device since that
2383 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002384 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2385 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002386 if (entry->type != EventEntry::TYPE_MOTION) {
2387 // Keep looking for motion events.
2388 continue;
2389 }
2390
2391 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
Jeff Brownefd32662011-03-08 15:13:06 -08002392 if (motionEntry->deviceId != deviceId
2393 || motionEntry->source != source) {
2394 // Keep looking for this device and source.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002395 continue;
2396 }
2397
Jeff Brown5ced76a2011-05-24 11:23:27 -07002398 if (!motionEntry->canAppendSamples(action, pointerCount, pointerIds)) {
Jeff Brownefd32662011-03-08 15:13:06 -08002399 // Last motion event in the queue for this device and source is
2400 // not compatible for appending new samples. Stop here.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002401 goto NoBatchingOrStreaming;
2402 }
2403
Jeff Brown9c3cda02010-06-15 01:31:58 -07002404 // Do the batching magic.
Jeff Brown5ced76a2011-05-24 11:23:27 -07002405 batchMotionLocked(motionEntry, eventTime, metaState, pointerCoords,
2406 "most recent motion event for this device and source in the inbound queue");
Jeff Brown9c3cda02010-06-15 01:31:58 -07002407 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002408 }
2409
Jeff Brown7157f6f2011-04-06 17:19:48 -07002410 // BATCHING ONTO PENDING EVENT CASE
2411 //
2412 // Try to append a move sample to the currently pending event, if there is one.
2413 // We can do this as long as we are still waiting to find the targets for the
2414 // event. Once the targets are locked-in we can only do streaming.
2415 if (mPendingEvent
2416 && (!mPendingEvent->dispatchInProgress || !mCurrentInputTargetsValid)
2417 && mPendingEvent->type == EventEntry::TYPE_MOTION) {
2418 MotionEntry* motionEntry = static_cast<MotionEntry*>(mPendingEvent);
2419 if (motionEntry->deviceId == deviceId && motionEntry->source == source) {
Jeff Brown5ced76a2011-05-24 11:23:27 -07002420 if (!motionEntry->canAppendSamples(action, pointerCount, pointerIds)) {
2421 // Pending motion event is for this device and source but it is
2422 // not compatible for appending new samples. Stop here.
Jeff Brown7157f6f2011-04-06 17:19:48 -07002423 goto NoBatchingOrStreaming;
2424 }
2425
Jeff Brown7157f6f2011-04-06 17:19:48 -07002426 // Do the batching magic.
Jeff Brown5ced76a2011-05-24 11:23:27 -07002427 batchMotionLocked(motionEntry, eventTime, metaState, pointerCoords,
2428 "pending motion event");
Jeff Brown7157f6f2011-04-06 17:19:48 -07002429 return; // done!
2430 }
2431 }
2432
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002433 // STREAMING CASE
2434 //
2435 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002436 // Search the outbound queue for the current foreground targets to find a dispatched
2437 // motion event that is still in progress. If found, then, appen the new sample to
2438 // that event and push it out to all current targets. The logic in
2439 // prepareDispatchCycleLocked takes care of the case where some targets may
2440 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002441 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002442 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2443 const InputTarget& inputTarget = mCurrentInputTargets[i];
2444 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2445 // Skip non-foreground targets. We only want to stream if there is at
2446 // least one foreground target whose dispatch is still in progress.
2447 continue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002448 }
Jeff Brown519e0242010-09-15 15:18:56 -07002449
2450 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2451 if (connectionIndex < 0) {
2452 // Connection must no longer be valid.
2453 continue;
2454 }
2455
2456 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2457 if (connection->outboundQueue.isEmpty()) {
2458 // This foreground target has an empty outbound queue.
2459 continue;
2460 }
2461
2462 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2463 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002464 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2465 || dispatchEntry->isSplit()) {
2466 // No motion event is being dispatched, or it is being split across
2467 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002468 continue;
2469 }
2470
2471 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2472 dispatchEntry->eventEntry);
Jeff Browncc0c1592011-02-19 05:07:28 -08002473 if (motionEntry->action != action
Jeff Brown519e0242010-09-15 15:18:56 -07002474 || motionEntry->deviceId != deviceId
Jeff Brown58a2da82011-01-25 16:02:22 -08002475 || motionEntry->source != source
Jeff Brown519e0242010-09-15 15:18:56 -07002476 || motionEntry->pointerCount != pointerCount
2477 || motionEntry->isInjected()) {
2478 // The motion event is not compatible with this move.
2479 continue;
2480 }
2481
2482 // Hurray! This foreground target is currently dispatching a move event
2483 // that we can stream onto. Append the motion sample and resume dispatch.
2484 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2485#if DEBUG_BATCHING
2486 LOGD("Appended motion sample onto batch for most recently dispatched "
Jeff Brown5ced76a2011-05-24 11:23:27 -07002487 "motion event for this device and source in the outbound queues. "
Jeff Brown519e0242010-09-15 15:18:56 -07002488 "Attempting to stream the motion sample.");
2489#endif
2490 nsecs_t currentTime = now();
2491 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2492 true /*resumeWithAppendedMotionSample*/);
2493
2494 runCommandsLockedInterruptible();
2495 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002496 }
2497 }
2498
2499NoBatchingOrStreaming:;
2500 }
2501
2502 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002503 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002504 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002505 xPrecision, yPrecision, downTime,
2506 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002507
Jeff Brownb88102f2010-09-08 11:49:43 -07002508 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002509 } // release lock
2510
Jeff Brownb88102f2010-09-08 11:49:43 -07002511 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002512 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002513 }
2514}
2515
Jeff Brown5ced76a2011-05-24 11:23:27 -07002516void InputDispatcher::batchMotionLocked(MotionEntry* entry, nsecs_t eventTime,
2517 int32_t metaState, const PointerCoords* pointerCoords, const char* eventDescription) {
2518 // Combine meta states.
2519 entry->metaState |= metaState;
2520
2521 // Coalesce this sample if not enough time has elapsed since the last sample was
2522 // initially appended to the batch.
2523 MotionSample* lastSample = entry->lastSample;
2524 long interval = eventTime - lastSample->eventTimeBeforeCoalescing;
2525 if (interval <= MOTION_SAMPLE_COALESCE_INTERVAL) {
2526 uint32_t pointerCount = entry->pointerCount;
2527 for (uint32_t i = 0; i < pointerCount; i++) {
2528 lastSample->pointerCoords[i].copyFrom(pointerCoords[i]);
2529 }
2530 lastSample->eventTime = eventTime;
2531#if DEBUG_BATCHING
2532 LOGD("Coalesced motion into last sample of batch for %s, events were %0.3f ms apart",
2533 eventDescription, interval * 0.000001f);
2534#endif
2535 return;
2536 }
2537
2538 // Append the sample.
2539 mAllocator.appendMotionSample(entry, eventTime, pointerCoords);
2540#if DEBUG_BATCHING
2541 LOGD("Appended motion sample onto batch for %s, events were %0.3f ms apart",
2542 eventDescription, interval * 0.000001f);
2543#endif
2544}
2545
Jeff Brownb6997262010-10-08 22:31:17 -07002546void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2547 uint32_t policyFlags) {
2548#if DEBUG_INBOUND_EVENT_DETAILS
2549 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2550 switchCode, switchValue, policyFlags);
2551#endif
2552
Jeff Browne20c9e02010-10-11 14:20:19 -07002553 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002554 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2555}
2556
Jeff Brown7fbdc842010-06-17 20:52:56 -07002557int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002558 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002559#if DEBUG_INBOUND_EVENT_DETAILS
2560 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002561 "syncMode=%d, timeoutMillis=%d",
2562 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002563#endif
2564
2565 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Browne20c9e02010-10-11 14:20:19 -07002566
2567 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2568 if (hasInjectionPermission(injectorPid, injectorUid)) {
2569 policyFlags |= POLICY_FLAG_TRUSTED;
2570 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002571
Jeff Brownb6997262010-10-08 22:31:17 -07002572 EventEntry* injectedEntry;
2573 switch (event->getType()) {
2574 case AINPUT_EVENT_TYPE_KEY: {
2575 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2576 int32_t action = keyEvent->getAction();
2577 if (! validateKeyEvent(action)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002578 return INPUT_EVENT_INJECTION_FAILED;
2579 }
2580
Jeff Brownb6997262010-10-08 22:31:17 -07002581 int32_t flags = keyEvent->getFlags();
Jeff Brown1f245102010-11-18 20:53:46 -08002582 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2583 policyFlags |= POLICY_FLAG_VIRTUAL;
2584 }
2585
2586 mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
2587
2588 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2589 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2590 }
Jeff Brown6ec402b2010-07-28 15:48:59 -07002591
Jeff Brownb6997262010-10-08 22:31:17 -07002592 mLock.lock();
Jeff Brown1f245102010-11-18 20:53:46 -08002593 injectedEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
2594 keyEvent->getDeviceId(), keyEvent->getSource(),
2595 policyFlags, action, flags,
2596 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
Jeff Brownb6997262010-10-08 22:31:17 -07002597 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2598 break;
2599 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002600
Jeff Brownb6997262010-10-08 22:31:17 -07002601 case AINPUT_EVENT_TYPE_MOTION: {
2602 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2603 int32_t action = motionEvent->getAction();
2604 size_t pointerCount = motionEvent->getPointerCount();
2605 const int32_t* pointerIds = motionEvent->getPointerIds();
2606 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2607 return INPUT_EVENT_INJECTION_FAILED;
2608 }
2609
2610 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Brown56194eb2011-03-02 19:23:13 -08002611 mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002612
2613 mLock.lock();
2614 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2615 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2616 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2617 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2618 action, motionEvent->getFlags(),
2619 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2620 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2621 motionEvent->getDownTime(), uint32_t(pointerCount),
2622 pointerIds, samplePointerCoords);
2623 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2624 sampleEventTimes += 1;
2625 samplePointerCoords += pointerCount;
2626 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2627 }
2628 injectedEntry = motionEntry;
2629 break;
2630 }
2631
2632 default:
2633 LOGW("Cannot inject event of type %d", event->getType());
2634 return INPUT_EVENT_INJECTION_FAILED;
2635 }
2636
2637 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2638 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2639 injectionState->injectionIsAsync = true;
2640 }
2641
2642 injectionState->refCount += 1;
2643 injectedEntry->injectionState = injectionState;
2644
2645 bool needWake = enqueueInboundEventLocked(injectedEntry);
2646 mLock.unlock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002647
Jeff Brownb88102f2010-09-08 11:49:43 -07002648 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002649 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002650 }
2651
2652 int32_t injectionResult;
2653 { // acquire lock
2654 AutoMutex _l(mLock);
2655
Jeff Brown6ec402b2010-07-28 15:48:59 -07002656 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2657 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2658 } else {
2659 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002660 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002661 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2662 break;
2663 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002664
Jeff Brown7fbdc842010-06-17 20:52:56 -07002665 nsecs_t remainingTimeout = endTime - now();
2666 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002667#if DEBUG_INJECTION
2668 LOGD("injectInputEvent - Timed out waiting for injection result "
2669 "to become available.");
2670#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002671 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2672 break;
2673 }
2674
Jeff Brown6ec402b2010-07-28 15:48:59 -07002675 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2676 }
2677
2678 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2679 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002680 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002681#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002682 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002683 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002684#endif
2685 nsecs_t remainingTimeout = endTime - now();
2686 if (remainingTimeout <= 0) {
2687#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002688 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002689 "dispatches to finish.");
2690#endif
2691 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2692 break;
2693 }
2694
2695 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2696 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002697 }
2698 }
2699
Jeff Brown01ce2e92010-09-26 22:20:12 -07002700 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002701 } // release lock
2702
Jeff Brown6ec402b2010-07-28 15:48:59 -07002703#if DEBUG_INJECTION
2704 LOGD("injectInputEvent - Finished with result %d. "
2705 "injectorPid=%d, injectorUid=%d",
2706 injectionResult, injectorPid, injectorUid);
2707#endif
2708
Jeff Brown7fbdc842010-06-17 20:52:56 -07002709 return injectionResult;
2710}
2711
Jeff Brownb6997262010-10-08 22:31:17 -07002712bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2713 return injectorUid == 0
2714 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2715}
2716
Jeff Brown7fbdc842010-06-17 20:52:56 -07002717void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002718 InjectionState* injectionState = entry->injectionState;
2719 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002720#if DEBUG_INJECTION
2721 LOGD("Setting input event injection result to %d. "
2722 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002723 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002724#endif
2725
Jeff Brown01ce2e92010-09-26 22:20:12 -07002726 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002727 // Log the outcome since the injector did not wait for the injection result.
2728 switch (injectionResult) {
2729 case INPUT_EVENT_INJECTION_SUCCEEDED:
2730 LOGV("Asynchronous input event injection succeeded.");
2731 break;
2732 case INPUT_EVENT_INJECTION_FAILED:
2733 LOGW("Asynchronous input event injection failed.");
2734 break;
2735 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2736 LOGW("Asynchronous input event injection permission denied.");
2737 break;
2738 case INPUT_EVENT_INJECTION_TIMED_OUT:
2739 LOGW("Asynchronous input event injection timed out.");
2740 break;
2741 }
2742 }
2743
Jeff Brown01ce2e92010-09-26 22:20:12 -07002744 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002745 mInjectionResultAvailableCondition.broadcast();
2746 }
2747}
2748
Jeff Brown01ce2e92010-09-26 22:20:12 -07002749void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2750 InjectionState* injectionState = entry->injectionState;
2751 if (injectionState) {
2752 injectionState->pendingForegroundDispatches += 1;
2753 }
2754}
2755
Jeff Brown519e0242010-09-15 15:18:56 -07002756void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002757 InjectionState* injectionState = entry->injectionState;
2758 if (injectionState) {
2759 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002760
Jeff Brown01ce2e92010-09-26 22:20:12 -07002761 if (injectionState->pendingForegroundDispatches == 0) {
2762 mInjectionSyncFinishedCondition.broadcast();
2763 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002764 }
2765}
2766
Jeff Brown01ce2e92010-09-26 22:20:12 -07002767const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2768 for (size_t i = 0; i < mWindows.size(); i++) {
2769 const InputWindow* window = & mWindows[i];
2770 if (window->inputChannel == inputChannel) {
2771 return window;
2772 }
2773 }
2774 return NULL;
2775}
2776
Jeff Brownb88102f2010-09-08 11:49:43 -07002777void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2778#if DEBUG_FOCUS
2779 LOGD("setInputWindows");
2780#endif
2781 { // acquire lock
2782 AutoMutex _l(mLock);
2783
Jeff Brown01ce2e92010-09-26 22:20:12 -07002784 // Clear old window pointers.
Jeff Brownb6997262010-10-08 22:31:17 -07002785 sp<InputChannel> oldFocusedWindowChannel;
2786 if (mFocusedWindow) {
2787 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2788 mFocusedWindow = NULL;
2789 }
2790
Jeff Brownb88102f2010-09-08 11:49:43 -07002791 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002792
2793 // Loop over new windows and rebuild the necessary window pointers for
2794 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002795 mWindows.appendVector(inputWindows);
2796
2797 size_t numWindows = mWindows.size();
2798 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002799 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002800 if (window->hasFocus) {
2801 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002802 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002803 }
2804 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002805
Jeff Brownb6997262010-10-08 22:31:17 -07002806 if (oldFocusedWindowChannel != NULL) {
2807 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2808#if DEBUG_FOCUS
2809 LOGD("Focus left window: %s",
2810 oldFocusedWindowChannel->getName().string());
2811#endif
Jeff Brown524ee642011-03-29 15:11:34 -07002812 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
2813 "focus left window");
2814 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel, options);
Jeff Brownb6997262010-10-08 22:31:17 -07002815 oldFocusedWindowChannel.clear();
2816 }
2817 }
2818 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2819#if DEBUG_FOCUS
2820 LOGD("Focus entered window: %s",
2821 mFocusedWindow->inputChannel->getName().string());
2822#endif
2823 }
2824
Jeff Brown01ce2e92010-09-26 22:20:12 -07002825 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2826 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2827 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2828 if (window) {
2829 touchedWindow.window = window;
2830 i += 1;
2831 } else {
Jeff Brownb6997262010-10-08 22:31:17 -07002832#if DEBUG_FOCUS
2833 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2834#endif
Jeff Brown524ee642011-03-29 15:11:34 -07002835 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
2836 "touched window was removed");
2837 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel, options);
Jeff Brownaf48cae2010-10-15 16:20:51 -07002838 mTouchState.windows.removeAt(i);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002839 }
2840 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002841
Jeff Brownb88102f2010-09-08 11:49:43 -07002842#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002843 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002844#endif
2845 } // release lock
2846
2847 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002848 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002849}
2850
2851void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2852#if DEBUG_FOCUS
2853 LOGD("setFocusedApplication");
2854#endif
2855 { // acquire lock
2856 AutoMutex _l(mLock);
2857
2858 releaseFocusedApplicationLocked();
2859
2860 if (inputApplication) {
2861 mFocusedApplicationStorage = *inputApplication;
2862 mFocusedApplication = & mFocusedApplicationStorage;
2863 }
2864
2865#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002866 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002867#endif
2868 } // release lock
2869
2870 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002871 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002872}
2873
2874void InputDispatcher::releaseFocusedApplicationLocked() {
2875 if (mFocusedApplication) {
2876 mFocusedApplication = NULL;
Jeff Brown928e0542011-01-10 11:17:36 -08002877 mFocusedApplicationStorage.inputApplicationHandle.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -07002878 }
2879}
2880
2881void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2882#if DEBUG_FOCUS
2883 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2884#endif
2885
2886 bool changed;
2887 { // acquire lock
2888 AutoMutex _l(mLock);
2889
2890 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brown120a4592010-10-27 18:43:51 -07002891 if (mDispatchFrozen && !frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002892 resetANRTimeoutsLocked();
2893 }
2894
Jeff Brown120a4592010-10-27 18:43:51 -07002895 if (mDispatchEnabled && !enabled) {
2896 resetAndDropEverythingLocked("dispatcher is being disabled");
2897 }
2898
Jeff Brownb88102f2010-09-08 11:49:43 -07002899 mDispatchEnabled = enabled;
2900 mDispatchFrozen = frozen;
2901 changed = true;
2902 } else {
2903 changed = false;
2904 }
2905
2906#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002907 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002908#endif
2909 } // release lock
2910
2911 if (changed) {
2912 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002913 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002914 }
2915}
2916
Jeff Browne6504122010-09-27 14:52:15 -07002917bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2918 const sp<InputChannel>& toChannel) {
2919#if DEBUG_FOCUS
2920 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2921 fromChannel->getName().string(), toChannel->getName().string());
2922#endif
2923 { // acquire lock
2924 AutoMutex _l(mLock);
2925
2926 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2927 const InputWindow* toWindow = getWindowLocked(toChannel);
2928 if (! fromWindow || ! toWindow) {
2929#if DEBUG_FOCUS
2930 LOGD("Cannot transfer focus because from or to window not found.");
2931#endif
2932 return false;
2933 }
2934 if (fromWindow == toWindow) {
2935#if DEBUG_FOCUS
2936 LOGD("Trivial transfer to same window.");
2937#endif
2938 return true;
2939 }
2940
2941 bool found = false;
2942 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2943 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2944 if (touchedWindow.window == fromWindow) {
2945 int32_t oldTargetFlags = touchedWindow.targetFlags;
2946 BitSet32 pointerIds = touchedWindow.pointerIds;
2947
2948 mTouchState.windows.removeAt(i);
2949
Jeff Brown46e75292010-11-10 16:53:45 -08002950 int32_t newTargetFlags = oldTargetFlags
2951 & (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT);
Jeff Browne6504122010-09-27 14:52:15 -07002952 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2953
2954 found = true;
2955 break;
2956 }
2957 }
2958
2959 if (! found) {
2960#if DEBUG_FOCUS
2961 LOGD("Focus transfer failed because from window did not have focus.");
2962#endif
2963 return false;
2964 }
2965
Jeff Brown9c9f1a32010-10-11 18:32:20 -07002966 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2967 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2968 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2969 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2970 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2971
2972 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
Jeff Brown524ee642011-03-29 15:11:34 -07002973 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Jeff Brown9c9f1a32010-10-11 18:32:20 -07002974 "transferring touch focus from this window to another window");
Jeff Brown524ee642011-03-29 15:11:34 -07002975 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Jeff Brown9c9f1a32010-10-11 18:32:20 -07002976 }
2977
Jeff Browne6504122010-09-27 14:52:15 -07002978#if DEBUG_FOCUS
2979 logDispatchStateLocked();
2980#endif
2981 } // release lock
2982
2983 // Wake up poll loop since it may need to make new input dispatching choices.
2984 mLooper->wake();
2985 return true;
2986}
2987
Jeff Brown120a4592010-10-27 18:43:51 -07002988void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2989#if DEBUG_FOCUS
2990 LOGD("Resetting and dropping all events (%s).", reason);
2991#endif
2992
Jeff Brown524ee642011-03-29 15:11:34 -07002993 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
2994 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Brown120a4592010-10-27 18:43:51 -07002995
2996 resetKeyRepeatLocked();
2997 releasePendingEventLocked();
2998 drainInboundQueueLocked();
2999 resetTargetsLocked();
3000
3001 mTouchState.reset();
3002}
3003
Jeff Brownb88102f2010-09-08 11:49:43 -07003004void InputDispatcher::logDispatchStateLocked() {
3005 String8 dump;
3006 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07003007
3008 char* text = dump.lockBuffer(dump.size());
3009 char* start = text;
3010 while (*start != '\0') {
3011 char* end = strchr(start, '\n');
3012 if (*end == '\n') {
3013 *(end++) = '\0';
3014 }
3015 LOGD("%s", start);
3016 start = end;
3017 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003018}
3019
3020void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003021 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
3022 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07003023
3024 if (mFocusedApplication) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003025 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07003026 mFocusedApplication->name.string(),
3027 mFocusedApplication->dispatchingTimeout / 1000000.0);
3028 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07003029 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003030 }
Jeff Brownf2f487182010-10-01 17:46:21 -07003031 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07003032 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f487182010-10-01 17:46:21 -07003033
3034 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
3035 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
Jeff Brown95712852011-01-04 19:41:59 -08003036 dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
Jeff Brown58a2da82011-01-25 16:02:22 -08003037 dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
Jeff Brownf2f487182010-10-01 17:46:21 -07003038 if (!mTouchState.windows.isEmpty()) {
3039 dump.append(INDENT "TouchedWindows:\n");
3040 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
3041 const TouchedWindow& touchedWindow = mTouchState.windows[i];
3042 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3043 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
3044 touchedWindow.targetFlags);
3045 }
3046 } else {
3047 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003048 }
3049
Jeff Brownf2f487182010-10-01 17:46:21 -07003050 if (!mWindows.isEmpty()) {
3051 dump.append(INDENT "Windows:\n");
3052 for (size_t i = 0; i < mWindows.size(); i++) {
3053 const InputWindow& window = mWindows[i];
3054 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
3055 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003056 "frame=[%d,%d][%d,%d], scale=%f, "
Jeff Brownfbf09772011-01-16 14:06:57 -08003057 "touchableRegion=",
Jeff Brownf2f487182010-10-01 17:46:21 -07003058 i, window.name.string(),
3059 toString(window.paused),
3060 toString(window.hasFocus),
3061 toString(window.hasWallpaper),
3062 toString(window.visible),
3063 toString(window.canReceiveKeys),
3064 window.layoutParamsFlags, window.layoutParamsType,
3065 window.layer,
3066 window.frameLeft, window.frameTop,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003067 window.frameRight, window.frameBottom,
3068 window.scaleFactor);
Jeff Brownfbf09772011-01-16 14:06:57 -08003069 dumpRegion(dump, window.touchableRegion);
3070 dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07003071 window.ownerPid, window.ownerUid,
3072 window.dispatchingTimeout / 1000000.0);
3073 }
3074 } else {
3075 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003076 }
3077
Jeff Brownf2f487182010-10-01 17:46:21 -07003078 if (!mMonitoringChannels.isEmpty()) {
3079 dump.append(INDENT "MonitoringChannels:\n");
3080 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3081 const sp<InputChannel>& channel = mMonitoringChannels[i];
3082 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
3083 }
3084 } else {
3085 dump.append(INDENT "MonitoringChannels: <none>\n");
3086 }
Jeff Brown519e0242010-09-15 15:18:56 -07003087
Jeff Brownf2f487182010-10-01 17:46:21 -07003088 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
3089
3090 if (!mActiveConnections.isEmpty()) {
3091 dump.append(INDENT "ActiveConnections:\n");
3092 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3093 const Connection* connection = mActiveConnections[i];
Jeff Brown76860e32010-10-25 17:37:46 -07003094 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brownb6997262010-10-08 22:31:17 -07003095 "inputState.isNeutral=%s\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07003096 i, connection->getInputChannelName(), connection->getStatusLabel(),
3097 connection->outboundQueue.count(),
Jeff Brownb6997262010-10-08 22:31:17 -07003098 toString(connection->inputState.isNeutral()));
Jeff Brownf2f487182010-10-01 17:46:21 -07003099 }
3100 } else {
3101 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003102 }
3103
3104 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003105 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07003106 (mAppSwitchDueTime - now()) / 1000000.0);
3107 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07003108 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003109 }
3110}
3111
Jeff Brown928e0542011-01-10 11:17:36 -08003112status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
3113 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003114#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07003115 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
3116 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07003117#endif
3118
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003119 { // acquire lock
3120 AutoMutex _l(mLock);
3121
Jeff Brown519e0242010-09-15 15:18:56 -07003122 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003123 LOGW("Attempted to register already registered input channel '%s'",
3124 inputChannel->getName().string());
3125 return BAD_VALUE;
3126 }
3127
Jeff Brown928e0542011-01-10 11:17:36 -08003128 sp<Connection> connection = new Connection(inputChannel, inputWindowHandle);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003129 status_t status = connection->initialize();
3130 if (status) {
3131 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
3132 inputChannel->getName().string(), status);
3133 return status;
3134 }
3135
Jeff Brown2cbecea2010-08-17 15:59:26 -07003136 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003137 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003138
Jeff Brownb88102f2010-09-08 11:49:43 -07003139 if (monitor) {
3140 mMonitoringChannels.push(inputChannel);
3141 }
3142
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003143 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07003144
Jeff Brown9c3cda02010-06-15 01:31:58 -07003145 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003146 } // release lock
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003147 return OK;
3148}
3149
3150status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003151#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07003152 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07003153#endif
3154
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003155 { // acquire lock
3156 AutoMutex _l(mLock);
3157
Jeff Brown519e0242010-09-15 15:18:56 -07003158 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003159 if (connectionIndex < 0) {
3160 LOGW("Attempted to unregister already unregistered input channel '%s'",
3161 inputChannel->getName().string());
3162 return BAD_VALUE;
3163 }
3164
3165 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3166 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
3167
3168 connection->status = Connection::STATUS_ZOMBIE;
3169
Jeff Brownb88102f2010-09-08 11:49:43 -07003170 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3171 if (mMonitoringChannels[i] == inputChannel) {
3172 mMonitoringChannels.removeAt(i);
3173 break;
3174 }
3175 }
3176
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003177 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07003178
Jeff Brown7fbdc842010-06-17 20:52:56 -07003179 nsecs_t currentTime = now();
Jeff Brownb6997262010-10-08 22:31:17 -07003180 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003181
3182 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003183 } // release lock
3184
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003185 // Wake the poll loop because removing the connection may have changed the current
3186 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003187 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003188 return OK;
3189}
3190
Jeff Brown519e0242010-09-15 15:18:56 -07003191ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07003192 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
3193 if (connectionIndex >= 0) {
3194 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3195 if (connection->inputChannel.get() == inputChannel.get()) {
3196 return connectionIndex;
3197 }
3198 }
3199
3200 return -1;
3201}
3202
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003203void InputDispatcher::activateConnectionLocked(Connection* connection) {
3204 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3205 if (mActiveConnections.itemAt(i) == connection) {
3206 return;
3207 }
3208 }
3209 mActiveConnections.add(connection);
3210}
3211
3212void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
3213 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3214 if (mActiveConnections.itemAt(i) == connection) {
3215 mActiveConnections.removeAt(i);
3216 return;
3217 }
3218 }
3219}
3220
Jeff Brown9c3cda02010-06-15 01:31:58 -07003221void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003222 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003223}
3224
Jeff Brown9c3cda02010-06-15 01:31:58 -07003225void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown3915bb82010-11-05 15:02:16 -07003226 nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
3227 CommandEntry* commandEntry = postCommandLocked(
3228 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
3229 commandEntry->connection = connection;
3230 commandEntry->handled = handled;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003231}
3232
Jeff Brown9c3cda02010-06-15 01:31:58 -07003233void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003234 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003235 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3236 connection->getInputChannelName());
3237
Jeff Brown9c3cda02010-06-15 01:31:58 -07003238 CommandEntry* commandEntry = postCommandLocked(
3239 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003240 commandEntry->connection = connection;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003241}
3242
Jeff Brown519e0242010-09-15 15:18:56 -07003243void InputDispatcher::onANRLocked(
3244 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
3245 nsecs_t eventTime, nsecs_t waitStartTime) {
3246 LOGI("Application is not responding: %s. "
3247 "%01.1fms since event, %01.1fms since wait started",
3248 getApplicationWindowLabelLocked(application, window).string(),
3249 (currentTime - eventTime) / 1000000.0,
3250 (currentTime - waitStartTime) / 1000000.0);
3251
3252 CommandEntry* commandEntry = postCommandLocked(
3253 & InputDispatcher::doNotifyANRLockedInterruptible);
3254 if (application) {
Jeff Brown928e0542011-01-10 11:17:36 -08003255 commandEntry->inputApplicationHandle = application->inputApplicationHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003256 }
3257 if (window) {
Jeff Brown928e0542011-01-10 11:17:36 -08003258 commandEntry->inputWindowHandle = window->inputWindowHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003259 commandEntry->inputChannel = window->inputChannel;
3260 }
3261}
3262
Jeff Brownb88102f2010-09-08 11:49:43 -07003263void InputDispatcher::doNotifyConfigurationChangedInterruptible(
3264 CommandEntry* commandEntry) {
3265 mLock.unlock();
3266
3267 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
3268
3269 mLock.lock();
3270}
3271
Jeff Brown9c3cda02010-06-15 01:31:58 -07003272void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
3273 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003274 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07003275
Jeff Brown7fbdc842010-06-17 20:52:56 -07003276 if (connection->status != Connection::STATUS_ZOMBIE) {
3277 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003278
Jeff Brown928e0542011-01-10 11:17:36 -08003279 mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003280
3281 mLock.lock();
3282 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07003283}
3284
Jeff Brown519e0242010-09-15 15:18:56 -07003285void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07003286 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07003287 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003288
Jeff Brown519e0242010-09-15 15:18:56 -07003289 nsecs_t newTimeout = mPolicy->notifyANR(
Jeff Brown928e0542011-01-10 11:17:36 -08003290 commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003291
Jeff Brown519e0242010-09-15 15:18:56 -07003292 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07003293
Jeff Brown519e0242010-09-15 15:18:56 -07003294 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003295}
3296
Jeff Brownb88102f2010-09-08 11:49:43 -07003297void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3298 CommandEntry* commandEntry) {
3299 KeyEntry* entry = commandEntry->keyEntry;
Jeff Brown1f245102010-11-18 20:53:46 -08003300
3301 KeyEvent event;
3302 initializeKeyEvent(&event, entry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003303
3304 mLock.unlock();
3305
Jeff Brown928e0542011-01-10 11:17:36 -08003306 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
Jeff Brown1f245102010-11-18 20:53:46 -08003307 &event, entry->policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -07003308
3309 mLock.lock();
3310
3311 entry->interceptKeyResult = consumed
3312 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
3313 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3314 mAllocator.releaseKeyEntry(entry);
3315}
3316
Jeff Brown3915bb82010-11-05 15:02:16 -07003317void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3318 CommandEntry* commandEntry) {
3319 sp<Connection> connection = commandEntry->connection;
3320 bool handled = commandEntry->handled;
3321
Jeff Brown49ed71d2010-12-06 17:13:33 -08003322 if (!connection->outboundQueue.isEmpty()) {
Jeff Brown3915bb82010-11-05 15:02:16 -07003323 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
3324 if (dispatchEntry->inProgress
Jeff Brown3915bb82010-11-05 15:02:16 -07003325 && dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3326 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003327 if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
Jeff Brown524ee642011-03-29 15:11:34 -07003328 // Get the fallback key state.
3329 // Clear it out after dispatching the UP.
3330 int32_t originalKeyCode = keyEntry->keyCode;
3331 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
3332 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
3333 connection->inputState.removeFallbackKey(originalKeyCode);
3334 }
3335
3336 if (handled || !dispatchEntry->hasForegroundTarget()) {
3337 // If the application handles the original key for which we previously
3338 // generated a fallback or if the window is not a foreground window,
3339 // then cancel the associated fallback key, if any.
3340 if (fallbackKeyCode != -1) {
3341 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
3342 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
3343 "application handled the original non-fallback key "
3344 "or is no longer a foreground target, "
3345 "canceling previously dispatched fallback key");
3346 options.keyCode = fallbackKeyCode;
3347 synthesizeCancelationEventsForConnectionLocked(connection, options);
3348 }
3349 connection->inputState.removeFallbackKey(originalKeyCode);
3350 }
Jeff Brown49ed71d2010-12-06 17:13:33 -08003351 } else {
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003352 // If the application did not handle a non-fallback key, first check
Jeff Brown524ee642011-03-29 15:11:34 -07003353 // that we are in a good state to perform unhandled key event processing
3354 // Then ask the policy what to do with it.
3355 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
3356 && keyEntry->repeatCount == 0;
3357 if (fallbackKeyCode == -1 && !initialDown) {
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003358#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown524ee642011-03-29 15:11:34 -07003359 LOGD("Unhandled key event: Skipping unhandled key event processing "
3360 "since this is not an initial down. "
3361 "keyCode=%d, action=%d, repeatCount=%d",
3362 originalKeyCode, keyEntry->action, keyEntry->repeatCount);
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003363#endif
Jeff Brown524ee642011-03-29 15:11:34 -07003364 goto SkipFallback;
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003365 }
3366
Jeff Brown524ee642011-03-29 15:11:34 -07003367 // Dispatch the unhandled key to the policy.
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003368#if DEBUG_OUTBOUND_EVENT_DETAILS
3369 LOGD("Unhandled key event: Asking policy to perform fallback action. "
3370 "keyCode=%d, action=%d, repeatCount=%d",
3371 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount);
3372#endif
Jeff Brown49ed71d2010-12-06 17:13:33 -08003373 KeyEvent event;
3374 initializeKeyEvent(&event, keyEntry);
Jeff Brown3915bb82010-11-05 15:02:16 -07003375
Jeff Brown49ed71d2010-12-06 17:13:33 -08003376 mLock.unlock();
Jeff Brown3915bb82010-11-05 15:02:16 -07003377
Jeff Brown928e0542011-01-10 11:17:36 -08003378 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003379 &event, keyEntry->policyFlags, &event);
Jeff Brown3915bb82010-11-05 15:02:16 -07003380
Jeff Brown49ed71d2010-12-06 17:13:33 -08003381 mLock.lock();
3382
Jeff Brown00045a72010-12-09 18:10:30 -08003383 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brown524ee642011-03-29 15:11:34 -07003384 connection->inputState.removeFallbackKey(originalKeyCode);
Jeff Brown00045a72010-12-09 18:10:30 -08003385 return;
3386 }
3387
3388 assert(connection->outboundQueue.headSentinel.next == dispatchEntry);
3389
Jeff Brown524ee642011-03-29 15:11:34 -07003390 // Latch the fallback keycode for this key on an initial down.
3391 // The fallback keycode cannot change at any other point in the lifecycle.
3392 if (initialDown) {
3393 if (fallback) {
3394 fallbackKeyCode = event.getKeyCode();
3395 } else {
3396 fallbackKeyCode = AKEYCODE_UNKNOWN;
3397 }
3398 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
3399 }
3400
3401 assert(fallbackKeyCode != -1);
3402
3403 // Cancel the fallback key if the policy decides not to send it anymore.
3404 // We will continue to dispatch the key to the policy but we will no
3405 // longer dispatch a fallback key to the application.
3406 if (fallbackKeyCode != AKEYCODE_UNKNOWN
3407 && (!fallback || fallbackKeyCode != event.getKeyCode())) {
3408#if DEBUG_OUTBOUND_EVENT_DETAILS
3409 if (fallback) {
3410 LOGD("Unhandled key event: Policy requested to send key %d"
3411 "as a fallback for %d, but on the DOWN it had requested "
3412 "to send %d instead. Fallback canceled.",
3413 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
3414 } else {
3415 LOGD("Unhandled key event: Policy did not request fallback for %d,"
3416 "but on the DOWN it had requested to send %d. "
3417 "Fallback canceled.",
3418 originalKeyCode, fallbackKeyCode);
3419 }
3420#endif
3421
3422 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
3423 "canceling fallback, policy no longer desires it");
3424 options.keyCode = fallbackKeyCode;
3425 synthesizeCancelationEventsForConnectionLocked(connection, options);
3426
3427 fallback = false;
3428 fallbackKeyCode = AKEYCODE_UNKNOWN;
3429 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
3430 connection->inputState.setFallbackKey(originalKeyCode,
3431 fallbackKeyCode);
3432 }
3433 }
3434
3435#if DEBUG_OUTBOUND_EVENT_DETAILS
3436 {
3437 String8 msg;
3438 const KeyedVector<int32_t, int32_t>& fallbackKeys =
3439 connection->inputState.getFallbackKeys();
3440 for (size_t i = 0; i < fallbackKeys.size(); i++) {
3441 msg.appendFormat(", %d->%d", fallbackKeys.keyAt(i),
3442 fallbackKeys.valueAt(i));
3443 }
3444 LOGD("Unhandled key event: %d currently tracked fallback keys%s.",
3445 fallbackKeys.size(), msg.string());
3446 }
3447#endif
3448
Jeff Brown49ed71d2010-12-06 17:13:33 -08003449 if (fallback) {
3450 // Restart the dispatch cycle using the fallback key.
3451 keyEntry->eventTime = event.getEventTime();
3452 keyEntry->deviceId = event.getDeviceId();
3453 keyEntry->source = event.getSource();
3454 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
Jeff Brown524ee642011-03-29 15:11:34 -07003455 keyEntry->keyCode = fallbackKeyCode;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003456 keyEntry->scanCode = event.getScanCode();
3457 keyEntry->metaState = event.getMetaState();
3458 keyEntry->repeatCount = event.getRepeatCount();
3459 keyEntry->downTime = event.getDownTime();
3460 keyEntry->syntheticRepeat = false;
3461
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003462#if DEBUG_OUTBOUND_EVENT_DETAILS
3463 LOGD("Unhandled key event: Dispatching fallback key. "
Jeff Brown524ee642011-03-29 15:11:34 -07003464 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
3465 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003466#endif
3467
Jeff Brown49ed71d2010-12-06 17:13:33 -08003468 dispatchEntry->inProgress = false;
3469 startDispatchCycleLocked(now(), connection);
3470 return;
Jeff Brown524ee642011-03-29 15:11:34 -07003471 } else {
3472#if DEBUG_OUTBOUND_EVENT_DETAILS
3473 LOGD("Unhandled key event: No fallback key.");
3474#endif
Jeff Brown49ed71d2010-12-06 17:13:33 -08003475 }
3476 }
3477 }
Jeff Brown3915bb82010-11-05 15:02:16 -07003478 }
3479 }
3480
Jeff Brownbfaf3b92011-02-22 15:00:50 -08003481SkipFallback:
Jeff Brown3915bb82010-11-05 15:02:16 -07003482 startNextDispatchCycleLocked(now(), connection);
3483}
3484
Jeff Brownb88102f2010-09-08 11:49:43 -07003485void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3486 mLock.unlock();
3487
Jeff Brown01ce2e92010-09-26 22:20:12 -07003488 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07003489
3490 mLock.lock();
3491}
3492
Jeff Brown3915bb82010-11-05 15:02:16 -07003493void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
3494 event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3495 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3496 entry->downTime, entry->eventTime);
3497}
3498
Jeff Brown519e0242010-09-15 15:18:56 -07003499void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3500 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3501 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07003502}
3503
3504void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003505 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003506 dumpDispatchStateLocked(dump);
Jeff Brown214eaf42011-05-26 19:17:02 -07003507
3508 dump.append(INDENT "Configuration:\n");
3509 dump.appendFormat(INDENT2 "MaxEventsPerSecond: %d\n", mConfig.maxEventsPerSecond);
3510 dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
3511 dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n", mConfig.keyRepeatTimeout * 0.000001f);
Jeff Brownb88102f2010-09-08 11:49:43 -07003512}
3513
Jeff Brown9c3cda02010-06-15 01:31:58 -07003514
Jeff Brown519e0242010-09-15 15:18:56 -07003515// --- InputDispatcher::Queue ---
3516
3517template <typename T>
3518uint32_t InputDispatcher::Queue<T>::count() const {
3519 uint32_t result = 0;
3520 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3521 result += 1;
3522 }
3523 return result;
3524}
3525
3526
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003527// --- InputDispatcher::Allocator ---
3528
3529InputDispatcher::Allocator::Allocator() {
3530}
3531
Jeff Brown01ce2e92010-09-26 22:20:12 -07003532InputDispatcher::InjectionState*
3533InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3534 InjectionState* injectionState = mInjectionStatePool.alloc();
3535 injectionState->refCount = 1;
3536 injectionState->injectorPid = injectorPid;
3537 injectionState->injectorUid = injectorUid;
3538 injectionState->injectionIsAsync = false;
3539 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3540 injectionState->pendingForegroundDispatches = 0;
3541 return injectionState;
3542}
3543
Jeff Brown7fbdc842010-06-17 20:52:56 -07003544void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brownb6997262010-10-08 22:31:17 -07003545 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003546 entry->type = type;
3547 entry->refCount = 1;
3548 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07003549 entry->eventTime = eventTime;
Jeff Brownb6997262010-10-08 22:31:17 -07003550 entry->policyFlags = policyFlags;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003551 entry->injectionState = NULL;
3552}
3553
3554void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3555 if (entry->injectionState) {
3556 releaseInjectionState(entry->injectionState);
3557 entry->injectionState = NULL;
3558 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07003559}
3560
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003561InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07003562InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003563 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003564 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003565 return entry;
3566}
3567
Jeff Brown7fbdc842010-06-17 20:52:56 -07003568InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown58a2da82011-01-25 16:02:22 -08003569 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003570 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3571 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003572 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003573 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003574
3575 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003576 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003577 entry->action = action;
3578 entry->flags = flags;
3579 entry->keyCode = keyCode;
3580 entry->scanCode = scanCode;
3581 entry->metaState = metaState;
3582 entry->repeatCount = repeatCount;
3583 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003584 entry->syntheticRepeat = false;
3585 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003586 return entry;
3587}
3588
Jeff Brown7fbdc842010-06-17 20:52:56 -07003589InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown58a2da82011-01-25 16:02:22 -08003590 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003591 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3592 nsecs_t downTime, uint32_t pointerCount,
3593 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003594 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003595 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003596
3597 entry->eventTime = eventTime;
3598 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003599 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003600 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07003601 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003602 entry->metaState = metaState;
3603 entry->edgeFlags = edgeFlags;
3604 entry->xPrecision = xPrecision;
3605 entry->yPrecision = yPrecision;
3606 entry->downTime = downTime;
3607 entry->pointerCount = pointerCount;
3608 entry->firstSample.eventTime = eventTime;
Jeff Brown5ced76a2011-05-24 11:23:27 -07003609 entry->firstSample.eventTimeBeforeCoalescing = eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003610 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003611 entry->lastSample = & entry->firstSample;
3612 for (uint32_t i = 0; i < pointerCount; i++) {
3613 entry->pointerIds[i] = pointerIds[i];
Jeff Brown96ad3972011-03-09 17:39:48 -08003614 entry->firstSample.pointerCoords[i].copyFrom(pointerCoords[i]);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003615 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003616 return entry;
3617}
3618
3619InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07003620 EventEntry* eventEntry,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003621 int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003622 DispatchEntry* entry = mDispatchEntryPool.alloc();
3623 entry->eventEntry = eventEntry;
3624 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07003625 entry->targetFlags = targetFlags;
3626 entry->xOffset = xOffset;
3627 entry->yOffset = yOffset;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003628 entry->scaleFactor = scaleFactor;
Jeff Brownb88102f2010-09-08 11:49:43 -07003629 entry->inProgress = false;
3630 entry->headMotionSample = NULL;
3631 entry->tailMotionSample = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003632 return entry;
3633}
3634
Jeff Brown9c3cda02010-06-15 01:31:58 -07003635InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3636 CommandEntry* entry = mCommandEntryPool.alloc();
3637 entry->command = command;
3638 return entry;
3639}
3640
Jeff Brown01ce2e92010-09-26 22:20:12 -07003641void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3642 injectionState->refCount -= 1;
3643 if (injectionState->refCount == 0) {
3644 mInjectionStatePool.free(injectionState);
3645 } else {
3646 assert(injectionState->refCount > 0);
3647 }
3648}
3649
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003650void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3651 switch (entry->type) {
3652 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3653 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3654 break;
3655 case EventEntry::TYPE_KEY:
3656 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3657 break;
3658 case EventEntry::TYPE_MOTION:
3659 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3660 break;
3661 default:
3662 assert(false);
3663 break;
3664 }
3665}
3666
3667void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3668 ConfigurationChangedEntry* entry) {
3669 entry->refCount -= 1;
3670 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003671 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003672 mConfigurationChangeEntryPool.free(entry);
3673 } else {
3674 assert(entry->refCount > 0);
3675 }
3676}
3677
3678void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3679 entry->refCount -= 1;
3680 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003681 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003682 mKeyEntryPool.free(entry);
3683 } else {
3684 assert(entry->refCount > 0);
3685 }
3686}
3687
3688void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3689 entry->refCount -= 1;
3690 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003691 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003692 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3693 MotionSample* next = sample->next;
3694 mMotionSamplePool.free(sample);
3695 sample = next;
3696 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003697 mMotionEntryPool.free(entry);
3698 } else {
3699 assert(entry->refCount > 0);
3700 }
3701}
3702
3703void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3704 releaseEventEntry(entry->eventEntry);
3705 mDispatchEntryPool.free(entry);
3706}
3707
Jeff Brown9c3cda02010-06-15 01:31:58 -07003708void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3709 mCommandEntryPool.free(entry);
3710}
3711
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003712void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003713 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003714 MotionSample* sample = mMotionSamplePool.alloc();
3715 sample->eventTime = eventTime;
Jeff Brown5ced76a2011-05-24 11:23:27 -07003716 sample->eventTimeBeforeCoalescing = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003717 uint32_t pointerCount = motionEntry->pointerCount;
3718 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown96ad3972011-03-09 17:39:48 -08003719 sample->pointerCoords[i].copyFrom(pointerCoords[i]);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003720 }
3721
3722 sample->next = NULL;
3723 motionEntry->lastSample->next = sample;
3724 motionEntry->lastSample = sample;
3725}
3726
Jeff Brown01ce2e92010-09-26 22:20:12 -07003727void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3728 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003729
Jeff Brown01ce2e92010-09-26 22:20:12 -07003730 keyEntry->dispatchInProgress = false;
3731 keyEntry->syntheticRepeat = false;
3732 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003733}
3734
3735
Jeff Brownae9fc032010-08-18 15:51:08 -07003736// --- InputDispatcher::MotionEntry ---
3737
3738uint32_t InputDispatcher::MotionEntry::countSamples() const {
3739 uint32_t count = 1;
3740 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3741 count += 1;
3742 }
3743 return count;
3744}
3745
Jeff Brown5ced76a2011-05-24 11:23:27 -07003746bool InputDispatcher::MotionEntry::canAppendSamples(int32_t action, uint32_t pointerCount,
3747 const int32_t* pointerIds) const {
3748 if (this->action != action
3749 || this->pointerCount != pointerCount
3750 || this->isInjected()) {
3751 return false;
3752 }
3753 for (uint32_t i = 0; i < pointerCount; i++) {
3754 if (this->pointerIds[i] != pointerIds[i]) {
3755 return false;
3756 }
3757 }
3758 return true;
3759}
3760
Jeff Brownb88102f2010-09-08 11:49:43 -07003761
3762// --- InputDispatcher::InputState ---
3763
Jeff Brownb6997262010-10-08 22:31:17 -07003764InputDispatcher::InputState::InputState() {
Jeff Brownb88102f2010-09-08 11:49:43 -07003765}
3766
3767InputDispatcher::InputState::~InputState() {
3768}
3769
3770bool InputDispatcher::InputState::isNeutral() const {
3771 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3772}
3773
Jeff Browncc0c1592011-02-19 05:07:28 -08003774void InputDispatcher::InputState::trackEvent(
Jeff Brownb88102f2010-09-08 11:49:43 -07003775 const EventEntry* entry) {
3776 switch (entry->type) {
3777 case EventEntry::TYPE_KEY:
Jeff Browncc0c1592011-02-19 05:07:28 -08003778 trackKey(static_cast<const KeyEntry*>(entry));
3779 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07003780
3781 case EventEntry::TYPE_MOTION:
Jeff Browncc0c1592011-02-19 05:07:28 -08003782 trackMotion(static_cast<const MotionEntry*>(entry));
3783 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07003784 }
3785}
3786
Jeff Browncc0c1592011-02-19 05:07:28 -08003787void InputDispatcher::InputState::trackKey(
Jeff Brownb88102f2010-09-08 11:49:43 -07003788 const KeyEntry* entry) {
3789 int32_t action = entry->action;
Jeff Brown524ee642011-03-29 15:11:34 -07003790 if (action == AKEY_EVENT_ACTION_UP
3791 && (entry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
3792 for (size_t i = 0; i < mFallbackKeys.size(); ) {
3793 if (mFallbackKeys.valueAt(i) == entry->keyCode) {
3794 mFallbackKeys.removeItemsAt(i);
3795 } else {
3796 i += 1;
3797 }
3798 }
3799 }
3800
Jeff Brownb88102f2010-09-08 11:49:43 -07003801 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3802 KeyMemento& memento = mKeyMementos.editItemAt(i);
3803 if (memento.deviceId == entry->deviceId
3804 && memento.source == entry->source
3805 && memento.keyCode == entry->keyCode
3806 && memento.scanCode == entry->scanCode) {
3807 switch (action) {
3808 case AKEY_EVENT_ACTION_UP:
3809 mKeyMementos.removeAt(i);
Jeff Browncc0c1592011-02-19 05:07:28 -08003810 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003811
3812 case AKEY_EVENT_ACTION_DOWN:
Jeff Browncc0c1592011-02-19 05:07:28 -08003813 mKeyMementos.removeAt(i);
3814 goto Found;
Jeff Brownb88102f2010-09-08 11:49:43 -07003815
3816 default:
Jeff Browncc0c1592011-02-19 05:07:28 -08003817 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003818 }
3819 }
3820 }
3821
Jeff Browncc0c1592011-02-19 05:07:28 -08003822Found:
3823 if (action == AKEY_EVENT_ACTION_DOWN) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003824 mKeyMementos.push();
3825 KeyMemento& memento = mKeyMementos.editTop();
3826 memento.deviceId = entry->deviceId;
3827 memento.source = entry->source;
3828 memento.keyCode = entry->keyCode;
3829 memento.scanCode = entry->scanCode;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003830 memento.flags = entry->flags;
Jeff Brownb88102f2010-09-08 11:49:43 -07003831 memento.downTime = entry->downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003832 }
3833}
3834
Jeff Browncc0c1592011-02-19 05:07:28 -08003835void InputDispatcher::InputState::trackMotion(
Jeff Brownb88102f2010-09-08 11:49:43 -07003836 const MotionEntry* entry) {
3837 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3838 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3839 MotionMemento& memento = mMotionMementos.editItemAt(i);
3840 if (memento.deviceId == entry->deviceId
3841 && memento.source == entry->source) {
3842 switch (action) {
3843 case AMOTION_EVENT_ACTION_UP:
3844 case AMOTION_EVENT_ACTION_CANCEL:
Jeff Browncc0c1592011-02-19 05:07:28 -08003845 case AMOTION_EVENT_ACTION_HOVER_MOVE:
Jeff Brownb88102f2010-09-08 11:49:43 -07003846 mMotionMementos.removeAt(i);
Jeff Browncc0c1592011-02-19 05:07:28 -08003847 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003848
3849 case AMOTION_EVENT_ACTION_DOWN:
Jeff Browncc0c1592011-02-19 05:07:28 -08003850 mMotionMementos.removeAt(i);
3851 goto Found;
Jeff Brownb88102f2010-09-08 11:49:43 -07003852
3853 case AMOTION_EVENT_ACTION_POINTER_UP:
Jeff Browncc0c1592011-02-19 05:07:28 -08003854 case AMOTION_EVENT_ACTION_POINTER_DOWN:
Jeff Brownb88102f2010-09-08 11:49:43 -07003855 case AMOTION_EVENT_ACTION_MOVE:
Jeff Browncc0c1592011-02-19 05:07:28 -08003856 memento.setPointers(entry);
3857 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003858
3859 default:
Jeff Browncc0c1592011-02-19 05:07:28 -08003860 return;
Jeff Brownb88102f2010-09-08 11:49:43 -07003861 }
3862 }
3863 }
3864
Jeff Browncc0c1592011-02-19 05:07:28 -08003865Found:
3866 if (action == AMOTION_EVENT_ACTION_DOWN) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003867 mMotionMementos.push();
3868 MotionMemento& memento = mMotionMementos.editTop();
3869 memento.deviceId = entry->deviceId;
3870 memento.source = entry->source;
3871 memento.xPrecision = entry->xPrecision;
3872 memento.yPrecision = entry->yPrecision;
3873 memento.downTime = entry->downTime;
3874 memento.setPointers(entry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003875 }
3876}
3877
3878void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3879 pointerCount = entry->pointerCount;
3880 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3881 pointerIds[i] = entry->pointerIds[i];
Jeff Brown96ad3972011-03-09 17:39:48 -08003882 pointerCoords[i].copyFrom(entry->lastSample->pointerCoords[i]);
Jeff Brownb88102f2010-09-08 11:49:43 -07003883 }
3884}
3885
Jeff Brownb6997262010-10-08 22:31:17 -07003886void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3887 Allocator* allocator, Vector<EventEntry*>& outEvents,
Jeff Brown524ee642011-03-29 15:11:34 -07003888 const CancelationOptions& options) {
Jeff Brownb6997262010-10-08 22:31:17 -07003889 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003890 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003891 if (shouldCancelKey(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003892 outEvents.push(allocator->obtainKeyEntry(currentTime,
3893 memento.deviceId, memento.source, 0,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003894 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
Jeff Brownb6997262010-10-08 22:31:17 -07003895 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3896 mKeyMementos.removeAt(i);
3897 } else {
3898 i += 1;
3899 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003900 }
3901
Jeff Browna1160a72010-10-11 18:22:53 -07003902 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003903 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003904 if (shouldCancelMotion(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003905 outEvents.push(allocator->obtainMotionEntry(currentTime,
3906 memento.deviceId, memento.source, 0,
3907 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3908 memento.xPrecision, memento.yPrecision, memento.downTime,
3909 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3910 mMotionMementos.removeAt(i);
3911 } else {
3912 i += 1;
3913 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003914 }
3915}
3916
3917void InputDispatcher::InputState::clear() {
3918 mKeyMementos.clear();
3919 mMotionMementos.clear();
Jeff Brown524ee642011-03-29 15:11:34 -07003920 mFallbackKeys.clear();
Jeff Brownb6997262010-10-08 22:31:17 -07003921}
3922
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003923void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3924 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3925 const MotionMemento& memento = mMotionMementos.itemAt(i);
3926 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3927 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3928 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3929 if (memento.deviceId == otherMemento.deviceId
3930 && memento.source == otherMemento.source) {
3931 other.mMotionMementos.removeAt(j);
3932 } else {
3933 j += 1;
3934 }
3935 }
3936 other.mMotionMementos.push(memento);
3937 }
3938 }
3939}
3940
Jeff Brown524ee642011-03-29 15:11:34 -07003941int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
3942 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
3943 return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
3944}
3945
3946void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
3947 int32_t fallbackKeyCode) {
3948 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
3949 if (index >= 0) {
3950 mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
3951 } else {
3952 mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
3953 }
3954}
3955
3956void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
3957 mFallbackKeys.removeItem(originalKeyCode);
3958}
3959
Jeff Brown49ed71d2010-12-06 17:13:33 -08003960bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
Jeff Brown524ee642011-03-29 15:11:34 -07003961 const CancelationOptions& options) {
3962 if (options.keyCode != -1 && memento.keyCode != options.keyCode) {
3963 return false;
3964 }
3965
3966 switch (options.mode) {
3967 case CancelationOptions::CANCEL_ALL_EVENTS:
3968 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003969 return true;
Jeff Brown524ee642011-03-29 15:11:34 -07003970 case CancelationOptions::CANCEL_FALLBACK_EVENTS:
Jeff Brown49ed71d2010-12-06 17:13:33 -08003971 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
3972 default:
3973 return false;
3974 }
3975}
3976
3977bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
Jeff Brown524ee642011-03-29 15:11:34 -07003978 const CancelationOptions& options) {
3979 switch (options.mode) {
3980 case CancelationOptions::CANCEL_ALL_EVENTS:
Jeff Brown49ed71d2010-12-06 17:13:33 -08003981 return true;
Jeff Brown524ee642011-03-29 15:11:34 -07003982 case CancelationOptions::CANCEL_POINTER_EVENTS:
Jeff Brown49ed71d2010-12-06 17:13:33 -08003983 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
Jeff Brown524ee642011-03-29 15:11:34 -07003984 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
Jeff Brown49ed71d2010-12-06 17:13:33 -08003985 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
3986 default:
3987 return false;
Jeff Brownb6997262010-10-08 22:31:17 -07003988 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003989}
3990
3991
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003992// --- InputDispatcher::Connection ---
3993
Jeff Brown928e0542011-01-10 11:17:36 -08003994InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
3995 const sp<InputWindowHandle>& inputWindowHandle) :
3996 status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
3997 inputPublisher(inputChannel),
Jeff Brown524ee642011-03-29 15:11:34 -07003998 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003999}
4000
4001InputDispatcher::Connection::~Connection() {
4002}
4003
4004status_t InputDispatcher::Connection::initialize() {
4005 return inputPublisher.initialize();
4006}
4007
Jeff Brown9c3cda02010-06-15 01:31:58 -07004008const char* InputDispatcher::Connection::getStatusLabel() const {
4009 switch (status) {
4010 case STATUS_NORMAL:
4011 return "NORMAL";
4012
4013 case STATUS_BROKEN:
4014 return "BROKEN";
4015
Jeff Brown9c3cda02010-06-15 01:31:58 -07004016 case STATUS_ZOMBIE:
4017 return "ZOMBIE";
4018
4019 default:
4020 return "UNKNOWN";
4021 }
4022}
4023
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004024InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
4025 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07004026 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
4027 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004028 if (dispatchEntry->eventEntry == eventEntry) {
4029 return dispatchEntry;
4030 }
4031 }
4032 return NULL;
4033}
4034
Jeff Brownb88102f2010-09-08 11:49:43 -07004035
Jeff Brown9c3cda02010-06-15 01:31:58 -07004036// --- InputDispatcher::CommandEntry ---
4037
Jeff Brownb88102f2010-09-08 11:49:43 -07004038InputDispatcher::CommandEntry::CommandEntry() :
4039 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07004040}
4041
4042InputDispatcher::CommandEntry::~CommandEntry() {
4043}
4044
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004045
Jeff Brown01ce2e92010-09-26 22:20:12 -07004046// --- InputDispatcher::TouchState ---
4047
4048InputDispatcher::TouchState::TouchState() :
Jeff Brown58a2da82011-01-25 16:02:22 -08004049 down(false), split(false), deviceId(-1), source(0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07004050}
4051
4052InputDispatcher::TouchState::~TouchState() {
4053}
4054
4055void InputDispatcher::TouchState::reset() {
4056 down = false;
4057 split = false;
Jeff Brown95712852011-01-04 19:41:59 -08004058 deviceId = -1;
Jeff Brown58a2da82011-01-25 16:02:22 -08004059 source = 0;
Jeff Brown01ce2e92010-09-26 22:20:12 -07004060 windows.clear();
4061}
4062
4063void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
4064 down = other.down;
4065 split = other.split;
Jeff Brown95712852011-01-04 19:41:59 -08004066 deviceId = other.deviceId;
Jeff Brown58a2da82011-01-25 16:02:22 -08004067 source = other.source;
Jeff Brown01ce2e92010-09-26 22:20:12 -07004068 windows.clear();
4069 windows.appendVector(other.windows);
4070}
4071
4072void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
4073 int32_t targetFlags, BitSet32 pointerIds) {
4074 if (targetFlags & InputTarget::FLAG_SPLIT) {
4075 split = true;
4076 }
4077
4078 for (size_t i = 0; i < windows.size(); i++) {
4079 TouchedWindow& touchedWindow = windows.editItemAt(i);
4080 if (touchedWindow.window == window) {
4081 touchedWindow.targetFlags |= targetFlags;
4082 touchedWindow.pointerIds.value |= pointerIds.value;
4083 return;
4084 }
4085 }
4086
4087 windows.push();
4088
4089 TouchedWindow& touchedWindow = windows.editTop();
4090 touchedWindow.window = window;
4091 touchedWindow.targetFlags = targetFlags;
4092 touchedWindow.pointerIds = pointerIds;
4093 touchedWindow.channel = window->inputChannel;
4094}
4095
4096void InputDispatcher::TouchState::removeOutsideTouchWindows() {
4097 for (size_t i = 0 ; i < windows.size(); ) {
4098 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
4099 windows.removeAt(i);
4100 } else {
4101 i += 1;
4102 }
4103 }
4104}
4105
4106const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
4107 for (size_t i = 0; i < windows.size(); i++) {
4108 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
4109 return windows[i].window;
4110 }
4111 }
4112 return NULL;
4113}
4114
4115
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07004116// --- InputDispatcherThread ---
4117
4118InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
4119 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
4120}
4121
4122InputDispatcherThread::~InputDispatcherThread() {
4123}
4124
4125bool InputDispatcherThread::threadLoop() {
4126 mDispatcher->dispatchOnce();
4127 return true;
4128}
4129
4130} // namespace android