blob: 28bd14bfdd70268e68fb28e0e27345015c9e410f [file] [log] [blame]
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jeff Brown46b9ac02010-04-22 18:58:52 -070017#define LOG_TAG "InputDispatcher"
18
19//#define LOG_NDEBUG 0
20
21// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070022#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070023
24// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070025#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070026
27// Log debug messages about batching.
Jeff Brown349703e2010-06-22 01:27:15 -070028#define DEBUG_BATCHING 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070029
30// Log debug messages about the dispatch cycle.
Jeff Brown349703e2010-06-22 01:27:15 -070031#define DEBUG_DISPATCH_CYCLE 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070032
Jeff Brown9c3cda02010-06-15 01:31:58 -070033// Log debug messages about registrations.
Jeff Brown349703e2010-06-22 01:27:15 -070034#define DEBUG_REGISTRATION 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070035
Jeff Brown46b9ac02010-04-22 18:58:52 -070036// Log debug messages about performance statistics.
Jeff Brown349703e2010-06-22 01:27:15 -070037#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Brown46b9ac02010-04-22 18:58:52 -070038
Jeff Brown7fbdc842010-06-17 20:52:56 -070039// Log debug messages about input event injection.
Jeff Brown349703e2010-06-22 01:27:15 -070040#define DEBUG_INJECTION 0
Jeff Brown7fbdc842010-06-17 20:52:56 -070041
Jeff Brownb88102f2010-09-08 11:49:43 -070042// Log debug messages about input focus tracking.
43#define DEBUG_FOCUS 0
44
45// Log debug messages about the app switch latency optimization.
46#define DEBUG_APP_SWITCH 0
47
Jeff Browna032cc02011-03-07 16:56:21 -080048// Log debug messages about hover events.
49#define DEBUG_HOVER 0
50
Jeff Brownb4ff35d2011-01-02 16:37:43 -080051#include "InputDispatcher.h"
52
Jeff Brown46b9ac02010-04-22 18:58:52 -070053#include <cutils/log.h>
Jeff Brownb88102f2010-09-08 11:49:43 -070054#include <ui/PowerManager.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070055
56#include <stddef.h>
57#include <unistd.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070058#include <errno.h>
59#include <limits.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070060
Jeff Brownf2f487182010-10-01 17:46:21 -070061#define INDENT " "
62#define INDENT2 " "
63
Jeff Brown46b9ac02010-04-22 18:58:52 -070064namespace android {
65
Jeff Brownb88102f2010-09-08 11:49:43 -070066// Default input dispatching timeout if there is no focused application or paused window
67// from which to determine an appropriate dispatching timeout.
68const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
69
70// Amount of time to allow for all pending events to be processed when an app switch
71// key is on the way. This is used to preempt input dispatch and drop input events
72// when an application takes too long to respond and the user has pressed an app switch key.
73const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
74
Jeff Brown928e0542011-01-10 11:17:36 -080075// Amount of time to allow for an event to be dispatched (measured since its eventTime)
76// before considering it stale and dropping it.
77const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
78
Jeff Brown4e91a182011-04-07 11:38:09 -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 Brown46b9ac02010-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)) {
Steve Block3762c312012-01-06 19:20:56 +0000121 ALOGE("Key event has invalid action code 0x%x", action);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700122 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 Browna032cc02011-03-07 16:56:21 -0800134 case AMOTION_EVENT_ACTION_HOVER_ENTER:
Jeff Browncc0c1592011-02-19 05:07:28 -0800135 case AMOTION_EVENT_ACTION_HOVER_MOVE:
Jeff Browna032cc02011-03-07 16:56:21 -0800136 case AMOTION_EVENT_ACTION_HOVER_EXIT:
Jeff Brown33bbfd22011-02-24 20:55:35 -0800137 case AMOTION_EVENT_ACTION_SCROLL:
Jeff Brown01ce2e92010-09-26 22:20:12 -0700138 return true;
Jeff Brownb6997262010-10-08 22:31:17 -0700139 case AMOTION_EVENT_ACTION_POINTER_DOWN:
140 case AMOTION_EVENT_ACTION_POINTER_UP: {
141 int32_t index = getMotionEventActionPointerIndex(action);
142 return index >= 0 && size_t(index) < pointerCount;
143 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700144 default:
145 return false;
146 }
147}
148
149static bool validateMotionEvent(int32_t action, size_t pointerCount,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700150 const PointerProperties* pointerProperties) {
Jeff Brownb6997262010-10-08 22:31:17 -0700151 if (! isValidMotionAction(action, pointerCount)) {
Steve Block3762c312012-01-06 19:20:56 +0000152 ALOGE("Motion event has invalid action code 0x%x", action);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700153 return false;
154 }
155 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Steve Block3762c312012-01-06 19:20:56 +0000156 ALOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
Jeff Brown01ce2e92010-09-26 22:20:12 -0700157 pointerCount, MAX_POINTERS);
158 return false;
159 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700160 BitSet32 pointerIdBits;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700161 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700162 int32_t id = pointerProperties[i].id;
Jeff Brownc3db8582010-10-20 15:33:38 -0700163 if (id < 0 || id > MAX_POINTER_ID) {
Steve Block3762c312012-01-06 19:20:56 +0000164 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
Jeff Brownc3db8582010-10-20 15:33:38 -0700165 id, MAX_POINTER_ID);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700166 return false;
167 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700168 if (pointerIdBits.hasBit(id)) {
Steve Block3762c312012-01-06 19:20:56 +0000169 ALOGE("Motion event has duplicate pointer id %d", id);
Jeff Brownc3db8582010-10-20 15:33:38 -0700170 return false;
171 }
172 pointerIdBits.markBit(id);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700173 }
174 return true;
175}
176
Jeff Brownfbf09772011-01-16 14:06:57 -0800177static void dumpRegion(String8& dump, const SkRegion& region) {
178 if (region.isEmpty()) {
179 dump.append("<empty>");
180 return;
181 }
182
183 bool first = true;
184 for (SkRegion::Iterator it(region); !it.done(); it.next()) {
185 if (first) {
186 first = false;
187 } else {
188 dump.append("|");
189 }
190 const SkIRect& rect = it.rect();
191 dump.appendFormat("[%d,%d][%d,%d]", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
192 }
193}
194
Jeff Brownb88102f2010-09-08 11:49:43 -0700195
Jeff Brown46b9ac02010-04-22 18:58:52 -0700196// --- InputDispatcher ---
197
Jeff Brown9c3cda02010-06-15 01:31:58 -0700198InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Brownb88102f2010-09-08 11:49:43 -0700199 mPolicy(policy),
Jeff Brown928e0542011-01-10 11:17:36 -0800200 mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
201 mNextUnblockedEvent(NULL),
Jeff Brown0029c662011-03-30 02:25:18 -0700202 mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false),
Jeff Brownb88102f2010-09-08 11:49:43 -0700203 mCurrentInputTargetsValid(false),
Jeff Brown9302c872011-07-13 22:51:29 -0700204 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700205 mLooper = new Looper(false);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700206
Jeff Brown46b9ac02010-04-22 18:58:52 -0700207 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700208
Jeff Brown214eaf42011-05-26 19:17:02 -0700209 policy->getDispatcherConfiguration(&mConfig);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700210}
211
212InputDispatcher::~InputDispatcher() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700213 { // acquire lock
214 AutoMutex _l(mLock);
215
216 resetKeyRepeatLocked();
Jeff Brown54a18252010-09-16 14:07:33 -0700217 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700218 drainInboundQueueLocked();
219 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700220
221 while (mConnectionsByReceiveFd.size() != 0) {
222 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
223 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700224}
225
226void InputDispatcher::dispatchOnce() {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700227 nsecs_t nextWakeupTime = LONG_LONG_MAX;
228 { // acquire lock
229 AutoMutex _l(mLock);
Jeff Brown112b5f52012-01-27 17:32:06 -0800230 mDispatcherIsAliveCondition.broadcast();
231
Jeff Brown214eaf42011-05-26 19:17:02 -0700232 dispatchOnceInnerLocked(&nextWakeupTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700233
Jeff Brownb88102f2010-09-08 11:49:43 -0700234 if (runCommandsLockedInterruptible()) {
235 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Brown46b9ac02010-04-22 18:58:52 -0700236 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700237 } // release lock
238
Jeff Brownb88102f2010-09-08 11:49:43 -0700239 // Wait for callback or timeout or wake. (make sure we round up, not down)
240 nsecs_t currentTime = now();
Jeff Brownaa3855d2011-03-17 01:34:19 -0700241 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700242 mLooper->pollOnce(timeoutMillis);
Jeff Brownb88102f2010-09-08 11:49:43 -0700243}
244
Jeff Brown214eaf42011-05-26 19:17:02 -0700245void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700246 nsecs_t currentTime = now();
247
248 // Reset the key repeat timer whenever we disallow key events, even if the next event
249 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
250 // out of sleep.
Jeff Brown214eaf42011-05-26 19:17:02 -0700251 if (!mPolicy->isKeyRepeatEnabled()) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700252 resetKeyRepeatLocked();
253 }
254
Jeff Brownb88102f2010-09-08 11:49:43 -0700255 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
256 if (mDispatchFrozen) {
257#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +0000258 ALOGD("Dispatch frozen. Waiting some more.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700259#endif
260 return;
261 }
262
263 // Optimize latency of app switches.
264 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
265 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
266 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
267 if (mAppSwitchDueTime < *nextWakeupTime) {
268 *nextWakeupTime = mAppSwitchDueTime;
269 }
270
Jeff Brownb88102f2010-09-08 11:49:43 -0700271 // Ready to start a new event.
272 // If we don't already have a pending event, go grab one.
273 if (! mPendingEvent) {
274 if (mInboundQueue.isEmpty()) {
275 if (isAppSwitchDue) {
276 // The inbound queue is empty so the app switch key we were waiting
277 // for will never arrive. Stop waiting for it.
278 resetPendingAppSwitchLocked(false);
279 isAppSwitchDue = false;
280 }
281
282 // Synthesize a key repeat if appropriate.
283 if (mKeyRepeatState.lastKeyEntry) {
284 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
Jeff Brown214eaf42011-05-26 19:17:02 -0700285 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700286 } else {
287 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
288 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
289 }
290 }
291 }
Jeff Browncc4f7db2011-08-30 20:34:48 -0700292
293 // Nothing to do if there is no pending event.
Jeff Brownb88102f2010-09-08 11:49:43 -0700294 if (! mPendingEvent) {
Jeff Browncc4f7db2011-08-30 20:34:48 -0700295 if (mActiveConnections.isEmpty()) {
296 dispatchIdleLocked();
297 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700298 return;
299 }
300 } else {
301 // Inbound queue has at least one entry.
Jeff Brown30802802012-02-03 13:35:13 -0800302 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brownb88102f2010-09-08 11:49:43 -0700303 mPendingEvent = entry;
304 }
Jeff Browne2fe69e2010-10-18 13:21:23 -0700305
306 // Poke user activity for this event.
307 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
308 pokeUserActivityLocked(mPendingEvent);
309 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700310 }
311
312 // Now we have an event to dispatch.
Jeff Brown928e0542011-01-10 11:17:36 -0800313 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Steve Blockec193de2012-01-09 18:35:44 +0000314 ALOG_ASSERT(mPendingEvent != NULL);
Jeff Brown54a18252010-09-16 14:07:33 -0700315 bool done = false;
Jeff Brownb6997262010-10-08 22:31:17 -0700316 DropReason dropReason = DROP_REASON_NOT_DROPPED;
317 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
318 dropReason = DROP_REASON_POLICY;
319 } else if (!mDispatchEnabled) {
320 dropReason = DROP_REASON_DISABLED;
321 }
Jeff Brown928e0542011-01-10 11:17:36 -0800322
323 if (mNextUnblockedEvent == mPendingEvent) {
324 mNextUnblockedEvent = NULL;
325 }
326
Jeff Brownb88102f2010-09-08 11:49:43 -0700327 switch (mPendingEvent->type) {
328 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
329 ConfigurationChangedEntry* typedEntry =
330 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700331 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brownb6997262010-10-08 22:31:17 -0700332 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Brownb88102f2010-09-08 11:49:43 -0700333 break;
334 }
335
Jeff Brown65fd2512011-08-18 11:20:58 -0700336 case EventEntry::TYPE_DEVICE_RESET: {
337 DeviceResetEntry* typedEntry =
338 static_cast<DeviceResetEntry*>(mPendingEvent);
339 done = dispatchDeviceResetLocked(currentTime, typedEntry);
340 dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
341 break;
342 }
343
Jeff Brownb88102f2010-09-08 11:49:43 -0700344 case EventEntry::TYPE_KEY: {
345 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700346 if (isAppSwitchDue) {
347 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700348 resetPendingAppSwitchLocked(true);
Jeff Brownb6997262010-10-08 22:31:17 -0700349 isAppSwitchDue = false;
350 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
351 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700352 }
353 }
Jeff Brown928e0542011-01-10 11:17:36 -0800354 if (dropReason == DROP_REASON_NOT_DROPPED
355 && isStaleEventLocked(currentTime, typedEntry)) {
356 dropReason = DROP_REASON_STALE;
357 }
358 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
359 dropReason = DROP_REASON_BLOCKED;
360 }
Jeff Brown214eaf42011-05-26 19:17:02 -0700361 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700362 break;
363 }
364
365 case EventEntry::TYPE_MOTION: {
366 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700367 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
368 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700369 }
Jeff Brown928e0542011-01-10 11:17:36 -0800370 if (dropReason == DROP_REASON_NOT_DROPPED
371 && isStaleEventLocked(currentTime, typedEntry)) {
372 dropReason = DROP_REASON_STALE;
373 }
374 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
375 dropReason = DROP_REASON_BLOCKED;
376 }
Jeff Brownb6997262010-10-08 22:31:17 -0700377 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Browne20c9e02010-10-11 14:20:19 -0700378 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700379 break;
380 }
381
382 default:
Steve Blockec193de2012-01-09 18:35:44 +0000383 ALOG_ASSERT(false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700384 break;
385 }
386
Jeff Brown54a18252010-09-16 14:07:33 -0700387 if (done) {
Jeff Brownb6997262010-10-08 22:31:17 -0700388 if (dropReason != DROP_REASON_NOT_DROPPED) {
389 dropInboundEventLocked(mPendingEvent, dropReason);
390 }
391
Jeff Brown54a18252010-09-16 14:07:33 -0700392 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700393 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
394 }
395}
396
Jeff Browncc4f7db2011-08-30 20:34:48 -0700397void InputDispatcher::dispatchIdleLocked() {
398#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +0000399 ALOGD("Dispatcher idle. There are no pending events or active connections.");
Jeff Browncc4f7db2011-08-30 20:34:48 -0700400#endif
401
402 // Reset targets when idle, to release input channels and other resources
403 // they are holding onto.
404 resetTargetsLocked();
405}
406
Jeff Brownb88102f2010-09-08 11:49:43 -0700407bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
408 bool needWake = mInboundQueue.isEmpty();
409 mInboundQueue.enqueueAtTail(entry);
410
411 switch (entry->type) {
Jeff Brownb6997262010-10-08 22:31:17 -0700412 case EventEntry::TYPE_KEY: {
Jeff Brown928e0542011-01-10 11:17:36 -0800413 // Optimize app switch latency.
414 // If the application takes too long to catch up then we drop all events preceding
415 // the app switch key.
Jeff Brownb6997262010-10-08 22:31:17 -0700416 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
417 if (isAppSwitchKeyEventLocked(keyEntry)) {
418 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
419 mAppSwitchSawKeyDown = true;
420 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
421 if (mAppSwitchSawKeyDown) {
422#if DEBUG_APP_SWITCH
Steve Block5baa3a62011-12-20 16:23:08 +0000423 ALOGD("App switch is pending!");
Jeff Brownb6997262010-10-08 22:31:17 -0700424#endif
425 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
426 mAppSwitchSawKeyDown = false;
427 needWake = true;
428 }
429 }
430 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700431 break;
432 }
Jeff Brown928e0542011-01-10 11:17:36 -0800433
434 case EventEntry::TYPE_MOTION: {
435 // Optimize case where the current application is unresponsive and the user
436 // decides to touch a window in a different application.
437 // If the application takes too long to catch up then we drop all events preceding
438 // the touch into the other window.
439 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
Jeff Brown33bbfd22011-02-24 20:55:35 -0800440 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
Jeff Brown928e0542011-01-10 11:17:36 -0800441 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
442 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
Jeff Brown9302c872011-07-13 22:51:29 -0700443 && mInputTargetWaitApplicationHandle != NULL) {
Jeff Brown91c69ab2011-02-14 17:03:18 -0800444 int32_t x = int32_t(motionEntry->firstSample.pointerCoords[0].
Jeff Brownebbd5d12011-02-17 13:01:34 -0800445 getAxisValue(AMOTION_EVENT_AXIS_X));
Jeff Brown91c69ab2011-02-14 17:03:18 -0800446 int32_t y = int32_t(motionEntry->firstSample.pointerCoords[0].
Jeff Brownebbd5d12011-02-17 13:01:34 -0800447 getAxisValue(AMOTION_EVENT_AXIS_Y));
Jeff Brown9302c872011-07-13 22:51:29 -0700448 sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(x, y);
449 if (touchedWindowHandle != NULL
450 && touchedWindowHandle->inputApplicationHandle
451 != mInputTargetWaitApplicationHandle) {
Jeff Brown928e0542011-01-10 11:17:36 -0800452 // User touched a different application than the one we are waiting on.
453 // Flag the event, and start pruning the input queue.
454 mNextUnblockedEvent = motionEntry;
455 needWake = true;
456 }
457 }
458 break;
459 }
Jeff Brownb6997262010-10-08 22:31:17 -0700460 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700461
462 return needWake;
463}
464
Jeff Brown9302c872011-07-13 22:51:29 -0700465sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
Jeff Brown928e0542011-01-10 11:17:36 -0800466 // Traverse windows from front to back to find touched window.
Jeff Brown9302c872011-07-13 22:51:29 -0700467 size_t numWindows = mWindowHandles.size();
Jeff Brown928e0542011-01-10 11:17:36 -0800468 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown9302c872011-07-13 22:51:29 -0700469 sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
Jeff Browncc4f7db2011-08-30 20:34:48 -0700470 const InputWindowInfo* windowInfo = windowHandle->getInfo();
471 int32_t flags = windowInfo->layoutParamsFlags;
Jeff Brown928e0542011-01-10 11:17:36 -0800472
Jeff Browncc4f7db2011-08-30 20:34:48 -0700473 if (windowInfo->visible) {
474 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
475 bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
476 | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
477 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Jeff Brown928e0542011-01-10 11:17:36 -0800478 // Found window.
Jeff Brown9302c872011-07-13 22:51:29 -0700479 return windowHandle;
Jeff Brown928e0542011-01-10 11:17:36 -0800480 }
481 }
482 }
483
Jeff Browncc4f7db2011-08-30 20:34:48 -0700484 if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
Jeff Brown928e0542011-01-10 11:17:36 -0800485 // Error window is on top but not visible, so touch is dropped.
486 return NULL;
487 }
488 }
489 return NULL;
490}
491
Jeff Brownb6997262010-10-08 22:31:17 -0700492void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
493 const char* reason;
494 switch (dropReason) {
495 case DROP_REASON_POLICY:
Jeff Browne20c9e02010-10-11 14:20:19 -0700496#if DEBUG_INBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +0000497 ALOGD("Dropped event because policy consumed it.");
Jeff Browne20c9e02010-10-11 14:20:19 -0700498#endif
Jeff Brown3122e442010-10-11 23:32:49 -0700499 reason = "inbound event was dropped because the policy consumed it";
Jeff Brownb6997262010-10-08 22:31:17 -0700500 break;
501 case DROP_REASON_DISABLED:
Steve Block6215d3f2012-01-04 20:05:49 +0000502 ALOGI("Dropped event because input dispatch is disabled.");
Jeff Brownb6997262010-10-08 22:31:17 -0700503 reason = "inbound event was dropped because input dispatch is disabled";
504 break;
505 case DROP_REASON_APP_SWITCH:
Steve Block6215d3f2012-01-04 20:05:49 +0000506 ALOGI("Dropped event because of pending overdue app switch.");
Jeff Brownb6997262010-10-08 22:31:17 -0700507 reason = "inbound event was dropped because of pending overdue app switch";
508 break;
Jeff Brown928e0542011-01-10 11:17:36 -0800509 case DROP_REASON_BLOCKED:
Steve Block6215d3f2012-01-04 20:05:49 +0000510 ALOGI("Dropped event because the current application is not responding and the user "
Jeff Brown81346812011-06-28 20:08:48 -0700511 "has started interacting with a different application.");
Jeff Brown928e0542011-01-10 11:17:36 -0800512 reason = "inbound event was dropped because the current application is not responding "
Jeff Brown81346812011-06-28 20:08:48 -0700513 "and the user has started interacting with a different application";
Jeff Brown928e0542011-01-10 11:17:36 -0800514 break;
515 case DROP_REASON_STALE:
Steve Block6215d3f2012-01-04 20:05:49 +0000516 ALOGI("Dropped event because it is stale.");
Jeff Brown928e0542011-01-10 11:17:36 -0800517 reason = "inbound event was dropped because it is stale";
518 break;
Jeff Brownb6997262010-10-08 22:31:17 -0700519 default:
Steve Blockec193de2012-01-09 18:35:44 +0000520 ALOG_ASSERT(false);
Jeff Brownb6997262010-10-08 22:31:17 -0700521 return;
522 }
523
524 switch (entry->type) {
Jeff Brownda3d5a92011-03-29 15:11:34 -0700525 case EventEntry::TYPE_KEY: {
526 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
527 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Brownb6997262010-10-08 22:31:17 -0700528 break;
Jeff Brownda3d5a92011-03-29 15:11:34 -0700529 }
Jeff Brownb6997262010-10-08 22:31:17 -0700530 case EventEntry::TYPE_MOTION: {
531 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
532 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
Jeff Brownda3d5a92011-03-29 15:11:34 -0700533 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
534 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Brownb6997262010-10-08 22:31:17 -0700535 } else {
Jeff Brownda3d5a92011-03-29 15:11:34 -0700536 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
537 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Brownb6997262010-10-08 22:31:17 -0700538 }
539 break;
540 }
541 }
542}
543
544bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700545 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
546}
547
Jeff Brownb6997262010-10-08 22:31:17 -0700548bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
549 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
550 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Browne20c9e02010-10-11 14:20:19 -0700551 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brownb6997262010-10-08 22:31:17 -0700552 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
553}
554
Jeff Brownb88102f2010-09-08 11:49:43 -0700555bool InputDispatcher::isAppSwitchPendingLocked() {
556 return mAppSwitchDueTime != LONG_LONG_MAX;
557}
558
Jeff Brownb88102f2010-09-08 11:49:43 -0700559void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
560 mAppSwitchDueTime = LONG_LONG_MAX;
561
562#if DEBUG_APP_SWITCH
563 if (handled) {
Steve Block5baa3a62011-12-20 16:23:08 +0000564 ALOGD("App switch has arrived.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700565 } else {
Steve Block5baa3a62011-12-20 16:23:08 +0000566 ALOGD("App switch was abandoned.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700567 }
568#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -0700569}
570
Jeff Brown928e0542011-01-10 11:17:36 -0800571bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
572 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
573}
574
Jeff Brown9c3cda02010-06-15 01:31:58 -0700575bool InputDispatcher::runCommandsLockedInterruptible() {
576 if (mCommandQueue.isEmpty()) {
577 return false;
578 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700579
Jeff Brown9c3cda02010-06-15 01:31:58 -0700580 do {
581 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
582
583 Command command = commandEntry->command;
584 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
585
Jeff Brown7fbdc842010-06-17 20:52:56 -0700586 commandEntry->connection.clear();
Jeff Brownac386072011-07-20 15:19:50 -0700587 delete commandEntry;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700588 } while (! mCommandQueue.isEmpty());
589 return true;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700590}
591
Jeff Brown9c3cda02010-06-15 01:31:58 -0700592InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
Jeff Brownac386072011-07-20 15:19:50 -0700593 CommandEntry* commandEntry = new CommandEntry(command);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700594 mCommandQueue.enqueueAtTail(commandEntry);
595 return commandEntry;
596}
597
Jeff Brownb88102f2010-09-08 11:49:43 -0700598void InputDispatcher::drainInboundQueueLocked() {
599 while (! mInboundQueue.isEmpty()) {
600 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700601 releaseInboundEventLocked(entry);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700602 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700603}
604
Jeff Brown54a18252010-09-16 14:07:33 -0700605void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700606 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700607 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700608 mPendingEvent = NULL;
609 }
610}
611
Jeff Brown54a18252010-09-16 14:07:33 -0700612void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700613 InjectionState* injectionState = entry->injectionState;
614 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700615#if DEBUG_DISPATCH_CYCLE
Steve Block5baa3a62011-12-20 16:23:08 +0000616 ALOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700617#endif
618 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
619 }
Jeff Brownabb4d442011-08-15 12:55:32 -0700620 if (entry == mNextUnblockedEvent) {
621 mNextUnblockedEvent = NULL;
622 }
Jeff Brownac386072011-07-20 15:19:50 -0700623 entry->release();
Jeff Brownb88102f2010-09-08 11:49:43 -0700624}
625
Jeff Brownb88102f2010-09-08 11:49:43 -0700626void InputDispatcher::resetKeyRepeatLocked() {
627 if (mKeyRepeatState.lastKeyEntry) {
Jeff Brownac386072011-07-20 15:19:50 -0700628 mKeyRepeatState.lastKeyEntry->release();
Jeff Brownb88102f2010-09-08 11:49:43 -0700629 mKeyRepeatState.lastKeyEntry = NULL;
630 }
631}
632
Jeff Brown214eaf42011-05-26 19:17:02 -0700633InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
Jeff Brown349703e2010-06-22 01:27:15 -0700634 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
635
Jeff Brown349703e2010-06-22 01:27:15 -0700636 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Browne20c9e02010-10-11 14:20:19 -0700637 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
638 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700639 if (entry->refCount == 1) {
Jeff Brownac386072011-07-20 15:19:50 -0700640 entry->recycle();
Jeff Brown7fbdc842010-06-17 20:52:56 -0700641 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700642 entry->policyFlags = policyFlags;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700643 entry->repeatCount += 1;
644 } else {
Jeff Brownac386072011-07-20 15:19:50 -0700645 KeyEntry* newEntry = new KeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700646 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700647 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700648 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700649
650 mKeyRepeatState.lastKeyEntry = newEntry;
Jeff Brownac386072011-07-20 15:19:50 -0700651 entry->release();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700652
653 entry = newEntry;
654 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700655 entry->syntheticRepeat = true;
656
657 // Increment reference count since we keep a reference to the event in
658 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
659 entry->refCount += 1;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700660
Jeff Brown214eaf42011-05-26 19:17:02 -0700661 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700662 return entry;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700663}
664
Jeff Brownb88102f2010-09-08 11:49:43 -0700665bool InputDispatcher::dispatchConfigurationChangedLocked(
666 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700667#if DEBUG_OUTBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +0000668 ALOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700669#endif
670
671 // Reset key repeating in case a keyboard device was added or removed or something.
672 resetKeyRepeatLocked();
673
674 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
675 CommandEntry* commandEntry = postCommandLocked(
676 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
677 commandEntry->eventTime = entry->eventTime;
678 return true;
679}
680
Jeff Brown65fd2512011-08-18 11:20:58 -0700681bool InputDispatcher::dispatchDeviceResetLocked(
682 nsecs_t currentTime, DeviceResetEntry* entry) {
683#if DEBUG_OUTBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +0000684 ALOGD("dispatchDeviceReset - eventTime=%lld, deviceId=%d", entry->eventTime, entry->deviceId);
Jeff Brown65fd2512011-08-18 11:20:58 -0700685#endif
686
687 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
688 "device was reset");
689 options.deviceId = entry->deviceId;
690 synthesizeCancelationEventsForAllConnectionsLocked(options);
691 return true;
692}
693
Jeff Brown214eaf42011-05-26 19:17:02 -0700694bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
Jeff Browne20c9e02010-10-11 14:20:19 -0700695 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700696 // Preprocessing.
697 if (! entry->dispatchInProgress) {
698 if (entry->repeatCount == 0
699 && entry->action == AKEY_EVENT_ACTION_DOWN
700 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brown0029c662011-03-30 02:25:18 -0700701 && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700702 if (mKeyRepeatState.lastKeyEntry
703 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
704 // We have seen two identical key downs in a row which indicates that the device
705 // driver is automatically generating key repeats itself. We take note of the
706 // repeat here, but we disable our own next key repeat timer since it is clear that
707 // we will not need to synthesize key repeats ourselves.
708 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
709 resetKeyRepeatLocked();
710 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
711 } else {
712 // Not a repeat. Save key down state in case we do see a repeat later.
713 resetKeyRepeatLocked();
Jeff Brown214eaf42011-05-26 19:17:02 -0700714 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
Jeff Browne46a0a42010-11-02 17:58:22 -0700715 }
716 mKeyRepeatState.lastKeyEntry = entry;
717 entry->refCount += 1;
718 } else if (! entry->syntheticRepeat) {
719 resetKeyRepeatLocked();
720 }
721
Jeff Browne2e01262011-03-02 20:34:30 -0800722 if (entry->repeatCount == 1) {
723 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
724 } else {
725 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
726 }
727
Jeff Browne46a0a42010-11-02 17:58:22 -0700728 entry->dispatchInProgress = true;
729 resetTargetsLocked();
730
731 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
732 }
733
Jeff Brown905805a2011-10-12 13:57:59 -0700734 // Handle case where the policy asked us to try again later last time.
735 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
736 if (currentTime < entry->interceptKeyWakeupTime) {
737 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
738 *nextWakeupTime = entry->interceptKeyWakeupTime;
739 }
740 return false; // wait until next wakeup
741 }
742 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
743 entry->interceptKeyWakeupTime = 0;
744 }
745
Jeff Brown54a18252010-09-16 14:07:33 -0700746 // Give the policy a chance to intercept the key.
747 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700748 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brown54a18252010-09-16 14:07:33 -0700749 CommandEntry* commandEntry = postCommandLocked(
750 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Brown9302c872011-07-13 22:51:29 -0700751 if (mFocusedWindowHandle != NULL) {
752 commandEntry->inputWindowHandle = mFocusedWindowHandle;
Jeff Brown54a18252010-09-16 14:07:33 -0700753 }
754 commandEntry->keyEntry = entry;
755 entry->refCount += 1;
756 return false; // wait for the command to run
757 } else {
758 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
759 }
760 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700761 if (*dropReason == DROP_REASON_NOT_DROPPED) {
762 *dropReason = DROP_REASON_POLICY;
763 }
Jeff Brown54a18252010-09-16 14:07:33 -0700764 }
765
766 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700767 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700768 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700769 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
770 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700771 return true;
772 }
773
Jeff Brownb88102f2010-09-08 11:49:43 -0700774 // Identify targets.
775 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700776 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
777 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700778 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
779 return false;
780 }
781
782 setInjectionResultLocked(entry, injectionResult);
783 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
784 return true;
785 }
786
787 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700788 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700789 }
790
791 // Dispatch the key.
792 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700793 return true;
794}
795
796void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
797#if DEBUG_OUTBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +0000798 ALOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brownb88102f2010-09-08 11:49:43 -0700799 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
Jeff Browne46a0a42010-11-02 17:58:22 -0700800 "repeatCount=%d, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700801 prefix,
802 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
803 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Jeff Browne46a0a42010-11-02 17:58:22 -0700804 entry->repeatCount, entry->downTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700805#endif
806}
807
808bool InputDispatcher::dispatchMotionLocked(
Jeff Browne20c9e02010-10-11 14:20:19 -0700809 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700810 // Preprocessing.
811 if (! entry->dispatchInProgress) {
812 entry->dispatchInProgress = true;
813 resetTargetsLocked();
814
815 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
816 }
817
Jeff Brown54a18252010-09-16 14:07:33 -0700818 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700819 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700820 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700821 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
822 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700823 return true;
824 }
825
Jeff Brownb88102f2010-09-08 11:49:43 -0700826 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
827
828 // Identify targets.
Jeff Browncc0c1592011-02-19 05:07:28 -0800829 bool conflictingPointerActions = false;
Jeff Brownb88102f2010-09-08 11:49:43 -0700830 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700831 int32_t injectionResult;
Jeff Browna032cc02011-03-07 16:56:21 -0800832 const MotionSample* splitBatchAfterSample = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -0700833 if (isPointerEvent) {
834 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700835 injectionResult = findTouchedWindowTargetsLocked(currentTime,
Jeff Browna032cc02011-03-07 16:56:21 -0800836 entry, nextWakeupTime, &conflictingPointerActions, &splitBatchAfterSample);
Jeff Brownb88102f2010-09-08 11:49:43 -0700837 } else {
838 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700839 injectionResult = findFocusedWindowTargetsLocked(currentTime,
840 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700841 }
842 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
843 return false;
844 }
845
846 setInjectionResultLocked(entry, injectionResult);
847 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
848 return true;
849 }
850
851 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700852 commitTargetsLocked();
Jeff Browna032cc02011-03-07 16:56:21 -0800853
854 // Unbatch the event if necessary by splitting it into two parts after the
855 // motion sample indicated by splitBatchAfterSample.
856 if (splitBatchAfterSample && splitBatchAfterSample->next) {
857#if DEBUG_BATCHING
858 uint32_t originalSampleCount = entry->countSamples();
859#endif
860 MotionSample* nextSample = splitBatchAfterSample->next;
Jeff Brownac386072011-07-20 15:19:50 -0700861 MotionEntry* nextEntry = new MotionEntry(nextSample->eventTime,
Jeff Browna032cc02011-03-07 16:56:21 -0800862 entry->deviceId, entry->source, entry->policyFlags,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700863 entry->action, entry->flags,
864 entry->metaState, entry->buttonState, entry->edgeFlags,
Jeff Browna032cc02011-03-07 16:56:21 -0800865 entry->xPrecision, entry->yPrecision, entry->downTime,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700866 entry->pointerCount, entry->pointerProperties, nextSample->pointerCoords);
Jeff Browna032cc02011-03-07 16:56:21 -0800867 if (nextSample != entry->lastSample) {
868 nextEntry->firstSample.next = nextSample->next;
869 nextEntry->lastSample = entry->lastSample;
870 }
Jeff Brownac386072011-07-20 15:19:50 -0700871 delete nextSample;
Jeff Browna032cc02011-03-07 16:56:21 -0800872
873 entry->lastSample = const_cast<MotionSample*>(splitBatchAfterSample);
874 entry->lastSample->next = NULL;
875
876 if (entry->injectionState) {
877 nextEntry->injectionState = entry->injectionState;
878 entry->injectionState->refCount += 1;
879 }
880
881#if DEBUG_BATCHING
Steve Block5baa3a62011-12-20 16:23:08 +0000882 ALOGD("Split batch of %d samples into two parts, first part has %d samples, "
Jeff Browna032cc02011-03-07 16:56:21 -0800883 "second part has %d samples.", originalSampleCount,
884 entry->countSamples(), nextEntry->countSamples());
885#endif
886
887 mInboundQueue.enqueueAtHead(nextEntry);
888 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700889 }
890
891 // Dispatch the motion.
Jeff Browncc0c1592011-02-19 05:07:28 -0800892 if (conflictingPointerActions) {
Jeff Brownda3d5a92011-03-29 15:11:34 -0700893 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
894 "conflicting pointer actions");
895 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Browncc0c1592011-02-19 05:07:28 -0800896 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700897 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700898 return true;
899}
900
901
902void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
903#if DEBUG_OUTBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +0000904 ALOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700905 "action=0x%x, flags=0x%x, "
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700906 "metaState=0x%x, buttonState=0x%x, "
907 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700908 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700909 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
910 entry->action, entry->flags,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700911 entry->metaState, entry->buttonState,
912 entry->edgeFlags, entry->xPrecision, entry->yPrecision,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700913 entry->downTime);
914
915 // Print the most recent sample that we have available, this may change due to batching.
916 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700917 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700918 for (; sample->next != NULL; sample = sample->next) {
919 sampleCount += 1;
920 }
921 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Steve Block5baa3a62011-12-20 16:23:08 +0000922 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700923 "x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700924 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700925 "orientation=%f",
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700926 i, entry->pointerProperties[i].id,
927 entry->pointerProperties[i].toolType,
Jeff Brownebbd5d12011-02-17 13:01:34 -0800928 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
929 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
930 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
931 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
932 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
933 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
934 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
935 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
936 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Jeff Brown46b9ac02010-04-22 18:58:52 -0700937 }
938
939 // Keep in mind that due to batching, it is possible for the number of samples actually
940 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700941 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Steve Block5baa3a62011-12-20 16:23:08 +0000942 ALOGD(" ... Total movement samples currently batched %d ...", sampleCount);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700943 }
944#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -0700945}
946
947void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
948 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
949#if DEBUG_DISPATCH_CYCLE
Steve Block5baa3a62011-12-20 16:23:08 +0000950 ALOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac02010-04-22 18:58:52 -0700951 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700952 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac02010-04-22 18:58:52 -0700953#endif
954
Steve Blockec193de2012-01-09 18:35:44 +0000955 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
Jeff Brown9c3cda02010-06-15 01:31:58 -0700956
Jeff Browne2fe69e2010-10-18 13:21:23 -0700957 pokeUserActivityLocked(eventEntry);
958
Jeff Brown46b9ac02010-04-22 18:58:52 -0700959 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
960 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
961
Jeff Brown519e0242010-09-15 15:18:56 -0700962 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700963 if (connectionIndex >= 0) {
964 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700965 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac02010-04-22 18:58:52 -0700966 resumeWithAppendedMotionSample);
967 } else {
Jeff Brownb6997262010-10-08 22:31:17 -0700968#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +0000969 ALOGD("Dropping event delivery to target with channel '%s' because it "
Jeff Brownb6997262010-10-08 22:31:17 -0700970 "is no longer registered with the input dispatcher.",
Jeff Brown46b9ac02010-04-22 18:58:52 -0700971 inputTarget.inputChannel->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -0700972#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -0700973 }
974 }
975}
976
Jeff Brown54a18252010-09-16 14:07:33 -0700977void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700978 mCurrentInputTargetsValid = false;
979 mCurrentInputTargets.clear();
Jeff Brown5ea29ab2011-07-27 11:50:51 -0700980 resetANRTimeoutsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700981}
982
Jeff Brown01ce2e92010-09-26 22:20:12 -0700983void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700984 mCurrentInputTargetsValid = true;
985}
986
987int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
Jeff Brown9302c872011-07-13 22:51:29 -0700988 const EventEntry* entry,
989 const sp<InputApplicationHandle>& applicationHandle,
990 const sp<InputWindowHandle>& windowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700991 nsecs_t* nextWakeupTime) {
Jeff Brown9302c872011-07-13 22:51:29 -0700992 if (applicationHandle == NULL && windowHandle == NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700993 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
994#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +0000995 ALOGD("Waiting for system to become ready for input.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700996#endif
997 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
998 mInputTargetWaitStartTime = currentTime;
999 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1000 mInputTargetWaitTimeoutExpired = false;
Jeff Brown9302c872011-07-13 22:51:29 -07001001 mInputTargetWaitApplicationHandle.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -07001002 }
1003 } else {
1004 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1005#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001006 ALOGD("Waiting for application to become ready for input: %s",
Jeff Brown9302c872011-07-13 22:51:29 -07001007 getApplicationWindowLabelLocked(applicationHandle, windowHandle).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001008#endif
Jeff Browncc4f7db2011-08-30 20:34:48 -07001009 nsecs_t timeout;
1010 if (windowHandle != NULL) {
1011 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1012 } else if (applicationHandle != NULL) {
1013 timeout = applicationHandle->getDispatchingTimeout(
1014 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1015 } else {
1016 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1017 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001018
1019 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1020 mInputTargetWaitStartTime = currentTime;
1021 mInputTargetWaitTimeoutTime = currentTime + timeout;
1022 mInputTargetWaitTimeoutExpired = false;
Jeff Brown9302c872011-07-13 22:51:29 -07001023 mInputTargetWaitApplicationHandle.clear();
Jeff Brown928e0542011-01-10 11:17:36 -08001024
Jeff Brown9302c872011-07-13 22:51:29 -07001025 if (windowHandle != NULL) {
1026 mInputTargetWaitApplicationHandle = windowHandle->inputApplicationHandle;
Jeff Brown928e0542011-01-10 11:17:36 -08001027 }
Jeff Brown9302c872011-07-13 22:51:29 -07001028 if (mInputTargetWaitApplicationHandle == NULL && applicationHandle != NULL) {
1029 mInputTargetWaitApplicationHandle = applicationHandle;
Jeff Brown928e0542011-01-10 11:17:36 -08001030 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001031 }
1032 }
1033
1034 if (mInputTargetWaitTimeoutExpired) {
1035 return INPUT_EVENT_INJECTION_TIMED_OUT;
1036 }
1037
1038 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown9302c872011-07-13 22:51:29 -07001039 onANRLocked(currentTime, applicationHandle, windowHandle,
1040 entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001041
1042 // Force poll loop to wake up immediately on next iteration once we get the
1043 // ANR response back from the policy.
1044 *nextWakeupTime = LONG_LONG_MIN;
1045 return INPUT_EVENT_INJECTION_PENDING;
1046 } else {
1047 // Force poll loop to wake up when timeout is due.
1048 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1049 *nextWakeupTime = mInputTargetWaitTimeoutTime;
1050 }
1051 return INPUT_EVENT_INJECTION_PENDING;
1052 }
1053}
1054
Jeff Brown519e0242010-09-15 15:18:56 -07001055void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1056 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001057 if (newTimeout > 0) {
1058 // Extend the timeout.
1059 mInputTargetWaitTimeoutTime = now() + newTimeout;
1060 } else {
1061 // Give up.
1062 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -07001063
Jeff Brown01ce2e92010-09-26 22:20:12 -07001064 // Release the touch targets.
1065 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07001066
Jeff Brown519e0242010-09-15 15:18:56 -07001067 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -07001068 if (inputChannel.get()) {
1069 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1070 if (connectionIndex >= 0) {
1071 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown00045a72010-12-09 18:10:30 -08001072 if (connection->status == Connection::STATUS_NORMAL) {
Jeff Brownda3d5a92011-03-29 15:11:34 -07001073 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
Jeff Brown00045a72010-12-09 18:10:30 -08001074 "application not responding");
Jeff Brownda3d5a92011-03-29 15:11:34 -07001075 synthesizeCancelationEventsForConnectionLocked(connection, options);
Jeff Brown00045a72010-12-09 18:10:30 -08001076 }
Jeff Browndc3e0052010-09-16 11:02:16 -07001077 }
Jeff Brown519e0242010-09-15 15:18:56 -07001078 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001079 }
1080}
1081
Jeff Brown519e0242010-09-15 15:18:56 -07001082nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -07001083 nsecs_t currentTime) {
1084 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1085 return currentTime - mInputTargetWaitStartTime;
1086 }
1087 return 0;
1088}
1089
1090void InputDispatcher::resetANRTimeoutsLocked() {
1091#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001092 ALOGD("Resetting ANR timeouts.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001093#endif
1094
Jeff Brownb88102f2010-09-08 11:49:43 -07001095 // Reset input target wait timeout.
1096 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
Jeff Brown5ea29ab2011-07-27 11:50:51 -07001097 mInputTargetWaitApplicationHandle.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -07001098}
1099
Jeff Brown01ce2e92010-09-26 22:20:12 -07001100int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
1101 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001102 mCurrentInputTargets.clear();
1103
1104 int32_t injectionResult;
1105
1106 // If there is no currently focused window and no focused application
1107 // then drop the event.
Jeff Brown9302c872011-07-13 22:51:29 -07001108 if (mFocusedWindowHandle == NULL) {
1109 if (mFocusedApplicationHandle != NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001110#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001111 ALOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001112 "focused application that may eventually add a window: %s.",
Jeff Brown9302c872011-07-13 22:51:29 -07001113 getApplicationWindowLabelLocked(mFocusedApplicationHandle, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001114#endif
1115 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Jeff Brown9302c872011-07-13 22:51:29 -07001116 mFocusedApplicationHandle, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001117 goto Unresponsive;
1118 }
1119
Steve Block6215d3f2012-01-04 20:05:49 +00001120 ALOGI("Dropping event because there is no focused window or focused application.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001121 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1122 goto Failed;
1123 }
1124
1125 // Check permissions.
Jeff Brown9302c872011-07-13 22:51:29 -07001126 if (! checkInjectionPermission(mFocusedWindowHandle, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001127 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1128 goto Failed;
1129 }
1130
1131 // If the currently focused window is paused then keep waiting.
Jeff Browncc4f7db2011-08-30 20:34:48 -07001132 if (mFocusedWindowHandle->getInfo()->paused) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001133#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001134 ALOGD("Waiting because focused window is paused.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001135#endif
1136 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Jeff Brown9302c872011-07-13 22:51:29 -07001137 mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001138 goto Unresponsive;
1139 }
1140
Jeff Brown519e0242010-09-15 15:18:56 -07001141 // If the currently focused window is still working on previous events then keep waiting.
Jeff Brown9302c872011-07-13 22:51:29 -07001142 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindowHandle)) {
Jeff Brown519e0242010-09-15 15:18:56 -07001143#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001144 ALOGD("Waiting because focused window still processing previous input.");
Jeff Brown519e0242010-09-15 15:18:56 -07001145#endif
1146 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Jeff Brown9302c872011-07-13 22:51:29 -07001147 mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime);
Jeff Brown519e0242010-09-15 15:18:56 -07001148 goto Unresponsive;
1149 }
1150
Jeff Brownb88102f2010-09-08 11:49:43 -07001151 // Success! Output targets.
1152 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown9302c872011-07-13 22:51:29 -07001153 addWindowTargetLocked(mFocusedWindowHandle,
Jeff Browna032cc02011-03-07 16:56:21 -08001154 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001155
1156 // Done.
1157Failed:
1158Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001159 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1160 updateDispatchStatisticsLocked(currentTime, entry,
1161 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001162#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001163 ALOGD("findFocusedWindow finished: injectionResult=%d, "
Jeff Brown519e0242010-09-15 15:18:56 -07001164 "timeSpendWaitingForApplication=%0.1fms",
1165 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001166#endif
1167 return injectionResult;
1168}
1169
Jeff Brown01ce2e92010-09-26 22:20:12 -07001170int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
Jeff Browna032cc02011-03-07 16:56:21 -08001171 const MotionEntry* entry, nsecs_t* nextWakeupTime, bool* outConflictingPointerActions,
1172 const MotionSample** outSplitBatchAfterSample) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001173 enum InjectionPermission {
1174 INJECTION_PERMISSION_UNKNOWN,
1175 INJECTION_PERMISSION_GRANTED,
1176 INJECTION_PERMISSION_DENIED
1177 };
1178
Jeff Brownb88102f2010-09-08 11:49:43 -07001179 mCurrentInputTargets.clear();
1180
1181 nsecs_t startTime = now();
1182
1183 // For security reasons, we defer updating the touch state until we are sure that
1184 // event injection will be allowed.
1185 //
1186 // FIXME In the original code, screenWasOff could never be set to true.
1187 // The reason is that the POLICY_FLAG_WOKE_HERE
1188 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1189 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1190 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1191 // events upon which no preprocessing took place. So policyFlags was always 0.
1192 // In the new native input dispatcher we're a bit more careful about event
1193 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1194 // Unfortunately we obtain undesirable behavior.
1195 //
1196 // Here's what happens:
1197 //
1198 // When the device dims in anticipation of going to sleep, touches
1199 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1200 // the device to brighten and reset the user activity timer.
1201 // Touches on other windows (such as the launcher window)
1202 // are dropped. Then after a moment, the device goes to sleep. Oops.
1203 //
1204 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1205 // instead of POLICY_FLAG_WOKE_HERE...
1206 //
1207 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1208
1209 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001210 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001211
1212 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001213 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1214 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Jeff Brown9302c872011-07-13 22:51:29 -07001215 sp<InputWindowHandle> newHoverWindowHandle;
Jeff Browncc0c1592011-02-19 05:07:28 -08001216
1217 bool isSplit = mTouchState.split;
Jeff Brown2717eff2011-06-30 23:53:07 -07001218 bool switchedDevice = mTouchState.deviceId >= 0
1219 && (mTouchState.deviceId != entry->deviceId
1220 || mTouchState.source != entry->source);
Jeff Browna032cc02011-03-07 16:56:21 -08001221 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1222 || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1223 || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1224 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
1225 || maskedAction == AMOTION_EVENT_ACTION_SCROLL
1226 || isHoverAction);
Jeff Brown81346812011-06-28 20:08:48 -07001227 bool wrongDevice = false;
Jeff Browna032cc02011-03-07 16:56:21 -08001228 if (newGesture) {
Jeff Browncc0c1592011-02-19 05:07:28 -08001229 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Jeff Brown81346812011-06-28 20:08:48 -07001230 if (switchedDevice && mTouchState.down && !down) {
1231#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001232 ALOGD("Dropping event because a pointer for a different device is already down.");
Jeff Brown81346812011-06-28 20:08:48 -07001233#endif
Jeff Browncc0c1592011-02-19 05:07:28 -08001234 mTempTouchState.copyFrom(mTouchState);
Jeff Brown81346812011-06-28 20:08:48 -07001235 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1236 switchedDevice = false;
1237 wrongDevice = true;
1238 goto Failed;
Jeff Browncc0c1592011-02-19 05:07:28 -08001239 }
Jeff Brown81346812011-06-28 20:08:48 -07001240 mTempTouchState.reset();
1241 mTempTouchState.down = down;
1242 mTempTouchState.deviceId = entry->deviceId;
1243 mTempTouchState.source = entry->source;
1244 isSplit = false;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001245 } else {
1246 mTempTouchState.copyFrom(mTouchState);
Jeff Browncc0c1592011-02-19 05:07:28 -08001247 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001248
Jeff Browna032cc02011-03-07 16:56:21 -08001249 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
Jeff Brown33bbfd22011-02-24 20:55:35 -08001250 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001251
Jeff Browna032cc02011-03-07 16:56:21 -08001252 const MotionSample* sample = &entry->firstSample;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001253 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Jeff Browna032cc02011-03-07 16:56:21 -08001254 int32_t x = int32_t(sample->pointerCoords[pointerIndex].
Jeff Brownebbd5d12011-02-17 13:01:34 -08001255 getAxisValue(AMOTION_EVENT_AXIS_X));
Jeff Browna032cc02011-03-07 16:56:21 -08001256 int32_t y = int32_t(sample->pointerCoords[pointerIndex].
Jeff Brownebbd5d12011-02-17 13:01:34 -08001257 getAxisValue(AMOTION_EVENT_AXIS_Y));
Jeff Brown9302c872011-07-13 22:51:29 -07001258 sp<InputWindowHandle> newTouchedWindowHandle;
1259 sp<InputWindowHandle> topErrorWindowHandle;
Jeff Browna032cc02011-03-07 16:56:21 -08001260 bool isTouchModal = false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001261
1262 // Traverse windows from front to back to find touched window and outside targets.
Jeff Brown9302c872011-07-13 22:51:29 -07001263 size_t numWindows = mWindowHandles.size();
Jeff Brownb88102f2010-09-08 11:49:43 -07001264 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown9302c872011-07-13 22:51:29 -07001265 sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
Jeff Browncc4f7db2011-08-30 20:34:48 -07001266 const InputWindowInfo* windowInfo = windowHandle->getInfo();
1267 int32_t flags = windowInfo->layoutParamsFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001268
Jeff Browncc4f7db2011-08-30 20:34:48 -07001269 if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
Jeff Brown9302c872011-07-13 22:51:29 -07001270 if (topErrorWindowHandle == NULL) {
1271 topErrorWindowHandle = windowHandle;
Jeff Brownb88102f2010-09-08 11:49:43 -07001272 }
1273 }
1274
Jeff Browncc4f7db2011-08-30 20:34:48 -07001275 if (windowInfo->visible) {
1276 if (! (flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
1277 isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
1278 | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
1279 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Jeff Brown9302c872011-07-13 22:51:29 -07001280 if (! screenWasOff
Jeff Browncc4f7db2011-08-30 20:34:48 -07001281 || (flags & InputWindowInfo::FLAG_TOUCHABLE_WHEN_WAKING)) {
Jeff Brown9302c872011-07-13 22:51:29 -07001282 newTouchedWindowHandle = windowHandle;
Jeff Brownb88102f2010-09-08 11:49:43 -07001283 }
1284 break; // found touched window, exit window loop
1285 }
1286 }
1287
Jeff Brown01ce2e92010-09-26 22:20:12 -07001288 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
Jeff Browncc4f7db2011-08-30 20:34:48 -07001289 && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Browna032cc02011-03-07 16:56:21 -08001290 int32_t outsideTargetFlags = InputTarget::FLAG_DISPATCH_AS_OUTSIDE;
Jeff Brown9302c872011-07-13 22:51:29 -07001291 if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001292 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1293 }
1294
Jeff Brown9302c872011-07-13 22:51:29 -07001295 mTempTouchState.addOrUpdateWindow(
1296 windowHandle, outsideTargetFlags, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001297 }
1298 }
1299 }
1300
1301 // If there is an error window but it is not taking focus (typically because
1302 // it is invisible) then wait for it. Any other focused window may in
1303 // fact be in ANR state.
Jeff Brown9302c872011-07-13 22:51:29 -07001304 if (topErrorWindowHandle != NULL && newTouchedWindowHandle != topErrorWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001305#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001306 ALOGD("Waiting because system error window is pending.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001307#endif
1308 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1309 NULL, NULL, nextWakeupTime);
1310 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1311 goto Unresponsive;
1312 }
1313
Jeff Brown01ce2e92010-09-26 22:20:12 -07001314 // Figure out whether splitting will be allowed for this window.
Jeff Browncc4f7db2011-08-30 20:34:48 -07001315 if (newTouchedWindowHandle != NULL
1316 && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001317 // New window supports splitting.
1318 isSplit = true;
1319 } else if (isSplit) {
1320 // New window does not support splitting but we have already split events.
1321 // Assign the pointer to the first foreground window we find.
1322 // (May be NULL which is why we put this code block before the next check.)
Jeff Brown9302c872011-07-13 22:51:29 -07001323 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
Jeff Brown01ce2e92010-09-26 22:20:12 -07001324 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001325
Jeff Brownb88102f2010-09-08 11:49:43 -07001326 // If we did not find a touched window then fail.
Jeff Brown9302c872011-07-13 22:51:29 -07001327 if (newTouchedWindowHandle == NULL) {
1328 if (mFocusedApplicationHandle != NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001329#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001330 ALOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001331 "focused application that may eventually add a new window: %s.",
Jeff Brown9302c872011-07-13 22:51:29 -07001332 getApplicationWindowLabelLocked(mFocusedApplicationHandle, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001333#endif
1334 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Jeff Brown9302c872011-07-13 22:51:29 -07001335 mFocusedApplicationHandle, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001336 goto Unresponsive;
1337 }
1338
Steve Block6215d3f2012-01-04 20:05:49 +00001339 ALOGI("Dropping event because there is no touched window or focused application.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001340 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001341 goto Failed;
1342 }
1343
Jeff Brown19dfc832010-10-05 12:26:23 -07001344 // Set target flags.
Jeff Browna032cc02011-03-07 16:56:21 -08001345 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
Jeff Brown19dfc832010-10-05 12:26:23 -07001346 if (isSplit) {
1347 targetFlags |= InputTarget::FLAG_SPLIT;
1348 }
Jeff Brown9302c872011-07-13 22:51:29 -07001349 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001350 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1351 }
1352
Jeff Browna032cc02011-03-07 16:56:21 -08001353 // Update hover state.
1354 if (isHoverAction) {
Jeff Brown9302c872011-07-13 22:51:29 -07001355 newHoverWindowHandle = newTouchedWindowHandle;
Jeff Browna032cc02011-03-07 16:56:21 -08001356
1357 // Ensure all subsequent motion samples are also within the touched window.
1358 // Set *outSplitBatchAfterSample to the sample before the first one that is not
1359 // within the touched window.
1360 if (!isTouchModal) {
1361 while (sample->next) {
Jeff Browncc4f7db2011-08-30 20:34:48 -07001362 if (!newHoverWindowHandle->getInfo()->touchableRegionContainsPoint(
Jeff Browna032cc02011-03-07 16:56:21 -08001363 sample->next->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X),
1364 sample->next->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y))) {
1365 *outSplitBatchAfterSample = sample;
1366 break;
1367 }
1368 sample = sample->next;
1369 }
1370 }
1371 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
Jeff Brown9302c872011-07-13 22:51:29 -07001372 newHoverWindowHandle = mLastHoverWindowHandle;
Jeff Browna032cc02011-03-07 16:56:21 -08001373 }
1374
Jeff Brown01ce2e92010-09-26 22:20:12 -07001375 // Update the temporary touch state.
1376 BitSet32 pointerIds;
1377 if (isSplit) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07001378 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001379 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001380 }
Jeff Brown9302c872011-07-13 22:51:29 -07001381 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001382 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001383 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001384
1385 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001386 if (! mTempTouchState.down) {
Jeff Browna2cc28d2011-03-25 11:58:46 -07001387#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001388 ALOGD("Dropping event because the pointer is not down or we previously "
Jeff Brown76860e32010-10-25 17:37:46 -07001389 "dropped the pointer down event.");
1390#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001391 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001392 goto Failed;
1393 }
Jeff Brown98db5fa2011-06-08 15:37:10 -07001394
1395 // Check whether touches should slip outside of the current foreground window.
1396 if (maskedAction == AMOTION_EVENT_ACTION_MOVE
1397 && entry->pointerCount == 1
1398 && mTempTouchState.isSlippery()) {
1399 const MotionSample* sample = &entry->firstSample;
1400 int32_t x = int32_t(sample->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1401 int32_t y = int32_t(sample->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
1402
Jeff Brown9302c872011-07-13 22:51:29 -07001403 sp<InputWindowHandle> oldTouchedWindowHandle =
1404 mTempTouchState.getFirstForegroundWindowHandle();
1405 sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(x, y);
1406 if (oldTouchedWindowHandle != newTouchedWindowHandle
1407 && newTouchedWindowHandle != NULL) {
Jeff Brown98db5fa2011-06-08 15:37:10 -07001408#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001409 ALOGD("Touch is slipping out of window %s into window %s.",
Jeff Browncc4f7db2011-08-30 20:34:48 -07001410 oldTouchedWindowHandle->getName().string(),
1411 newTouchedWindowHandle->getName().string());
Jeff Brown98db5fa2011-06-08 15:37:10 -07001412#endif
1413 // Make a slippery exit from the old window.
Jeff Brown9302c872011-07-13 22:51:29 -07001414 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
Jeff Brown98db5fa2011-06-08 15:37:10 -07001415 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
1416
1417 // Make a slippery entrance into the new window.
Jeff Browncc4f7db2011-08-30 20:34:48 -07001418 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Jeff Brown98db5fa2011-06-08 15:37:10 -07001419 isSplit = true;
1420 }
1421
1422 int32_t targetFlags = InputTarget::FLAG_FOREGROUND
1423 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
1424 if (isSplit) {
1425 targetFlags |= InputTarget::FLAG_SPLIT;
1426 }
Jeff Brown9302c872011-07-13 22:51:29 -07001427 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
Jeff Brown98db5fa2011-06-08 15:37:10 -07001428 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1429 }
1430
1431 BitSet32 pointerIds;
1432 if (isSplit) {
1433 pointerIds.markBit(entry->pointerProperties[0].id);
1434 }
Jeff Brown9302c872011-07-13 22:51:29 -07001435 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Jeff Brown98db5fa2011-06-08 15:37:10 -07001436
1437 // Split the batch here so we send exactly one sample.
1438 *outSplitBatchAfterSample = &entry->firstSample;
1439 }
1440 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001441 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001442
Jeff Brown9302c872011-07-13 22:51:29 -07001443 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Jeff Browna032cc02011-03-07 16:56:21 -08001444 // Split the batch here so we send exactly one sample as part of ENTER or EXIT.
1445 *outSplitBatchAfterSample = &entry->firstSample;
1446
1447 // Let the previous window know that the hover sequence is over.
Jeff Brown9302c872011-07-13 22:51:29 -07001448 if (mLastHoverWindowHandle != NULL) {
Jeff Browna032cc02011-03-07 16:56:21 -08001449#if DEBUG_HOVER
Steve Block5baa3a62011-12-20 16:23:08 +00001450 ALOGD("Sending hover exit event to window %s.",
Jeff Browncc4f7db2011-08-30 20:34:48 -07001451 mLastHoverWindowHandle->getName().string());
Jeff Browna032cc02011-03-07 16:56:21 -08001452#endif
Jeff Brown9302c872011-07-13 22:51:29 -07001453 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
Jeff Browna032cc02011-03-07 16:56:21 -08001454 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
1455 }
1456
1457 // Let the new window know that the hover sequence is starting.
Jeff Brown9302c872011-07-13 22:51:29 -07001458 if (newHoverWindowHandle != NULL) {
Jeff Browna032cc02011-03-07 16:56:21 -08001459#if DEBUG_HOVER
Steve Block5baa3a62011-12-20 16:23:08 +00001460 ALOGD("Sending hover enter event to window %s.",
Jeff Browncc4f7db2011-08-30 20:34:48 -07001461 newHoverWindowHandle->getName().string());
Jeff Browna032cc02011-03-07 16:56:21 -08001462#endif
Jeff Brown9302c872011-07-13 22:51:29 -07001463 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
Jeff Browna032cc02011-03-07 16:56:21 -08001464 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
1465 }
1466 }
1467
Jeff Brown01ce2e92010-09-26 22:20:12 -07001468 // Check permission to inject into all touched foreground windows and ensure there
1469 // is at least one touched foreground window.
1470 {
1471 bool haveForegroundWindow = false;
1472 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1473 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1474 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1475 haveForegroundWindow = true;
Jeff Brown9302c872011-07-13 22:51:29 -07001476 if (! checkInjectionPermission(touchedWindow.windowHandle,
1477 entry->injectionState)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001478 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1479 injectionPermission = INJECTION_PERMISSION_DENIED;
1480 goto Failed;
1481 }
1482 }
1483 }
1484 if (! haveForegroundWindow) {
Jeff Browna2cc28d2011-03-25 11:58:46 -07001485#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001486 ALOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001487#endif
1488 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001489 goto Failed;
1490 }
1491
Jeff Brown01ce2e92010-09-26 22:20:12 -07001492 // Permission granted to injection into all touched foreground windows.
1493 injectionPermission = INJECTION_PERMISSION_GRANTED;
1494 }
Jeff Brown519e0242010-09-15 15:18:56 -07001495
Kenny Root7a9db182011-06-02 15:16:05 -07001496 // Check whether windows listening for outside touches are owned by the same UID. If it is
1497 // set the policy flag that we will not reveal coordinate information to this window.
1498 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
Jeff Brown9302c872011-07-13 22:51:29 -07001499 sp<InputWindowHandle> foregroundWindowHandle =
1500 mTempTouchState.getFirstForegroundWindowHandle();
Jeff Browncc4f7db2011-08-30 20:34:48 -07001501 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Kenny Root7a9db182011-06-02 15:16:05 -07001502 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1503 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1504 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
Jeff Brown9302c872011-07-13 22:51:29 -07001505 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
Jeff Browncc4f7db2011-08-30 20:34:48 -07001506 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Jeff Brown9302c872011-07-13 22:51:29 -07001507 mTempTouchState.addOrUpdateWindow(inputWindowHandle,
Kenny Root7a9db182011-06-02 15:16:05 -07001508 InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
1509 }
1510 }
1511 }
1512 }
1513
Jeff Brown01ce2e92010-09-26 22:20:12 -07001514 // Ensure all touched foreground windows are ready for new input.
1515 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1516 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1517 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1518 // If the touched window is paused then keep waiting.
Jeff Browncc4f7db2011-08-30 20:34:48 -07001519 if (touchedWindow.windowHandle->getInfo()->paused) {
Jeff Browna2cc28d2011-03-25 11:58:46 -07001520#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001521 ALOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001522#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001523 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Jeff Brown9302c872011-07-13 22:51:29 -07001524 NULL, touchedWindow.windowHandle, nextWakeupTime);
Jeff Brown01ce2e92010-09-26 22:20:12 -07001525 goto Unresponsive;
1526 }
1527
1528 // If the touched window is still working on previous events then keep waiting.
Jeff Brown9302c872011-07-13 22:51:29 -07001529 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.windowHandle)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001530#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001531 ALOGD("Waiting because touched window still processing previous input.");
Jeff Brown01ce2e92010-09-26 22:20:12 -07001532#endif
1533 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
Jeff Brown9302c872011-07-13 22:51:29 -07001534 NULL, touchedWindow.windowHandle, nextWakeupTime);
Jeff Brown01ce2e92010-09-26 22:20:12 -07001535 goto Unresponsive;
1536 }
1537 }
1538 }
1539
1540 // If this is the first pointer going down and the touched window has a wallpaper
1541 // then also add the touched wallpaper windows so they are locked in for the duration
1542 // of the touch gesture.
Jeff Brown33bbfd22011-02-24 20:55:35 -08001543 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1544 // engine only supports touch events. We would need to add a mechanism similar
1545 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1546 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
Jeff Brown9302c872011-07-13 22:51:29 -07001547 sp<InputWindowHandle> foregroundWindowHandle =
1548 mTempTouchState.getFirstForegroundWindowHandle();
Jeff Browncc4f7db2011-08-30 20:34:48 -07001549 if (foregroundWindowHandle->getInfo()->hasWallpaper) {
Jeff Brown9302c872011-07-13 22:51:29 -07001550 for (size_t i = 0; i < mWindowHandles.size(); i++) {
1551 sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
Jeff Browncc4f7db2011-08-30 20:34:48 -07001552 if (windowHandle->getInfo()->layoutParamsType
1553 == InputWindowInfo::TYPE_WALLPAPER) {
Jeff Brown9302c872011-07-13 22:51:29 -07001554 mTempTouchState.addOrUpdateWindow(windowHandle,
Jeff Browna032cc02011-03-07 16:56:21 -08001555 InputTarget::FLAG_WINDOW_IS_OBSCURED
1556 | InputTarget::FLAG_DISPATCH_AS_IS,
1557 BitSet32(0));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001558 }
1559 }
1560 }
1561 }
1562
Jeff Brownb88102f2010-09-08 11:49:43 -07001563 // Success! Output targets.
1564 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001565
Jeff Brown01ce2e92010-09-26 22:20:12 -07001566 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1567 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
Jeff Brown9302c872011-07-13 22:51:29 -07001568 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001569 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001570 }
1571
Jeff Browna032cc02011-03-07 16:56:21 -08001572 // Drop the outside or hover touch windows since we will not care about them
1573 // in the next iteration.
1574 mTempTouchState.filterNonAsIsTouchWindows();
Jeff Brown01ce2e92010-09-26 22:20:12 -07001575
Jeff Brownb88102f2010-09-08 11:49:43 -07001576Failed:
1577 // Check injection permission once and for all.
1578 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001579 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001580 injectionPermission = INJECTION_PERMISSION_GRANTED;
1581 } else {
1582 injectionPermission = INJECTION_PERMISSION_DENIED;
1583 }
1584 }
1585
1586 // Update final pieces of touch state if the injector had permission.
1587 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown95712852011-01-04 19:41:59 -08001588 if (!wrongDevice) {
Jeff Brown81346812011-06-28 20:08:48 -07001589 if (switchedDevice) {
1590#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001591 ALOGD("Conflicting pointer actions: Switched to a different device.");
Jeff Brown81346812011-06-28 20:08:48 -07001592#endif
1593 *outConflictingPointerActions = true;
1594 }
1595
1596 if (isHoverAction) {
1597 // Started hovering, therefore no longer down.
1598 if (mTouchState.down) {
1599#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001600 ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
Jeff Brown81346812011-06-28 20:08:48 -07001601#endif
1602 *outConflictingPointerActions = true;
1603 }
1604 mTouchState.reset();
1605 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1606 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
1607 mTouchState.deviceId = entry->deviceId;
1608 mTouchState.source = entry->source;
1609 }
1610 } else if (maskedAction == AMOTION_EVENT_ACTION_UP
1611 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Jeff Brown95712852011-01-04 19:41:59 -08001612 // All pointers up or canceled.
Jeff Brown33bbfd22011-02-24 20:55:35 -08001613 mTouchState.reset();
Jeff Brown95712852011-01-04 19:41:59 -08001614 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1615 // First pointer went down.
1616 if (mTouchState.down) {
Jeff Brownb6997262010-10-08 22:31:17 -07001617#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001618 ALOGD("Conflicting pointer actions: Down received while already down.");
Jeff Brownb6997262010-10-08 22:31:17 -07001619#endif
Jeff Brown81346812011-06-28 20:08:48 -07001620 *outConflictingPointerActions = true;
Jeff Brown95712852011-01-04 19:41:59 -08001621 }
Jeff Brown33bbfd22011-02-24 20:55:35 -08001622 mTouchState.copyFrom(mTempTouchState);
Jeff Brown95712852011-01-04 19:41:59 -08001623 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1624 // One pointer went up.
1625 if (isSplit) {
1626 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07001627 uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
Jeff Brownb88102f2010-09-08 11:49:43 -07001628
Jeff Brown95712852011-01-04 19:41:59 -08001629 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1630 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1631 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1632 touchedWindow.pointerIds.clearBit(pointerId);
1633 if (touchedWindow.pointerIds.isEmpty()) {
1634 mTempTouchState.windows.removeAt(i);
1635 continue;
1636 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001637 }
Jeff Brown95712852011-01-04 19:41:59 -08001638 i += 1;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001639 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001640 }
Jeff Brown33bbfd22011-02-24 20:55:35 -08001641 mTouchState.copyFrom(mTempTouchState);
1642 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1643 // Discard temporary touch state since it was only valid for this action.
1644 } else {
1645 // Save changes to touch state as-is for all other actions.
1646 mTouchState.copyFrom(mTempTouchState);
Jeff Brownb88102f2010-09-08 11:49:43 -07001647 }
Jeff Browna032cc02011-03-07 16:56:21 -08001648
1649 // Update hover state.
Jeff Brown9302c872011-07-13 22:51:29 -07001650 mLastHoverWindowHandle = newHoverWindowHandle;
Jeff Brown95712852011-01-04 19:41:59 -08001651 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001652 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001653#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001654 ALOGD("Not updating touch focus because injection was denied.");
Jeff Brown01ce2e92010-09-26 22:20:12 -07001655#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001656 }
1657
1658Unresponsive:
Jeff Brown120a4592010-10-27 18:43:51 -07001659 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1660 mTempTouchState.reset();
1661
Jeff Brown519e0242010-09-15 15:18:56 -07001662 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1663 updateDispatchStatisticsLocked(currentTime, entry,
1664 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001665#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001666 ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001667 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001668 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001669#endif
1670 return injectionResult;
1671}
1672
Jeff Brown9302c872011-07-13 22:51:29 -07001673void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
1674 int32_t targetFlags, BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001675 mCurrentInputTargets.push();
1676
Jeff Browncc4f7db2011-08-30 20:34:48 -07001677 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Jeff Brownb88102f2010-09-08 11:49:43 -07001678 InputTarget& target = mCurrentInputTargets.editTop();
Jeff Browncc4f7db2011-08-30 20:34:48 -07001679 target.inputChannel = windowInfo->inputChannel;
Jeff Brownb88102f2010-09-08 11:49:43 -07001680 target.flags = targetFlags;
Jeff Browncc4f7db2011-08-30 20:34:48 -07001681 target.xOffset = - windowInfo->frameLeft;
1682 target.yOffset = - windowInfo->frameTop;
1683 target.scaleFactor = windowInfo->scaleFactor;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001684 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001685}
1686
1687void InputDispatcher::addMonitoringTargetsLocked() {
1688 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1689 mCurrentInputTargets.push();
1690
1691 InputTarget& target = mCurrentInputTargets.editTop();
1692 target.inputChannel = mMonitoringChannels[i];
Jeff Brownb6110c22011-04-01 16:15:13 -07001693 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Jeff Brownb88102f2010-09-08 11:49:43 -07001694 target.xOffset = 0;
1695 target.yOffset = 0;
Jeff Brownb6110c22011-04-01 16:15:13 -07001696 target.pointerIds.clear();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001697 target.scaleFactor = 1.0f;
Jeff Brownb88102f2010-09-08 11:49:43 -07001698 }
1699}
1700
Jeff Brown9302c872011-07-13 22:51:29 -07001701bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001702 const InjectionState* injectionState) {
1703 if (injectionState
Jeff Browncc4f7db2011-08-30 20:34:48 -07001704 && (windowHandle == NULL
1705 || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
Jeff Brownb6997262010-10-08 22:31:17 -07001706 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Jeff Brown9302c872011-07-13 22:51:29 -07001707 if (windowHandle != NULL) {
Steve Block8564c8d2012-01-05 23:22:43 +00001708 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Jeff Brown9302c872011-07-13 22:51:29 -07001709 "owned by uid %d",
Jeff Brownb6997262010-10-08 22:31:17 -07001710 injectionState->injectorPid, injectionState->injectorUid,
Jeff Browncc4f7db2011-08-30 20:34:48 -07001711 windowHandle->getName().string(),
1712 windowHandle->getInfo()->ownerUid);
Jeff Brownb6997262010-10-08 22:31:17 -07001713 } else {
Steve Block8564c8d2012-01-05 23:22:43 +00001714 ALOGW("Permission denied: injecting event from pid %d uid %d",
Jeff Brownb6997262010-10-08 22:31:17 -07001715 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001716 }
Jeff Brownb6997262010-10-08 22:31:17 -07001717 return false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001718 }
1719 return true;
1720}
1721
Jeff Brown19dfc832010-10-05 12:26:23 -07001722bool InputDispatcher::isWindowObscuredAtPointLocked(
Jeff Brown9302c872011-07-13 22:51:29 -07001723 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
1724 size_t numWindows = mWindowHandles.size();
Jeff Brownb88102f2010-09-08 11:49:43 -07001725 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown9302c872011-07-13 22:51:29 -07001726 sp<InputWindowHandle> otherHandle = mWindowHandles.itemAt(i);
1727 if (otherHandle == windowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001728 break;
1729 }
Jeff Browncc4f7db2011-08-30 20:34:48 -07001730
1731 const InputWindowInfo* otherInfo = otherHandle->getInfo();
1732 if (otherInfo->visible && ! otherInfo->isTrustedOverlay()
1733 && otherInfo->frameContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001734 return true;
1735 }
1736 }
1737 return false;
1738}
1739
Jeff Brown9302c872011-07-13 22:51:29 -07001740bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(
1741 const sp<InputWindowHandle>& windowHandle) {
Jeff Browncc4f7db2011-08-30 20:34:48 -07001742 ssize_t connectionIndex = getConnectionIndexLocked(windowHandle->getInputChannel());
Jeff Brown519e0242010-09-15 15:18:56 -07001743 if (connectionIndex >= 0) {
1744 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1745 return connection->outboundQueue.isEmpty();
1746 } else {
1747 return true;
1748 }
1749}
1750
Jeff Brown9302c872011-07-13 22:51:29 -07001751String8 InputDispatcher::getApplicationWindowLabelLocked(
1752 const sp<InputApplicationHandle>& applicationHandle,
1753 const sp<InputWindowHandle>& windowHandle) {
1754 if (applicationHandle != NULL) {
1755 if (windowHandle != NULL) {
Jeff Browncc4f7db2011-08-30 20:34:48 -07001756 String8 label(applicationHandle->getName());
Jeff Brown519e0242010-09-15 15:18:56 -07001757 label.append(" - ");
Jeff Browncc4f7db2011-08-30 20:34:48 -07001758 label.append(windowHandle->getName());
Jeff Brown519e0242010-09-15 15:18:56 -07001759 return label;
1760 } else {
Jeff Browncc4f7db2011-08-30 20:34:48 -07001761 return applicationHandle->getName();
Jeff Brown519e0242010-09-15 15:18:56 -07001762 }
Jeff Brown9302c872011-07-13 22:51:29 -07001763 } else if (windowHandle != NULL) {
Jeff Browncc4f7db2011-08-30 20:34:48 -07001764 return windowHandle->getName();
Jeff Brown519e0242010-09-15 15:18:56 -07001765 } else {
1766 return String8("<unknown application or window>");
1767 }
1768}
1769
Jeff Browne2fe69e2010-10-18 13:21:23 -07001770void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
Jeff Brown56194eb2011-03-02 19:23:13 -08001771 int32_t eventType = POWER_MANAGER_OTHER_EVENT;
Jeff Brown4d396052010-10-29 21:50:21 -07001772 switch (eventEntry->type) {
1773 case EventEntry::TYPE_MOTION: {
Jeff Browne2fe69e2010-10-18 13:21:23 -07001774 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Brown4d396052010-10-29 21:50:21 -07001775 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1776 return;
1777 }
1778
Jeff Brown56194eb2011-03-02 19:23:13 -08001779 if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
Joe Onorato1a542c72010-11-08 09:48:20 -08001780 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001781 }
Jeff Brown4d396052010-10-29 21:50:21 -07001782 break;
1783 }
1784 case EventEntry::TYPE_KEY: {
1785 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1786 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1787 return;
1788 }
Jeff Brown56194eb2011-03-02 19:23:13 -08001789 eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brown4d396052010-10-29 21:50:21 -07001790 break;
1791 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001792 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001793
Jeff Brownb88102f2010-09-08 11:49:43 -07001794 CommandEntry* commandEntry = postCommandLocked(
1795 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Browne2fe69e2010-10-18 13:21:23 -07001796 commandEntry->eventTime = eventEntry->eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001797 commandEntry->userActivityEventType = eventType;
1798}
1799
Jeff Brown7fbdc842010-06-17 20:52:56 -07001800void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1801 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001802 bool resumeWithAppendedMotionSample) {
1803#if DEBUG_DISPATCH_CYCLE
Steve Block5baa3a62011-12-20 16:23:08 +00001804 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Jeff Brown9cc695c2011-08-23 18:35:04 -07001805 "xOffset=%f, yOffset=%f, scaleFactor=%f, "
Jeff Brown83c09682010-12-23 17:50:18 -08001806 "pointerIds=0x%x, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001807 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001808 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001809 inputTarget->xOffset, inputTarget->yOffset,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001810 inputTarget->scaleFactor, inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001811 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac02010-04-22 18:58:52 -07001812#endif
1813
Jeff Brown01ce2e92010-09-26 22:20:12 -07001814 // Make sure we are never called for streaming when splitting across multiple windows.
1815 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
Steve Blockec193de2012-01-09 18:35:44 +00001816 ALOG_ASSERT(! (resumeWithAppendedMotionSample && isSplit));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001817
Jeff Brown46b9ac02010-04-22 18:58:52 -07001818 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001819 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac02010-04-22 18:58:52 -07001820 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb6997262010-10-08 22:31:17 -07001821#if DEBUG_DISPATCH_CYCLE
Steve Block5baa3a62011-12-20 16:23:08 +00001822 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001823 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brownb6997262010-10-08 22:31:17 -07001824#endif
Jeff Brown46b9ac02010-04-22 18:58:52 -07001825 return;
1826 }
1827
Jeff Brown01ce2e92010-09-26 22:20:12 -07001828 // Split a motion event if needed.
1829 if (isSplit) {
Steve Blockec193de2012-01-09 18:35:44 +00001830 ALOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
Jeff Brown01ce2e92010-09-26 22:20:12 -07001831
1832 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1833 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1834 MotionEntry* splitMotionEntry = splitMotionEvent(
1835 originalMotionEntry, inputTarget->pointerIds);
Jeff Brown58a2da82011-01-25 16:02:22 -08001836 if (!splitMotionEntry) {
1837 return; // split event was dropped
1838 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001839#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00001840 ALOGD("channel '%s' ~ Split motion event.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07001841 connection->getInputChannelName());
1842 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1843#endif
Jeff Brownc0cb3dc2012-01-12 18:30:12 -08001844 enqueueDispatchEntriesLocked(currentTime, connection,
1845 splitMotionEntry, inputTarget, resumeWithAppendedMotionSample);
1846 splitMotionEntry->release();
1847 return;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001848 }
1849 }
1850
Jeff Brownc0cb3dc2012-01-12 18:30:12 -08001851 // Not splitting. Enqueue dispatch entries for the event as is.
1852 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget,
1853 resumeWithAppendedMotionSample);
1854}
1855
1856void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
1857 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
1858 bool resumeWithAppendedMotionSample) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001859 // Resume the dispatch cycle with a freshly appended motion sample.
1860 // First we check that the last dispatch entry in the outbound queue is for the same
1861 // motion event to which we appended the motion sample. If we find such a dispatch
1862 // entry, and if it is currently in progress then we try to stream the new sample.
1863 bool wasEmpty = connection->outboundQueue.isEmpty();
1864
1865 if (! wasEmpty && resumeWithAppendedMotionSample) {
1866 DispatchEntry* motionEventDispatchEntry =
1867 connection->findQueuedDispatchEntryForEvent(eventEntry);
1868 if (motionEventDispatchEntry) {
1869 // If the dispatch entry is not in progress, then we must be busy dispatching an
1870 // earlier event. Not a problem, the motion event is on the outbound queue and will
1871 // be dispatched later.
1872 if (! motionEventDispatchEntry->inProgress) {
1873#if DEBUG_BATCHING
Steve Block5baa3a62011-12-20 16:23:08 +00001874 ALOGD("channel '%s' ~ Not streaming because the motion event has "
Jeff Brown46b9ac02010-04-22 18:58:52 -07001875 "not yet been dispatched. "
1876 "(Waiting for earlier events to be consumed.)",
1877 connection->getInputChannelName());
1878#endif
1879 return;
1880 }
1881
1882 // If the dispatch entry is in progress but it already has a tail of pending
1883 // motion samples, then it must mean that the shared memory buffer filled up.
1884 // Not a problem, when this dispatch cycle is finished, we will eventually start
1885 // a new dispatch cycle to process the tail and that tail includes the newly
1886 // appended motion sample.
1887 if (motionEventDispatchEntry->tailMotionSample) {
1888#if DEBUG_BATCHING
Steve Block5baa3a62011-12-20 16:23:08 +00001889 ALOGD("channel '%s' ~ Not streaming because no new samples can "
Jeff Brown46b9ac02010-04-22 18:58:52 -07001890 "be appended to the motion event in this dispatch cycle. "
1891 "(Waiting for next dispatch cycle to start.)",
1892 connection->getInputChannelName());
1893#endif
1894 return;
1895 }
1896
Jeff Brown81346812011-06-28 20:08:48 -07001897 // If the motion event was modified in flight, then we cannot stream the sample.
1898 if ((motionEventDispatchEntry->targetFlags & InputTarget::FLAG_DISPATCH_MASK)
1899 != InputTarget::FLAG_DISPATCH_AS_IS) {
1900#if DEBUG_BATCHING
Steve Block5baa3a62011-12-20 16:23:08 +00001901 ALOGD("channel '%s' ~ Not streaming because the motion event was not "
Jeff Brown81346812011-06-28 20:08:48 -07001902 "being dispatched as-is. "
1903 "(Waiting for next dispatch cycle to start.)",
1904 connection->getInputChannelName());
1905#endif
1906 return;
1907 }
1908
Jeff Brown46b9ac02010-04-22 18:58:52 -07001909 // The dispatch entry is in progress and is still potentially open for streaming.
1910 // Try to stream the new motion sample. This might fail if the consumer has already
1911 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001912 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1913 MotionSample* appendedMotionSample = motionEntry->lastSample;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001914 status_t status;
1915 if (motionEventDispatchEntry->scaleFactor == 1.0f) {
1916 status = connection->inputPublisher.appendMotionSample(
1917 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1918 } else {
1919 PointerCoords scaledCoords[MAX_POINTERS];
1920 for (size_t i = 0; i < motionEntry->pointerCount; i++) {
1921 scaledCoords[i] = appendedMotionSample->pointerCoords[i];
1922 scaledCoords[i].scale(motionEventDispatchEntry->scaleFactor);
1923 }
1924 status = connection->inputPublisher.appendMotionSample(
1925 appendedMotionSample->eventTime, scaledCoords);
1926 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001927 if (status == OK) {
1928#if DEBUG_BATCHING
Steve Block5baa3a62011-12-20 16:23:08 +00001929 ALOGD("channel '%s' ~ Successfully streamed new motion sample.",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001930 connection->getInputChannelName());
1931#endif
1932 return;
1933 }
1934
1935#if DEBUG_BATCHING
1936 if (status == NO_MEMORY) {
Steve Block5baa3a62011-12-20 16:23:08 +00001937 ALOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown46b9ac02010-04-22 18:58:52 -07001938 "dispatched move event because the shared memory buffer is full. "
1939 "(Waiting for next dispatch cycle to start.)",
1940 connection->getInputChannelName());
1941 } else if (status == status_t(FAILED_TRANSACTION)) {
Steve Block5baa3a62011-12-20 16:23:08 +00001942 ALOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001943 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac02010-04-22 18:58:52 -07001944 "(Waiting for next dispatch cycle to start.)",
1945 connection->getInputChannelName());
1946 } else {
Steve Block5baa3a62011-12-20 16:23:08 +00001947 ALOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown46b9ac02010-04-22 18:58:52 -07001948 "dispatched move event due to an error, status=%d. "
1949 "(Waiting for next dispatch cycle to start.)",
1950 connection->getInputChannelName(), status);
1951 }
1952#endif
1953 // Failed to stream. Start a new tail of pending motion samples to dispatch
1954 // in the next cycle.
1955 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1956 return;
1957 }
1958 }
1959
Jeff Browna032cc02011-03-07 16:56:21 -08001960 // Enqueue dispatch entries for the requested modes.
1961 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1962 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
1963 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1964 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
1965 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1966 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
1967 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1968 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brown98db5fa2011-06-08 15:37:10 -07001969 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1970 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
1971 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1972 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Jeff Browna032cc02011-03-07 16:56:21 -08001973
1974 // If the outbound queue was previously empty, start the dispatch cycle going.
Jeff Brownb6110c22011-04-01 16:15:13 -07001975 if (wasEmpty && !connection->outboundQueue.isEmpty()) {
Jeff Browna032cc02011-03-07 16:56:21 -08001976 activateConnectionLocked(connection.get());
1977 startDispatchCycleLocked(currentTime, connection);
1978 }
1979}
1980
1981void InputDispatcher::enqueueDispatchEntryLocked(
1982 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
1983 bool resumeWithAppendedMotionSample, int32_t dispatchMode) {
1984 int32_t inputTargetFlags = inputTarget->flags;
1985 if (!(inputTargetFlags & dispatchMode)) {
1986 return;
1987 }
1988 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
1989
Jeff Brown46b9ac02010-04-22 18:58:52 -07001990 // This is a new event.
1991 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownac386072011-07-20 15:19:50 -07001992 DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07001993 inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001994 inputTarget->scaleFactor);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001995
Jeff Brown46b9ac02010-04-22 18:58:52 -07001996 // Handle the case where we could not stream a new motion sample because the consumer has
1997 // already consumed the motion event (otherwise the corresponding dispatch entry would
1998 // still be in the outbound queue for this connection). We set the head motion sample
1999 // to the list starting with the newly appended motion sample.
2000 if (resumeWithAppendedMotionSample) {
2001#if DEBUG_BATCHING
Steve Block5baa3a62011-12-20 16:23:08 +00002002 ALOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
Jeff Brown46b9ac02010-04-22 18:58:52 -07002003 "that cannot be streamed because the motion event has already been consumed.",
2004 connection->getInputChannelName());
2005#endif
2006 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
2007 dispatchEntry->headMotionSample = appendedMotionSample;
2008 }
2009
Jeff Brown81346812011-06-28 20:08:48 -07002010 // Apply target flags and update the connection's input state.
2011 switch (eventEntry->type) {
2012 case EventEntry::TYPE_KEY: {
2013 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
2014 dispatchEntry->resolvedAction = keyEntry->action;
2015 dispatchEntry->resolvedFlags = keyEntry->flags;
2016
2017 if (!connection->inputState.trackKey(keyEntry,
2018 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2019#if DEBUG_DISPATCH_CYCLE
Steve Block5baa3a62011-12-20 16:23:08 +00002020 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
Jeff Brown81346812011-06-28 20:08:48 -07002021 connection->getInputChannelName());
2022#endif
Jeff Brownc0cb3dc2012-01-12 18:30:12 -08002023 delete dispatchEntry;
Jeff Brown81346812011-06-28 20:08:48 -07002024 return; // skip the inconsistent event
2025 }
2026 break;
2027 }
2028
2029 case EventEntry::TYPE_MOTION: {
2030 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
2031 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2032 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2033 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2034 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2035 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2036 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2037 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2038 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2039 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2040 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2041 } else {
2042 dispatchEntry->resolvedAction = motionEntry->action;
2043 }
2044 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
2045 && !connection->inputState.isHovering(
2046 motionEntry->deviceId, motionEntry->source)) {
2047#if DEBUG_DISPATCH_CYCLE
Steve Block5baa3a62011-12-20 16:23:08 +00002048 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
Jeff Brown81346812011-06-28 20:08:48 -07002049 connection->getInputChannelName());
2050#endif
2051 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2052 }
2053
2054 dispatchEntry->resolvedFlags = motionEntry->flags;
2055 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2056 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2057 }
2058
2059 if (!connection->inputState.trackMotion(motionEntry,
2060 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
2061#if DEBUG_DISPATCH_CYCLE
Steve Block5baa3a62011-12-20 16:23:08 +00002062 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
Jeff Brown81346812011-06-28 20:08:48 -07002063 connection->getInputChannelName());
2064#endif
Jeff Brownc0cb3dc2012-01-12 18:30:12 -08002065 delete dispatchEntry;
Jeff Brown81346812011-06-28 20:08:48 -07002066 return; // skip the inconsistent event
2067 }
2068 break;
2069 }
2070 }
2071
Jeff Brownc0cb3dc2012-01-12 18:30:12 -08002072 // Remember that we are waiting for this dispatch to complete.
2073 if (dispatchEntry->hasForegroundTarget()) {
2074 incrementPendingForegroundDispatchesLocked(eventEntry);
2075 }
2076
Jeff Brown46b9ac02010-04-22 18:58:52 -07002077 // Enqueue the dispatch entry.
2078 connection->outboundQueue.enqueueAtTail(dispatchEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002079}
2080
Jeff Brown7fbdc842010-06-17 20:52:56 -07002081void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07002082 const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002083#if DEBUG_DISPATCH_CYCLE
Steve Block5baa3a62011-12-20 16:23:08 +00002084 ALOGD("channel '%s' ~ startDispatchCycle",
Jeff Brown46b9ac02010-04-22 18:58:52 -07002085 connection->getInputChannelName());
2086#endif
2087
Steve Blockec193de2012-01-09 18:35:44 +00002088 ALOG_ASSERT(connection->status == Connection::STATUS_NORMAL);
2089 ALOG_ASSERT(! connection->outboundQueue.isEmpty());
Jeff Brown46b9ac02010-04-22 18:58:52 -07002090
Jeff Brownac386072011-07-20 15:19:50 -07002091 DispatchEntry* dispatchEntry = connection->outboundQueue.head;
Steve Blockec193de2012-01-09 18:35:44 +00002092 ALOG_ASSERT(! dispatchEntry->inProgress);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002093
Jeff Brownb88102f2010-09-08 11:49:43 -07002094 // Mark the dispatch entry as in progress.
2095 dispatchEntry->inProgress = true;
2096
Jeff Brown46b9ac02010-04-22 18:58:52 -07002097 // Publish the event.
2098 status_t status;
Jeff Browna032cc02011-03-07 16:56:21 -08002099 EventEntry* eventEntry = dispatchEntry->eventEntry;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002100 switch (eventEntry->type) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002101 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002102 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002103
Jeff Brown46b9ac02010-04-22 18:58:52 -07002104 // Publish the key event.
Jeff Brown81346812011-06-28 20:08:48 -07002105 status = connection->inputPublisher.publishKeyEvent(
2106 keyEntry->deviceId, keyEntry->source,
2107 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
2108 keyEntry->keyCode, keyEntry->scanCode,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002109 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
2110 keyEntry->eventTime);
2111
2112 if (status) {
Steve Block3762c312012-01-06 19:20:56 +00002113 ALOGE("channel '%s' ~ Could not publish key event, "
Jeff Brown46b9ac02010-04-22 18:58:52 -07002114 "status=%d", connection->getInputChannelName(), status);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002115 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002116 return;
2117 }
2118 break;
2119 }
2120
2121 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002122 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002123
Jeff Brown46b9ac02010-04-22 18:58:52 -07002124 // If headMotionSample is non-NULL, then it points to the first new sample that we
2125 // were unable to dispatch during the previous cycle so we resume dispatching from
2126 // that point in the list of motion samples.
2127 // Otherwise, we just start from the first sample of the motion event.
2128 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
2129 if (! firstMotionSample) {
2130 firstMotionSample = & motionEntry->firstSample;
2131 }
2132
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002133 PointerCoords scaledCoords[MAX_POINTERS];
2134 const PointerCoords* usingCoords = firstMotionSample->pointerCoords;
2135
Jeff Brownd3616592010-07-16 17:21:06 -07002136 // Set the X and Y offset depending on the input source.
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002137 float xOffset, yOffset, scaleFactor;
Kenny Root7a9db182011-06-02 15:16:05 -07002138 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER
2139 && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002140 scaleFactor = dispatchEntry->scaleFactor;
2141 xOffset = dispatchEntry->xOffset * scaleFactor;
2142 yOffset = dispatchEntry->yOffset * scaleFactor;
2143 if (scaleFactor != 1.0f) {
2144 for (size_t i = 0; i < motionEntry->pointerCount; i++) {
2145 scaledCoords[i] = firstMotionSample->pointerCoords[i];
2146 scaledCoords[i].scale(scaleFactor);
2147 }
2148 usingCoords = scaledCoords;
2149 }
Jeff Brownd3616592010-07-16 17:21:06 -07002150 } else {
2151 xOffset = 0.0f;
2152 yOffset = 0.0f;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002153 scaleFactor = 1.0f;
Kenny Root7a9db182011-06-02 15:16:05 -07002154
2155 // We don't want the dispatch target to know.
2156 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
2157 for (size_t i = 0; i < motionEntry->pointerCount; i++) {
2158 scaledCoords[i].clear();
2159 }
2160 usingCoords = scaledCoords;
2161 }
Jeff Brownd3616592010-07-16 17:21:06 -07002162 }
2163
Jeff Brown46b9ac02010-04-22 18:58:52 -07002164 // Publish the motion event and the first motion sample.
Jeff Brown81346812011-06-28 20:08:48 -07002165 status = connection->inputPublisher.publishMotionEvent(
2166 motionEntry->deviceId, motionEntry->source,
2167 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
2168 motionEntry->edgeFlags, motionEntry->metaState, motionEntry->buttonState,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07002169 xOffset, yOffset,
2170 motionEntry->xPrecision, motionEntry->yPrecision,
Jeff Brown46b9ac02010-04-22 18:58:52 -07002171 motionEntry->downTime, firstMotionSample->eventTime,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07002172 motionEntry->pointerCount, motionEntry->pointerProperties,
2173 usingCoords);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002174
2175 if (status) {
Steve Block3762c312012-01-06 19:20:56 +00002176 ALOGE("channel '%s' ~ Could not publish motion event, "
Jeff Brown46b9ac02010-04-22 18:58:52 -07002177 "status=%d", connection->getInputChannelName(), status);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002178 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002179 return;
2180 }
2181
Jeff Brown81346812011-06-28 20:08:48 -07002182 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_MOVE
2183 || dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Browna032cc02011-03-07 16:56:21 -08002184 // Append additional motion samples.
2185 MotionSample* nextMotionSample = firstMotionSample->next;
2186 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07002187 if (usingCoords == scaledCoords) {
Kenny Root7a9db182011-06-02 15:16:05 -07002188 if (!(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2189 for (size_t i = 0; i < motionEntry->pointerCount; i++) {
2190 scaledCoords[i] = nextMotionSample->pointerCoords[i];
2191 scaledCoords[i].scale(scaleFactor);
2192 }
Dianne Hackborn2ba3e802011-05-11 10:59:54 -07002193 }
2194 } else {
2195 usingCoords = nextMotionSample->pointerCoords;
Dianne Hackborne7d25b72011-05-09 21:19:26 -07002196 }
Jeff Browna032cc02011-03-07 16:56:21 -08002197 status = connection->inputPublisher.appendMotionSample(
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07002198 nextMotionSample->eventTime, usingCoords);
Jeff Browna032cc02011-03-07 16:56:21 -08002199 if (status == NO_MEMORY) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002200#if DEBUG_DISPATCH_CYCLE
Steve Block5baa3a62011-12-20 16:23:08 +00002201 ALOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
Jeff Brown46b9ac02010-04-22 18:58:52 -07002202 "be sent in the next dispatch cycle.",
2203 connection->getInputChannelName());
2204#endif
Jeff Browna032cc02011-03-07 16:56:21 -08002205 break;
2206 }
2207 if (status != OK) {
Steve Block3762c312012-01-06 19:20:56 +00002208 ALOGE("channel '%s' ~ Could not append motion sample "
Jeff Browna032cc02011-03-07 16:56:21 -08002209 "for a reason other than out of memory, status=%d",
2210 connection->getInputChannelName(), status);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002211 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
Jeff Browna032cc02011-03-07 16:56:21 -08002212 return;
2213 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002214 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002215
Jeff Browna032cc02011-03-07 16:56:21 -08002216 // Remember the next motion sample that we could not dispatch, in case we ran out
2217 // of space in the shared memory buffer.
2218 dispatchEntry->tailMotionSample = nextMotionSample;
2219 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002220 break;
2221 }
2222
2223 default: {
Steve Blockec193de2012-01-09 18:35:44 +00002224 ALOG_ASSERT(false);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002225 }
2226 }
2227
2228 // Send the dispatch signal.
2229 status = connection->inputPublisher.sendDispatchSignal();
2230 if (status) {
Steve Block3762c312012-01-06 19:20:56 +00002231 ALOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
Jeff Brown46b9ac02010-04-22 18:58:52 -07002232 connection->getInputChannelName(), status);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002233 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002234 return;
2235 }
2236
2237 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07002238 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002239 connection->lastDispatchTime = currentTime;
2240
Jeff Brown46b9ac02010-04-22 18:58:52 -07002241 // Notify other system components.
2242 onDispatchCycleStartedLocked(currentTime, connection);
2243}
2244
Jeff Brown7fbdc842010-06-17 20:52:56 -07002245void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown3915bb82010-11-05 15:02:16 -07002246 const sp<Connection>& connection, bool handled) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002247#if DEBUG_DISPATCH_CYCLE
Steve Block5baa3a62011-12-20 16:23:08 +00002248 ALOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown3915bb82010-11-05 15:02:16 -07002249 "%01.1fms since dispatch, handled=%s",
Jeff Brown46b9ac02010-04-22 18:58:52 -07002250 connection->getInputChannelName(),
2251 connection->getEventLatencyMillis(currentTime),
Jeff Brown3915bb82010-11-05 15:02:16 -07002252 connection->getDispatchLatencyMillis(currentTime),
2253 toString(handled));
Jeff Brown46b9ac02010-04-22 18:58:52 -07002254#endif
2255
Jeff Brown9c3cda02010-06-15 01:31:58 -07002256 if (connection->status == Connection::STATUS_BROKEN
2257 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002258 return;
2259 }
2260
Jeff Brown46b9ac02010-04-22 18:58:52 -07002261 // Reset the publisher since the event has been consumed.
2262 // We do this now so that the publisher can release some of its internal resources
2263 // while waiting for the next dispatch cycle to begin.
2264 status_t status = connection->inputPublisher.reset();
2265 if (status) {
Steve Block3762c312012-01-06 19:20:56 +00002266 ALOGE("channel '%s' ~ Could not reset publisher, status=%d",
Jeff Brown46b9ac02010-04-22 18:58:52 -07002267 connection->getInputChannelName(), status);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002268 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002269 return;
2270 }
2271
Jeff Brown3915bb82010-11-05 15:02:16 -07002272 // Notify other system components and prepare to start the next dispatch cycle.
2273 onDispatchCycleFinishedLocked(currentTime, connection, handled);
Jeff Brownb88102f2010-09-08 11:49:43 -07002274}
2275
2276void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
2277 const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002278 // Start the next dispatch cycle for this connection.
2279 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownac386072011-07-20 15:19:50 -07002280 DispatchEntry* dispatchEntry = connection->outboundQueue.head;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002281 if (dispatchEntry->inProgress) {
2282 // Finish or resume current event in progress.
2283 if (dispatchEntry->tailMotionSample) {
2284 // We have a tail of undispatched motion samples.
2285 // Reuse the same DispatchEntry and start a new cycle.
2286 dispatchEntry->inProgress = false;
2287 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
2288 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07002289 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002290 return;
2291 }
2292 // Finished.
2293 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07002294 if (dispatchEntry->hasForegroundTarget()) {
2295 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002296 }
Jeff Brownac386072011-07-20 15:19:50 -07002297 delete dispatchEntry;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002298 } else {
2299 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07002300 // progress event, which means we actually aborted it.
Jeff Brown46b9ac02010-04-22 18:58:52 -07002301 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07002302 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002303 return;
2304 }
2305 }
2306
2307 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002308 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac02010-04-22 18:58:52 -07002309}
2310
Jeff Brownb6997262010-10-08 22:31:17 -07002311void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Jeff Browncc4f7db2011-08-30 20:34:48 -07002312 const sp<Connection>& connection, bool notify) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002313#if DEBUG_DISPATCH_CYCLE
Steve Block5baa3a62011-12-20 16:23:08 +00002314 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Jeff Browncc4f7db2011-08-30 20:34:48 -07002315 connection->getInputChannelName(), toString(notify));
Jeff Brown46b9ac02010-04-22 18:58:52 -07002316#endif
2317
Jeff Brownb88102f2010-09-08 11:49:43 -07002318 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002319 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac02010-04-22 18:58:52 -07002320
Jeff Brownb6997262010-10-08 22:31:17 -07002321 // The connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002322 // Ignore already broken or zombie connections.
Jeff Brownb6997262010-10-08 22:31:17 -07002323 if (connection->status == Connection::STATUS_NORMAL) {
2324 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002325
Jeff Browncc4f7db2011-08-30 20:34:48 -07002326 if (notify) {
2327 // Notify other system components.
2328 onDispatchCycleBrokenLocked(currentTime, connection);
2329 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002330 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002331}
2332
Jeff Brown519e0242010-09-15 15:18:56 -07002333void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
2334 while (! connection->outboundQueue.isEmpty()) {
2335 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
2336 if (dispatchEntry->hasForegroundTarget()) {
2337 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07002338 }
Jeff Brownac386072011-07-20 15:19:50 -07002339 delete dispatchEntry;
Jeff Brownb88102f2010-09-08 11:49:43 -07002340 }
2341
Jeff Brown519e0242010-09-15 15:18:56 -07002342 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07002343}
2344
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002345int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002346 InputDispatcher* d = static_cast<InputDispatcher*>(data);
2347
2348 { // acquire lock
2349 AutoMutex _l(d->mLock);
2350
2351 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
2352 if (connectionIndex < 0) {
Steve Block3762c312012-01-06 19:20:56 +00002353 ALOGE("Received spurious receive callback for unknown input channel. "
Jeff Brown46b9ac02010-04-22 18:58:52 -07002354 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002355 return 0; // remove the callback
Jeff Brown46b9ac02010-04-22 18:58:52 -07002356 }
2357
Jeff Browncc4f7db2011-08-30 20:34:48 -07002358 bool notify;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002359 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002360 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2361 if (!(events & ALOOPER_EVENT_INPUT)) {
Steve Block8564c8d2012-01-05 23:22:43 +00002362 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Jeff Browncc4f7db2011-08-30 20:34:48 -07002363 "events=0x%x", connection->getInputChannelName(), events);
2364 return 1;
2365 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002366
Jeff Browncc4f7db2011-08-30 20:34:48 -07002367 bool handled = false;
2368 status_t status = connection->inputPublisher.receiveFinishedSignal(&handled);
2369 if (!status) {
2370 nsecs_t currentTime = now();
2371 d->finishDispatchCycleLocked(currentTime, connection, handled);
2372 d->runCommandsLockedInterruptible();
2373 return 1;
2374 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002375
Steve Block3762c312012-01-06 19:20:56 +00002376 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Jeff Brown46b9ac02010-04-22 18:58:52 -07002377 connection->getInputChannelName(), status);
Jeff Browncc4f7db2011-08-30 20:34:48 -07002378 notify = true;
2379 } else {
2380 // Monitor channels are never explicitly unregistered.
2381 // We do it automatically when the remote endpoint is closed so don't warn
2382 // about them.
2383 notify = !connection->monitor;
2384 if (notify) {
Steve Block8564c8d2012-01-05 23:22:43 +00002385 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Jeff Browncc4f7db2011-08-30 20:34:48 -07002386 "events=0x%x", connection->getInputChannelName(), events);
2387 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002388 }
2389
Jeff Browncc4f7db2011-08-30 20:34:48 -07002390 // Unregister the channel.
2391 d->unregisterInputChannelLocked(connection->inputChannel, notify);
2392 return 0; // remove the callback
Jeff Brown46b9ac02010-04-22 18:58:52 -07002393 } // release lock
2394}
2395
Jeff Brownb6997262010-10-08 22:31:17 -07002396void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Jeff Brownda3d5a92011-03-29 15:11:34 -07002397 const CancelationOptions& options) {
Jeff Brownb6997262010-10-08 22:31:17 -07002398 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
2399 synthesizeCancelationEventsForConnectionLocked(
Jeff Brownda3d5a92011-03-29 15:11:34 -07002400 mConnectionsByReceiveFd.valueAt(i), options);
Jeff Brownb6997262010-10-08 22:31:17 -07002401 }
2402}
2403
2404void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Jeff Brownda3d5a92011-03-29 15:11:34 -07002405 const sp<InputChannel>& channel, const CancelationOptions& options) {
Jeff Brownb6997262010-10-08 22:31:17 -07002406 ssize_t index = getConnectionIndexLocked(channel);
2407 if (index >= 0) {
2408 synthesizeCancelationEventsForConnectionLocked(
Jeff Brownda3d5a92011-03-29 15:11:34 -07002409 mConnectionsByReceiveFd.valueAt(index), options);
Jeff Brownb6997262010-10-08 22:31:17 -07002410 }
2411}
2412
2413void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
Jeff Brownda3d5a92011-03-29 15:11:34 -07002414 const sp<Connection>& connection, const CancelationOptions& options) {
Jeff Brownc0cb3dc2012-01-12 18:30:12 -08002415 if (connection->status == Connection::STATUS_BROKEN) {
2416 return;
2417 }
2418
Jeff Brownb6997262010-10-08 22:31:17 -07002419 nsecs_t currentTime = now();
2420
2421 mTempCancelationEvents.clear();
Jeff Brownac386072011-07-20 15:19:50 -07002422 connection->inputState.synthesizeCancelationEvents(currentTime,
Jeff Brownb6997262010-10-08 22:31:17 -07002423 mTempCancelationEvents, options);
2424
Jeff Brownc0cb3dc2012-01-12 18:30:12 -08002425 if (!mTempCancelationEvents.isEmpty()) {
Jeff Brownb6997262010-10-08 22:31:17 -07002426#if DEBUG_OUTBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00002427 ALOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
Jeff Brownda3d5a92011-03-29 15:11:34 -07002428 "with reality: %s, mode=%d.",
2429 connection->getInputChannelName(), mTempCancelationEvents.size(),
2430 options.reason, options.mode);
Jeff Brownb6997262010-10-08 22:31:17 -07002431#endif
2432 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
2433 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
2434 switch (cancelationEventEntry->type) {
2435 case EventEntry::TYPE_KEY:
2436 logOutboundKeyDetailsLocked("cancel - ",
2437 static_cast<KeyEntry*>(cancelationEventEntry));
2438 break;
2439 case EventEntry::TYPE_MOTION:
2440 logOutboundMotionDetailsLocked("cancel - ",
2441 static_cast<MotionEntry*>(cancelationEventEntry));
2442 break;
2443 }
2444
Jeff Brown81346812011-06-28 20:08:48 -07002445 InputTarget target;
Jeff Brown9302c872011-07-13 22:51:29 -07002446 sp<InputWindowHandle> windowHandle = getWindowHandleLocked(connection->inputChannel);
2447 if (windowHandle != NULL) {
Jeff Browncc4f7db2011-08-30 20:34:48 -07002448 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2449 target.xOffset = -windowInfo->frameLeft;
2450 target.yOffset = -windowInfo->frameTop;
2451 target.scaleFactor = windowInfo->scaleFactor;
Jeff Brownb6997262010-10-08 22:31:17 -07002452 } else {
Jeff Brown81346812011-06-28 20:08:48 -07002453 target.xOffset = 0;
2454 target.yOffset = 0;
2455 target.scaleFactor = 1.0f;
Jeff Brownb6997262010-10-08 22:31:17 -07002456 }
Jeff Brown81346812011-06-28 20:08:48 -07002457 target.inputChannel = connection->inputChannel;
2458 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Jeff Brownb6997262010-10-08 22:31:17 -07002459
Jeff Brown81346812011-06-28 20:08:48 -07002460 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
2461 &target, false, InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownb6997262010-10-08 22:31:17 -07002462
Jeff Brownac386072011-07-20 15:19:50 -07002463 cancelationEventEntry->release();
Jeff Brownb6997262010-10-08 22:31:17 -07002464 }
2465
Jeff Brownac386072011-07-20 15:19:50 -07002466 if (!connection->outboundQueue.head->inProgress) {
Jeff Brownb6997262010-10-08 22:31:17 -07002467 startDispatchCycleLocked(currentTime, connection);
2468 }
2469 }
2470}
2471
Jeff Brown01ce2e92010-09-26 22:20:12 -07002472InputDispatcher::MotionEntry*
2473InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
Steve Blockec193de2012-01-09 18:35:44 +00002474 ALOG_ASSERT(pointerIds.value != 0);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002475
2476 uint32_t splitPointerIndexMap[MAX_POINTERS];
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07002477 PointerProperties splitPointerProperties[MAX_POINTERS];
Jeff Brown01ce2e92010-09-26 22:20:12 -07002478 PointerCoords splitPointerCoords[MAX_POINTERS];
2479
2480 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2481 uint32_t splitPointerCount = 0;
2482
2483 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2484 originalPointerIndex++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07002485 const PointerProperties& pointerProperties =
2486 originalMotionEntry->pointerProperties[originalPointerIndex];
2487 uint32_t pointerId = uint32_t(pointerProperties.id);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002488 if (pointerIds.hasBit(pointerId)) {
2489 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07002490 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
Jeff Brownace13b12011-03-09 17:39:48 -08002491 splitPointerCoords[splitPointerCount].copyFrom(
2492 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex]);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002493 splitPointerCount += 1;
2494 }
2495 }
Jeff Brown58a2da82011-01-25 16:02:22 -08002496
2497 if (splitPointerCount != pointerIds.count()) {
2498 // This is bad. We are missing some of the pointers that we expected to deliver.
2499 // Most likely this indicates that we received an ACTION_MOVE events that has
2500 // different pointer ids than we expected based on the previous ACTION_DOWN
2501 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2502 // in this way.
Steve Block8564c8d2012-01-05 23:22:43 +00002503 ALOGW("Dropping split motion event because the pointer count is %d but "
Jeff Brown58a2da82011-01-25 16:02:22 -08002504 "we expected there to be %d pointers. This probably means we received "
2505 "a broken sequence of pointer ids from the input device.",
2506 splitPointerCount, pointerIds.count());
2507 return NULL;
2508 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002509
2510 int32_t action = originalMotionEntry->action;
2511 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2512 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2513 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2514 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07002515 const PointerProperties& pointerProperties =
2516 originalMotionEntry->pointerProperties[originalPointerIndex];
2517 uint32_t pointerId = uint32_t(pointerProperties.id);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002518 if (pointerIds.hasBit(pointerId)) {
2519 if (pointerIds.count() == 1) {
2520 // The first/last pointer went down/up.
2521 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2522 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07002523 } else {
2524 // A secondary pointer went down/up.
2525 uint32_t splitPointerIndex = 0;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07002526 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
Jeff Brown9a01d052010-09-27 16:35:11 -07002527 splitPointerIndex += 1;
2528 }
2529 action = maskedAction | (splitPointerIndex
2530 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002531 }
2532 } else {
2533 // An unrelated pointer changed.
2534 action = AMOTION_EVENT_ACTION_MOVE;
2535 }
2536 }
2537
Jeff Brownac386072011-07-20 15:19:50 -07002538 MotionEntry* splitMotionEntry = new MotionEntry(
Jeff Brown01ce2e92010-09-26 22:20:12 -07002539 originalMotionEntry->eventTime,
2540 originalMotionEntry->deviceId,
2541 originalMotionEntry->source,
2542 originalMotionEntry->policyFlags,
2543 action,
2544 originalMotionEntry->flags,
2545 originalMotionEntry->metaState,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07002546 originalMotionEntry->buttonState,
Jeff Brown01ce2e92010-09-26 22:20:12 -07002547 originalMotionEntry->edgeFlags,
2548 originalMotionEntry->xPrecision,
2549 originalMotionEntry->yPrecision,
2550 originalMotionEntry->downTime,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07002551 splitPointerCount, splitPointerProperties, splitPointerCoords);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002552
2553 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2554 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2555 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2556 splitPointerIndex++) {
2557 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
Jeff Brownace13b12011-03-09 17:39:48 -08002558 splitPointerCoords[splitPointerIndex].copyFrom(
2559 originalMotionSample->pointerCoords[originalPointerIndex]);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002560 }
2561
Jeff Brownac386072011-07-20 15:19:50 -07002562 splitMotionEntry->appendSample(originalMotionSample->eventTime, splitPointerCoords);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002563 }
2564
Jeff Browna032cc02011-03-07 16:56:21 -08002565 if (originalMotionEntry->injectionState) {
2566 splitMotionEntry->injectionState = originalMotionEntry->injectionState;
2567 splitMotionEntry->injectionState->refCount += 1;
2568 }
2569
Jeff Brown01ce2e92010-09-26 22:20:12 -07002570 return splitMotionEntry;
2571}
2572
Jeff Brownbe1aa822011-07-27 16:04:54 -07002573void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002574#if DEBUG_INBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00002575 ALOGD("notifyConfigurationChanged - eventTime=%lld", args->eventTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002576#endif
2577
Jeff Brownb88102f2010-09-08 11:49:43 -07002578 bool needWake;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002579 { // acquire lock
2580 AutoMutex _l(mLock);
2581
Jeff Brownbe1aa822011-07-27 16:04:54 -07002582 ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(args->eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07002583 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002584 } // release lock
2585
Jeff Brownb88102f2010-09-08 11:49:43 -07002586 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002587 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002588 }
2589}
2590
Jeff Brownbe1aa822011-07-27 16:04:54 -07002591void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002592#if DEBUG_INBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00002593 ALOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac02010-04-22 18:58:52 -07002594 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownbe1aa822011-07-27 16:04:54 -07002595 args->eventTime, args->deviceId, args->source, args->policyFlags,
2596 args->action, args->flags, args->keyCode, args->scanCode,
2597 args->metaState, args->downTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002598#endif
Jeff Brownbe1aa822011-07-27 16:04:54 -07002599 if (!validateKeyEvent(args->action)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002600 return;
2601 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002602
Jeff Brownbe1aa822011-07-27 16:04:54 -07002603 uint32_t policyFlags = args->policyFlags;
2604 int32_t flags = args->flags;
2605 int32_t metaState = args->metaState;
Jeff Brown1f245102010-11-18 20:53:46 -08002606 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2607 policyFlags |= POLICY_FLAG_VIRTUAL;
2608 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2609 }
Jeff Brown924c4d42011-03-07 16:40:47 -08002610 if (policyFlags & POLICY_FLAG_ALT) {
2611 metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON;
2612 }
2613 if (policyFlags & POLICY_FLAG_ALT_GR) {
2614 metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON;
2615 }
2616 if (policyFlags & POLICY_FLAG_SHIFT) {
2617 metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON;
2618 }
2619 if (policyFlags & POLICY_FLAG_CAPS_LOCK) {
2620 metaState |= AMETA_CAPS_LOCK_ON;
2621 }
2622 if (policyFlags & POLICY_FLAG_FUNCTION) {
2623 metaState |= AMETA_FUNCTION_ON;
2624 }
Jeff Brown1f245102010-11-18 20:53:46 -08002625
Jeff Browne20c9e02010-10-11 14:20:19 -07002626 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown1f245102010-11-18 20:53:46 -08002627
2628 KeyEvent event;
Jeff Brownbe1aa822011-07-27 16:04:54 -07002629 event.initialize(args->deviceId, args->source, args->action,
2630 flags, args->keyCode, args->scanCode, metaState, 0,
2631 args->downTime, args->eventTime);
Jeff Brown1f245102010-11-18 20:53:46 -08002632
2633 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
2634
2635 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2636 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2637 }
Jeff Brownb6997262010-10-08 22:31:17 -07002638
Jeff Brownb88102f2010-09-08 11:49:43 -07002639 bool needWake;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002640 { // acquire lock
Jeff Brown0029c662011-03-30 02:25:18 -07002641 mLock.lock();
2642
2643 if (mInputFilterEnabled) {
2644 mLock.unlock();
2645
2646 policyFlags |= POLICY_FLAG_FILTERED;
2647 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2648 return; // event was consumed by the filter
2649 }
2650
2651 mLock.lock();
2652 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002653
Jeff Brown7fbdc842010-06-17 20:52:56 -07002654 int32_t repeatCount = 0;
Jeff Brownbe1aa822011-07-27 16:04:54 -07002655 KeyEntry* newEntry = new KeyEntry(args->eventTime,
2656 args->deviceId, args->source, policyFlags,
2657 args->action, flags, args->keyCode, args->scanCode,
2658 metaState, repeatCount, args->downTime);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002659
Jeff Brownb88102f2010-09-08 11:49:43 -07002660 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown0029c662011-03-30 02:25:18 -07002661 mLock.unlock();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002662 } // release lock
2663
Jeff Brownb88102f2010-09-08 11:49:43 -07002664 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002665 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002666 }
2667}
2668
Jeff Brownbe1aa822011-07-27 16:04:54 -07002669void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002670#if DEBUG_INBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00002671 ALOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07002672 "action=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, edgeFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002673 "xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownbe1aa822011-07-27 16:04:54 -07002674 args->eventTime, args->deviceId, args->source, args->policyFlags,
2675 args->action, args->flags, args->metaState, args->buttonState,
2676 args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
2677 for (uint32_t i = 0; i < args->pointerCount; i++) {
Steve Block5baa3a62011-12-20 16:23:08 +00002678 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07002679 "x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002680 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002681 "orientation=%f",
Jeff Brownbe1aa822011-07-27 16:04:54 -07002682 i, args->pointerProperties[i].id,
2683 args->pointerProperties[i].toolType,
2684 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2685 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2686 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2687 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2688 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2689 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2690 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2691 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2692 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Jeff Brown46b9ac02010-04-22 18:58:52 -07002693 }
2694#endif
Jeff Brownbe1aa822011-07-27 16:04:54 -07002695 if (!validateMotionEvent(args->action, args->pointerCount, args->pointerProperties)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002696 return;
2697 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002698
Jeff Brownbe1aa822011-07-27 16:04:54 -07002699 uint32_t policyFlags = args->policyFlags;
Jeff Browne20c9e02010-10-11 14:20:19 -07002700 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownbe1aa822011-07-27 16:04:54 -07002701 mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002702
Jeff Brownb88102f2010-09-08 11:49:43 -07002703 bool needWake;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002704 { // acquire lock
Jeff Brown0029c662011-03-30 02:25:18 -07002705 mLock.lock();
2706
2707 if (mInputFilterEnabled) {
2708 mLock.unlock();
2709
2710 MotionEvent event;
Jeff Brownbe1aa822011-07-27 16:04:54 -07002711 event.initialize(args->deviceId, args->source, args->action, args->flags,
2712 args->edgeFlags, args->metaState, args->buttonState, 0, 0,
2713 args->xPrecision, args->yPrecision,
2714 args->downTime, args->eventTime,
2715 args->pointerCount, args->pointerProperties, args->pointerCoords);
Jeff Brown0029c662011-03-30 02:25:18 -07002716
2717 policyFlags |= POLICY_FLAG_FILTERED;
2718 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2719 return; // event was consumed by the filter
2720 }
2721
2722 mLock.lock();
2723 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07002724
2725 // Attempt batching and streaming of move events.
Jeff Brownbe1aa822011-07-27 16:04:54 -07002726 if (args->action == AMOTION_EVENT_ACTION_MOVE
2727 || args->action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002728 // BATCHING CASE
2729 //
2730 // Try to append a move sample to the tail of the inbound queue for this device.
2731 // Give up if we encounter a non-move motion event for this device since that
2732 // means we cannot append any new samples until a new motion event has started.
Jeff Brownac386072011-07-20 15:19:50 -07002733 for (EventEntry* entry = mInboundQueue.tail; entry; entry = entry->prev) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07002734 if (entry->type != EventEntry::TYPE_MOTION) {
2735 // Keep looking for motion events.
2736 continue;
2737 }
2738
2739 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
Jeff Brownbe1aa822011-07-27 16:04:54 -07002740 if (motionEntry->deviceId != args->deviceId
2741 || motionEntry->source != args->source) {
Jeff Brownefd32662011-03-08 15:13:06 -08002742 // Keep looking for this device and source.
Jeff Brown46b9ac02010-04-22 18:58:52 -07002743 continue;
2744 }
2745
Jeff Brownbe1aa822011-07-27 16:04:54 -07002746 if (!motionEntry->canAppendSamples(args->action,
2747 args->pointerCount, args->pointerProperties)) {
Jeff Brownefd32662011-03-08 15:13:06 -08002748 // Last motion event in the queue for this device and source is
2749 // not compatible for appending new samples. Stop here.
Jeff Brown46b9ac02010-04-22 18:58:52 -07002750 goto NoBatchingOrStreaming;
2751 }
2752
Jeff Brown9c3cda02010-06-15 01:31:58 -07002753 // Do the batching magic.
Jeff Brownbe1aa822011-07-27 16:04:54 -07002754 batchMotionLocked(motionEntry, args->eventTime,
2755 args->metaState, args->pointerCoords,
Jeff Brown4e91a182011-04-07 11:38:09 -07002756 "most recent motion event for this device and source in the inbound queue");
Jeff Brown0029c662011-03-30 02:25:18 -07002757 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002758 return; // done!
Jeff Brown46b9ac02010-04-22 18:58:52 -07002759 }
2760
Jeff Brownf6989da2011-04-06 17:19:48 -07002761 // BATCHING ONTO PENDING EVENT CASE
2762 //
2763 // Try to append a move sample to the currently pending event, if there is one.
2764 // We can do this as long as we are still waiting to find the targets for the
2765 // event. Once the targets are locked-in we can only do streaming.
2766 if (mPendingEvent
2767 && (!mPendingEvent->dispatchInProgress || !mCurrentInputTargetsValid)
2768 && mPendingEvent->type == EventEntry::TYPE_MOTION) {
2769 MotionEntry* motionEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brownbe1aa822011-07-27 16:04:54 -07002770 if (motionEntry->deviceId == args->deviceId
2771 && motionEntry->source == args->source) {
2772 if (!motionEntry->canAppendSamples(args->action,
2773 args->pointerCount, args->pointerProperties)) {
Jeff Brown4e91a182011-04-07 11:38:09 -07002774 // Pending motion event is for this device and source but it is
2775 // not compatible for appending new samples. Stop here.
Jeff Brownf6989da2011-04-06 17:19:48 -07002776 goto NoBatchingOrStreaming;
2777 }
2778
Jeff Brownf6989da2011-04-06 17:19:48 -07002779 // Do the batching magic.
Jeff Brownbe1aa822011-07-27 16:04:54 -07002780 batchMotionLocked(motionEntry, args->eventTime,
2781 args->metaState, args->pointerCoords,
Jeff Brown4e91a182011-04-07 11:38:09 -07002782 "pending motion event");
Jeff Brownf6989da2011-04-06 17:19:48 -07002783 mLock.unlock();
2784 return; // done!
2785 }
2786 }
2787
Jeff Brown46b9ac02010-04-22 18:58:52 -07002788 // STREAMING CASE
2789 //
2790 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002791 // Search the outbound queue for the current foreground targets to find a dispatched
2792 // motion event that is still in progress. If found, then, appen the new sample to
2793 // that event and push it out to all current targets. The logic in
2794 // prepareDispatchCycleLocked takes care of the case where some targets may
2795 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002796 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002797 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2798 const InputTarget& inputTarget = mCurrentInputTargets[i];
2799 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2800 // Skip non-foreground targets. We only want to stream if there is at
2801 // least one foreground target whose dispatch is still in progress.
2802 continue;
Jeff Brown46b9ac02010-04-22 18:58:52 -07002803 }
Jeff Brown519e0242010-09-15 15:18:56 -07002804
2805 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2806 if (connectionIndex < 0) {
2807 // Connection must no longer be valid.
2808 continue;
2809 }
2810
2811 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2812 if (connection->outboundQueue.isEmpty()) {
2813 // This foreground target has an empty outbound queue.
2814 continue;
2815 }
2816
Jeff Brownac386072011-07-20 15:19:50 -07002817 DispatchEntry* dispatchEntry = connection->outboundQueue.head;
Jeff Brown519e0242010-09-15 15:18:56 -07002818 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002819 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2820 || dispatchEntry->isSplit()) {
2821 // No motion event is being dispatched, or it is being split across
2822 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002823 continue;
2824 }
2825
2826 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2827 dispatchEntry->eventEntry);
Jeff Brownbe1aa822011-07-27 16:04:54 -07002828 if (motionEntry->action != args->action
2829 || motionEntry->deviceId != args->deviceId
2830 || motionEntry->source != args->source
2831 || motionEntry->pointerCount != args->pointerCount
Jeff Brown519e0242010-09-15 15:18:56 -07002832 || motionEntry->isInjected()) {
2833 // The motion event is not compatible with this move.
2834 continue;
2835 }
2836
Jeff Brownbe1aa822011-07-27 16:04:54 -07002837 if (args->action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brown9302c872011-07-13 22:51:29 -07002838 if (mLastHoverWindowHandle == NULL) {
Jeff Browna032cc02011-03-07 16:56:21 -08002839#if DEBUG_BATCHING
Steve Block5baa3a62011-12-20 16:23:08 +00002840 ALOGD("Not streaming hover move because there is no "
Jeff Browna032cc02011-03-07 16:56:21 -08002841 "last hovered window.");
2842#endif
2843 goto NoBatchingOrStreaming;
2844 }
2845
Jeff Brown9302c872011-07-13 22:51:29 -07002846 sp<InputWindowHandle> hoverWindowHandle = findTouchedWindowAtLocked(
Jeff Brownbe1aa822011-07-27 16:04:54 -07002847 args->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X),
2848 args->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Jeff Brown9302c872011-07-13 22:51:29 -07002849 if (mLastHoverWindowHandle != hoverWindowHandle) {
Jeff Browna032cc02011-03-07 16:56:21 -08002850#if DEBUG_BATCHING
Steve Block5baa3a62011-12-20 16:23:08 +00002851 ALOGD("Not streaming hover move because the last hovered window "
Jeff Browna032cc02011-03-07 16:56:21 -08002852 "is '%s' but the currently hovered window is '%s'.",
Jeff Browncc4f7db2011-08-30 20:34:48 -07002853 mLastHoverWindowHandle->getName().string(),
Jeff Brown9302c872011-07-13 22:51:29 -07002854 hoverWindowHandle != NULL
Jeff Browncc4f7db2011-08-30 20:34:48 -07002855 ? hoverWindowHandle->getName().string() : "<null>");
Jeff Browna032cc02011-03-07 16:56:21 -08002856#endif
2857 goto NoBatchingOrStreaming;
2858 }
2859 }
2860
Jeff Brown519e0242010-09-15 15:18:56 -07002861 // Hurray! This foreground target is currently dispatching a move event
2862 // that we can stream onto. Append the motion sample and resume dispatch.
Jeff Brownbe1aa822011-07-27 16:04:54 -07002863 motionEntry->appendSample(args->eventTime, args->pointerCoords);
Jeff Brown519e0242010-09-15 15:18:56 -07002864#if DEBUG_BATCHING
Steve Block5baa3a62011-12-20 16:23:08 +00002865 ALOGD("Appended motion sample onto batch for most recently dispatched "
Jeff Brown4e91a182011-04-07 11:38:09 -07002866 "motion event for this device and source in the outbound queues. "
Jeff Brown519e0242010-09-15 15:18:56 -07002867 "Attempting to stream the motion sample.");
2868#endif
2869 nsecs_t currentTime = now();
2870 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2871 true /*resumeWithAppendedMotionSample*/);
2872
2873 runCommandsLockedInterruptible();
Jeff Brown0029c662011-03-30 02:25:18 -07002874 mLock.unlock();
Jeff Brown519e0242010-09-15 15:18:56 -07002875 return; // done!
Jeff Brown46b9ac02010-04-22 18:58:52 -07002876 }
2877 }
2878
2879NoBatchingOrStreaming:;
2880 }
2881
2882 // Just enqueue a new motion event.
Jeff Brownbe1aa822011-07-27 16:04:54 -07002883 MotionEntry* newEntry = new MotionEntry(args->eventTime,
2884 args->deviceId, args->source, policyFlags,
2885 args->action, args->flags, args->metaState, args->buttonState,
2886 args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
2887 args->pointerCount, args->pointerProperties, args->pointerCoords);
Jeff Brown46b9ac02010-04-22 18:58:52 -07002888
Jeff Brownb88102f2010-09-08 11:49:43 -07002889 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown0029c662011-03-30 02:25:18 -07002890 mLock.unlock();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002891 } // release lock
2892
Jeff Brownb88102f2010-09-08 11:49:43 -07002893 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002894 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07002895 }
2896}
2897
Jeff Brown4e91a182011-04-07 11:38:09 -07002898void InputDispatcher::batchMotionLocked(MotionEntry* entry, nsecs_t eventTime,
2899 int32_t metaState, const PointerCoords* pointerCoords, const char* eventDescription) {
2900 // Combine meta states.
2901 entry->metaState |= metaState;
2902
2903 // Coalesce this sample if not enough time has elapsed since the last sample was
2904 // initially appended to the batch.
2905 MotionSample* lastSample = entry->lastSample;
2906 long interval = eventTime - lastSample->eventTimeBeforeCoalescing;
2907 if (interval <= MOTION_SAMPLE_COALESCE_INTERVAL) {
2908 uint32_t pointerCount = entry->pointerCount;
2909 for (uint32_t i = 0; i < pointerCount; i++) {
2910 lastSample->pointerCoords[i].copyFrom(pointerCoords[i]);
2911 }
2912 lastSample->eventTime = eventTime;
2913#if DEBUG_BATCHING
Steve Block5baa3a62011-12-20 16:23:08 +00002914 ALOGD("Coalesced motion into last sample of batch for %s, events were %0.3f ms apart",
Jeff Brown4e91a182011-04-07 11:38:09 -07002915 eventDescription, interval * 0.000001f);
2916#endif
2917 return;
2918 }
2919
2920 // Append the sample.
Jeff Brownac386072011-07-20 15:19:50 -07002921 entry->appendSample(eventTime, pointerCoords);
Jeff Brown4e91a182011-04-07 11:38:09 -07002922#if DEBUG_BATCHING
Steve Block5baa3a62011-12-20 16:23:08 +00002923 ALOGD("Appended motion sample onto batch for %s, events were %0.3f ms apart",
Jeff Brown4e91a182011-04-07 11:38:09 -07002924 eventDescription, interval * 0.000001f);
2925#endif
2926}
2927
Jeff Brownbe1aa822011-07-27 16:04:54 -07002928void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
Jeff Brownb6997262010-10-08 22:31:17 -07002929#if DEBUG_INBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00002930 ALOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchCode=%d, switchValue=%d",
Jeff Brownbe1aa822011-07-27 16:04:54 -07002931 args->eventTime, args->policyFlags,
2932 args->switchCode, args->switchValue);
Jeff Brownb6997262010-10-08 22:31:17 -07002933#endif
2934
Jeff Brownbe1aa822011-07-27 16:04:54 -07002935 uint32_t policyFlags = args->policyFlags;
Jeff Browne20c9e02010-10-11 14:20:19 -07002936 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownbe1aa822011-07-27 16:04:54 -07002937 mPolicy->notifySwitch(args->eventTime,
2938 args->switchCode, args->switchValue, policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002939}
2940
Jeff Brown65fd2512011-08-18 11:20:58 -07002941void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
2942#if DEBUG_INBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00002943 ALOGD("notifyDeviceReset - eventTime=%lld, deviceId=%d",
Jeff Brown65fd2512011-08-18 11:20:58 -07002944 args->eventTime, args->deviceId);
2945#endif
2946
2947 bool needWake;
2948 { // acquire lock
2949 AutoMutex _l(mLock);
2950
2951 DeviceResetEntry* newEntry = new DeviceResetEntry(args->eventTime, args->deviceId);
2952 needWake = enqueueInboundEventLocked(newEntry);
2953 } // release lock
2954
2955 if (needWake) {
2956 mLooper->wake();
2957 }
2958}
2959
Jeff Brown7fbdc842010-06-17 20:52:56 -07002960int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown0029c662011-03-30 02:25:18 -07002961 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
2962 uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002963#if DEBUG_INBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00002964 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown0029c662011-03-30 02:25:18 -07002965 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
2966 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002967#endif
2968
2969 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Browne20c9e02010-10-11 14:20:19 -07002970
Jeff Brown0029c662011-03-30 02:25:18 -07002971 policyFlags |= POLICY_FLAG_INJECTED;
Jeff Browne20c9e02010-10-11 14:20:19 -07002972 if (hasInjectionPermission(injectorPid, injectorUid)) {
2973 policyFlags |= POLICY_FLAG_TRUSTED;
2974 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002975
Jeff Brownb6997262010-10-08 22:31:17 -07002976 EventEntry* injectedEntry;
2977 switch (event->getType()) {
2978 case AINPUT_EVENT_TYPE_KEY: {
2979 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2980 int32_t action = keyEvent->getAction();
2981 if (! validateKeyEvent(action)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002982 return INPUT_EVENT_INJECTION_FAILED;
2983 }
2984
Jeff Brownb6997262010-10-08 22:31:17 -07002985 int32_t flags = keyEvent->getFlags();
Jeff Brown1f245102010-11-18 20:53:46 -08002986 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2987 policyFlags |= POLICY_FLAG_VIRTUAL;
2988 }
2989
Jeff Brown0029c662011-03-30 02:25:18 -07002990 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2991 mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
2992 }
Jeff Brown1f245102010-11-18 20:53:46 -08002993
2994 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2995 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2996 }
Jeff Brown6ec402b2010-07-28 15:48:59 -07002997
Jeff Brownb6997262010-10-08 22:31:17 -07002998 mLock.lock();
Jeff Brownac386072011-07-20 15:19:50 -07002999 injectedEntry = new KeyEntry(keyEvent->getEventTime(),
Jeff Brown1f245102010-11-18 20:53:46 -08003000 keyEvent->getDeviceId(), keyEvent->getSource(),
3001 policyFlags, action, flags,
3002 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
Jeff Brownb6997262010-10-08 22:31:17 -07003003 keyEvent->getRepeatCount(), keyEvent->getDownTime());
3004 break;
3005 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07003006
Jeff Brownb6997262010-10-08 22:31:17 -07003007 case AINPUT_EVENT_TYPE_MOTION: {
3008 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3009 int32_t action = motionEvent->getAction();
3010 size_t pointerCount = motionEvent->getPointerCount();
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003011 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3012 if (! validateMotionEvent(action, pointerCount, pointerProperties)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003013 return INPUT_EVENT_INJECTION_FAILED;
3014 }
3015
Jeff Brown0029c662011-03-30 02:25:18 -07003016 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3017 nsecs_t eventTime = motionEvent->getEventTime();
3018 mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
3019 }
Jeff Brownb6997262010-10-08 22:31:17 -07003020
3021 mLock.lock();
3022 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3023 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Jeff Brownac386072011-07-20 15:19:50 -07003024 MotionEntry* motionEntry = new MotionEntry(*sampleEventTimes,
Jeff Brownb6997262010-10-08 22:31:17 -07003025 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
3026 action, motionEvent->getFlags(),
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003027 motionEvent->getMetaState(), motionEvent->getButtonState(),
3028 motionEvent->getEdgeFlags(),
Jeff Brownb6997262010-10-08 22:31:17 -07003029 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
3030 motionEvent->getDownTime(), uint32_t(pointerCount),
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003031 pointerProperties, samplePointerCoords);
Jeff Brownb6997262010-10-08 22:31:17 -07003032 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3033 sampleEventTimes += 1;
3034 samplePointerCoords += pointerCount;
Jeff Brownac386072011-07-20 15:19:50 -07003035 motionEntry->appendSample(*sampleEventTimes, samplePointerCoords);
Jeff Brownb6997262010-10-08 22:31:17 -07003036 }
3037 injectedEntry = motionEntry;
3038 break;
3039 }
3040
3041 default:
Steve Block8564c8d2012-01-05 23:22:43 +00003042 ALOGW("Cannot inject event of type %d", event->getType());
Jeff Brownb6997262010-10-08 22:31:17 -07003043 return INPUT_EVENT_INJECTION_FAILED;
3044 }
3045
Jeff Brownac386072011-07-20 15:19:50 -07003046 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Jeff Brownb6997262010-10-08 22:31:17 -07003047 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3048 injectionState->injectionIsAsync = true;
3049 }
3050
3051 injectionState->refCount += 1;
3052 injectedEntry->injectionState = injectionState;
3053
3054 bool needWake = enqueueInboundEventLocked(injectedEntry);
3055 mLock.unlock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07003056
Jeff Brownb88102f2010-09-08 11:49:43 -07003057 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003058 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07003059 }
3060
3061 int32_t injectionResult;
3062 { // acquire lock
3063 AutoMutex _l(mLock);
3064
Jeff Brown6ec402b2010-07-28 15:48:59 -07003065 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3066 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
3067 } else {
3068 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003069 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07003070 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
3071 break;
3072 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07003073
Jeff Brown7fbdc842010-06-17 20:52:56 -07003074 nsecs_t remainingTimeout = endTime - now();
3075 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07003076#if DEBUG_INJECTION
Steve Block5baa3a62011-12-20 16:23:08 +00003077 ALOGD("injectInputEvent - Timed out waiting for injection result "
Jeff Brown6ec402b2010-07-28 15:48:59 -07003078 "to become available.");
3079#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07003080 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3081 break;
3082 }
3083
Jeff Brown6ec402b2010-07-28 15:48:59 -07003084 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
3085 }
3086
3087 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
3088 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003089 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07003090#if DEBUG_INJECTION
Steve Block5baa3a62011-12-20 16:23:08 +00003091 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07003092 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07003093#endif
3094 nsecs_t remainingTimeout = endTime - now();
3095 if (remainingTimeout <= 0) {
3096#if DEBUG_INJECTION
Steve Block5baa3a62011-12-20 16:23:08 +00003097 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07003098 "dispatches to finish.");
3099#endif
3100 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
3101 break;
3102 }
3103
3104 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
3105 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07003106 }
3107 }
3108
Jeff Brownac386072011-07-20 15:19:50 -07003109 injectionState->release();
Jeff Brown7fbdc842010-06-17 20:52:56 -07003110 } // release lock
3111
Jeff Brown6ec402b2010-07-28 15:48:59 -07003112#if DEBUG_INJECTION
Steve Block5baa3a62011-12-20 16:23:08 +00003113 ALOGD("injectInputEvent - Finished with result %d. "
Jeff Brown6ec402b2010-07-28 15:48:59 -07003114 "injectorPid=%d, injectorUid=%d",
3115 injectionResult, injectorPid, injectorUid);
3116#endif
3117
Jeff Brown7fbdc842010-06-17 20:52:56 -07003118 return injectionResult;
3119}
3120
Jeff Brownb6997262010-10-08 22:31:17 -07003121bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
3122 return injectorUid == 0
3123 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
3124}
3125
Jeff Brown7fbdc842010-06-17 20:52:56 -07003126void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003127 InjectionState* injectionState = entry->injectionState;
3128 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003129#if DEBUG_INJECTION
Steve Block5baa3a62011-12-20 16:23:08 +00003130 ALOGD("Setting input event injection result to %d. "
Jeff Brown7fbdc842010-06-17 20:52:56 -07003131 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07003132 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003133#endif
3134
Jeff Brown0029c662011-03-30 02:25:18 -07003135 if (injectionState->injectionIsAsync
3136 && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07003137 // Log the outcome since the injector did not wait for the injection result.
3138 switch (injectionResult) {
3139 case INPUT_EVENT_INJECTION_SUCCEEDED:
Steve Block71f2cf12011-10-20 11:56:00 +01003140 ALOGV("Asynchronous input event injection succeeded.");
Jeff Brown6ec402b2010-07-28 15:48:59 -07003141 break;
3142 case INPUT_EVENT_INJECTION_FAILED:
Steve Block8564c8d2012-01-05 23:22:43 +00003143 ALOGW("Asynchronous input event injection failed.");
Jeff Brown6ec402b2010-07-28 15:48:59 -07003144 break;
3145 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
Steve Block8564c8d2012-01-05 23:22:43 +00003146 ALOGW("Asynchronous input event injection permission denied.");
Jeff Brown6ec402b2010-07-28 15:48:59 -07003147 break;
3148 case INPUT_EVENT_INJECTION_TIMED_OUT:
Steve Block8564c8d2012-01-05 23:22:43 +00003149 ALOGW("Asynchronous input event injection timed out.");
Jeff Brown6ec402b2010-07-28 15:48:59 -07003150 break;
3151 }
3152 }
3153
Jeff Brown01ce2e92010-09-26 22:20:12 -07003154 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003155 mInjectionResultAvailableCondition.broadcast();
3156 }
3157}
3158
Jeff Brown01ce2e92010-09-26 22:20:12 -07003159void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
3160 InjectionState* injectionState = entry->injectionState;
3161 if (injectionState) {
3162 injectionState->pendingForegroundDispatches += 1;
3163 }
3164}
3165
Jeff Brown519e0242010-09-15 15:18:56 -07003166void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003167 InjectionState* injectionState = entry->injectionState;
3168 if (injectionState) {
3169 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07003170
Jeff Brown01ce2e92010-09-26 22:20:12 -07003171 if (injectionState->pendingForegroundDispatches == 0) {
3172 mInjectionSyncFinishedCondition.broadcast();
3173 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003174 }
3175}
3176
Jeff Brown9302c872011-07-13 22:51:29 -07003177sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
3178 const sp<InputChannel>& inputChannel) const {
3179 size_t numWindows = mWindowHandles.size();
3180 for (size_t i = 0; i < numWindows; i++) {
3181 const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
Jeff Browncc4f7db2011-08-30 20:34:48 -07003182 if (windowHandle->getInputChannel() == inputChannel) {
Jeff Brown9302c872011-07-13 22:51:29 -07003183 return windowHandle;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003184 }
3185 }
3186 return NULL;
3187}
3188
Jeff Brown9302c872011-07-13 22:51:29 -07003189bool InputDispatcher::hasWindowHandleLocked(
3190 const sp<InputWindowHandle>& windowHandle) const {
3191 size_t numWindows = mWindowHandles.size();
3192 for (size_t i = 0; i < numWindows; i++) {
3193 if (mWindowHandles.itemAt(i) == windowHandle) {
3194 return true;
3195 }
3196 }
3197 return false;
3198}
3199
3200void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003201#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00003202 ALOGD("setInputWindows");
Jeff Brownb88102f2010-09-08 11:49:43 -07003203#endif
3204 { // acquire lock
3205 AutoMutex _l(mLock);
3206
Jeff Browncc4f7db2011-08-30 20:34:48 -07003207 Vector<sp<InputWindowHandle> > oldWindowHandles = mWindowHandles;
Jeff Brown9302c872011-07-13 22:51:29 -07003208 mWindowHandles = inputWindowHandles;
Jeff Brownb6997262010-10-08 22:31:17 -07003209
Jeff Brown9302c872011-07-13 22:51:29 -07003210 sp<InputWindowHandle> newFocusedWindowHandle;
3211 bool foundHoveredWindow = false;
3212 for (size_t i = 0; i < mWindowHandles.size(); i++) {
3213 const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
Jeff Browncc4f7db2011-08-30 20:34:48 -07003214 if (!windowHandle->updateInfo() || windowHandle->getInputChannel() == NULL) {
Jeff Brown9302c872011-07-13 22:51:29 -07003215 mWindowHandles.removeAt(i--);
3216 continue;
3217 }
Jeff Browncc4f7db2011-08-30 20:34:48 -07003218 if (windowHandle->getInfo()->hasFocus) {
Jeff Brown9302c872011-07-13 22:51:29 -07003219 newFocusedWindowHandle = windowHandle;
3220 }
3221 if (windowHandle == mLastHoverWindowHandle) {
3222 foundHoveredWindow = true;
Jeff Brownb88102f2010-09-08 11:49:43 -07003223 }
3224 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07003225
Jeff Brown9302c872011-07-13 22:51:29 -07003226 if (!foundHoveredWindow) {
3227 mLastHoverWindowHandle = NULL;
3228 }
3229
3230 if (mFocusedWindowHandle != newFocusedWindowHandle) {
3231 if (mFocusedWindowHandle != NULL) {
Jeff Brownb6997262010-10-08 22:31:17 -07003232#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00003233 ALOGD("Focus left window: %s",
Jeff Browncc4f7db2011-08-30 20:34:48 -07003234 mFocusedWindowHandle->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -07003235#endif
Jeff Browncc4f7db2011-08-30 20:34:48 -07003236 sp<InputChannel> focusedInputChannel = mFocusedWindowHandle->getInputChannel();
3237 if (focusedInputChannel != NULL) {
Christopher Tated9be36c2011-08-16 16:09:33 -07003238 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3239 "focus left window");
3240 synthesizeCancelationEventsForInputChannelLocked(
Jeff Browncc4f7db2011-08-30 20:34:48 -07003241 focusedInputChannel, options);
Christopher Tated9be36c2011-08-16 16:09:33 -07003242 }
Jeff Brownb6997262010-10-08 22:31:17 -07003243 }
Jeff Brown9302c872011-07-13 22:51:29 -07003244 if (newFocusedWindowHandle != NULL) {
Jeff Brownb6997262010-10-08 22:31:17 -07003245#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00003246 ALOGD("Focus entered window: %s",
Jeff Browncc4f7db2011-08-30 20:34:48 -07003247 newFocusedWindowHandle->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -07003248#endif
Jeff Brown9302c872011-07-13 22:51:29 -07003249 }
3250 mFocusedWindowHandle = newFocusedWindowHandle;
Jeff Brownb6997262010-10-08 22:31:17 -07003251 }
3252
Jeff Brown9302c872011-07-13 22:51:29 -07003253 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003254 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
Jeff Brown9302c872011-07-13 22:51:29 -07003255 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003256#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00003257 ALOGD("Touched window was removed: %s",
Jeff Browncc4f7db2011-08-30 20:34:48 -07003258 touchedWindow.windowHandle->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -07003259#endif
Jeff Browncc4f7db2011-08-30 20:34:48 -07003260 sp<InputChannel> touchedInputChannel =
3261 touchedWindow.windowHandle->getInputChannel();
3262 if (touchedInputChannel != NULL) {
Christopher Tated9be36c2011-08-16 16:09:33 -07003263 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3264 "touched window was removed");
3265 synthesizeCancelationEventsForInputChannelLocked(
Jeff Browncc4f7db2011-08-30 20:34:48 -07003266 touchedInputChannel, options);
Christopher Tated9be36c2011-08-16 16:09:33 -07003267 }
Jeff Brown9302c872011-07-13 22:51:29 -07003268 mTouchState.windows.removeAt(i--);
Jeff Brown01ce2e92010-09-26 22:20:12 -07003269 }
3270 }
Jeff Browncc4f7db2011-08-30 20:34:48 -07003271
3272 // Release information for windows that are no longer present.
3273 // This ensures that unused input channels are released promptly.
3274 // Otherwise, they might stick around until the window handle is destroyed
3275 // which might not happen until the next GC.
3276 for (size_t i = 0; i < oldWindowHandles.size(); i++) {
3277 const sp<InputWindowHandle>& oldWindowHandle = oldWindowHandles.itemAt(i);
3278 if (!hasWindowHandleLocked(oldWindowHandle)) {
3279#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00003280 ALOGD("Window went away: %s", oldWindowHandle->getName().string());
Jeff Browncc4f7db2011-08-30 20:34:48 -07003281#endif
3282 oldWindowHandle->releaseInfo();
3283 }
3284 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003285 } // release lock
3286
3287 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003288 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07003289}
3290
Jeff Brown9302c872011-07-13 22:51:29 -07003291void InputDispatcher::setFocusedApplication(
3292 const sp<InputApplicationHandle>& inputApplicationHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003293#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00003294 ALOGD("setFocusedApplication");
Jeff Brownb88102f2010-09-08 11:49:43 -07003295#endif
3296 { // acquire lock
3297 AutoMutex _l(mLock);
3298
Jeff Browncc4f7db2011-08-30 20:34:48 -07003299 if (inputApplicationHandle != NULL && inputApplicationHandle->updateInfo()) {
Jeff Brown5ea29ab2011-07-27 11:50:51 -07003300 if (mFocusedApplicationHandle != inputApplicationHandle) {
3301 if (mFocusedApplicationHandle != NULL) {
3302 resetTargetsLocked();
Jeff Browncc4f7db2011-08-30 20:34:48 -07003303 mFocusedApplicationHandle->releaseInfo();
Jeff Brown5ea29ab2011-07-27 11:50:51 -07003304 }
3305 mFocusedApplicationHandle = inputApplicationHandle;
3306 }
3307 } else if (mFocusedApplicationHandle != NULL) {
3308 resetTargetsLocked();
Jeff Browncc4f7db2011-08-30 20:34:48 -07003309 mFocusedApplicationHandle->releaseInfo();
Jeff Brown9302c872011-07-13 22:51:29 -07003310 mFocusedApplicationHandle.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -07003311 }
3312
3313#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07003314 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07003315#endif
3316 } // release lock
3317
3318 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003319 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07003320}
3321
Jeff Brownb88102f2010-09-08 11:49:43 -07003322void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
3323#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00003324 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07003325#endif
3326
3327 bool changed;
3328 { // acquire lock
3329 AutoMutex _l(mLock);
3330
3331 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brown120a4592010-10-27 18:43:51 -07003332 if (mDispatchFrozen && !frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003333 resetANRTimeoutsLocked();
3334 }
3335
Jeff Brown120a4592010-10-27 18:43:51 -07003336 if (mDispatchEnabled && !enabled) {
3337 resetAndDropEverythingLocked("dispatcher is being disabled");
3338 }
3339
Jeff Brownb88102f2010-09-08 11:49:43 -07003340 mDispatchEnabled = enabled;
3341 mDispatchFrozen = frozen;
3342 changed = true;
3343 } else {
3344 changed = false;
3345 }
3346
3347#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07003348 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07003349#endif
3350 } // release lock
3351
3352 if (changed) {
3353 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003354 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07003355 }
3356}
3357
Jeff Brown0029c662011-03-30 02:25:18 -07003358void InputDispatcher::setInputFilterEnabled(bool enabled) {
3359#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00003360 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
Jeff Brown0029c662011-03-30 02:25:18 -07003361#endif
3362
3363 { // acquire lock
3364 AutoMutex _l(mLock);
3365
3366 if (mInputFilterEnabled == enabled) {
3367 return;
3368 }
3369
3370 mInputFilterEnabled = enabled;
3371 resetAndDropEverythingLocked("input filter is being enabled or disabled");
3372 } // release lock
3373
3374 // Wake up poll loop since there might be work to do to drop everything.
3375 mLooper->wake();
3376}
3377
Jeff Browne6504122010-09-27 14:52:15 -07003378bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
3379 const sp<InputChannel>& toChannel) {
3380#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00003381 ALOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
Jeff Browne6504122010-09-27 14:52:15 -07003382 fromChannel->getName().string(), toChannel->getName().string());
3383#endif
3384 { // acquire lock
3385 AutoMutex _l(mLock);
3386
Jeff Brown9302c872011-07-13 22:51:29 -07003387 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromChannel);
3388 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toChannel);
3389 if (fromWindowHandle == NULL || toWindowHandle == NULL) {
Jeff Browne6504122010-09-27 14:52:15 -07003390#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00003391 ALOGD("Cannot transfer focus because from or to window not found.");
Jeff Browne6504122010-09-27 14:52:15 -07003392#endif
3393 return false;
3394 }
Jeff Brown9302c872011-07-13 22:51:29 -07003395 if (fromWindowHandle == toWindowHandle) {
Jeff Browne6504122010-09-27 14:52:15 -07003396#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00003397 ALOGD("Trivial transfer to same window.");
Jeff Browne6504122010-09-27 14:52:15 -07003398#endif
3399 return true;
3400 }
3401
3402 bool found = false;
3403 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
3404 const TouchedWindow& touchedWindow = mTouchState.windows[i];
Jeff Brown9302c872011-07-13 22:51:29 -07003405 if (touchedWindow.windowHandle == fromWindowHandle) {
Jeff Browne6504122010-09-27 14:52:15 -07003406 int32_t oldTargetFlags = touchedWindow.targetFlags;
3407 BitSet32 pointerIds = touchedWindow.pointerIds;
3408
3409 mTouchState.windows.removeAt(i);
3410
Jeff Brown46e75292010-11-10 16:53:45 -08003411 int32_t newTargetFlags = oldTargetFlags
Jeff Browna032cc02011-03-07 16:56:21 -08003412 & (InputTarget::FLAG_FOREGROUND
3413 | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brown9302c872011-07-13 22:51:29 -07003414 mTouchState.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Jeff Browne6504122010-09-27 14:52:15 -07003415
3416 found = true;
3417 break;
3418 }
3419 }
3420
3421 if (! found) {
3422#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00003423 ALOGD("Focus transfer failed because from window did not have focus.");
Jeff Browne6504122010-09-27 14:52:15 -07003424#endif
3425 return false;
3426 }
3427
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003428 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
3429 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
3430 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
3431 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
3432 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
3433
3434 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
Jeff Brownda3d5a92011-03-29 15:11:34 -07003435 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003436 "transferring touch focus from this window to another window");
Jeff Brownda3d5a92011-03-29 15:11:34 -07003437 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003438 }
3439
Jeff Browne6504122010-09-27 14:52:15 -07003440#if DEBUG_FOCUS
3441 logDispatchStateLocked();
3442#endif
3443 } // release lock
3444
3445 // Wake up poll loop since it may need to make new input dispatching choices.
3446 mLooper->wake();
3447 return true;
3448}
3449
Jeff Brown120a4592010-10-27 18:43:51 -07003450void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
3451#if DEBUG_FOCUS
Steve Block5baa3a62011-12-20 16:23:08 +00003452 ALOGD("Resetting and dropping all events (%s).", reason);
Jeff Brown120a4592010-10-27 18:43:51 -07003453#endif
3454
Jeff Brownda3d5a92011-03-29 15:11:34 -07003455 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3456 synthesizeCancelationEventsForAllConnectionsLocked(options);
Jeff Brown120a4592010-10-27 18:43:51 -07003457
3458 resetKeyRepeatLocked();
3459 releasePendingEventLocked();
3460 drainInboundQueueLocked();
3461 resetTargetsLocked();
3462
3463 mTouchState.reset();
Jeff Brown9302c872011-07-13 22:51:29 -07003464 mLastHoverWindowHandle.clear();
Jeff Brown120a4592010-10-27 18:43:51 -07003465}
3466
Jeff Brownb88102f2010-09-08 11:49:43 -07003467void InputDispatcher::logDispatchStateLocked() {
3468 String8 dump;
3469 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07003470
3471 char* text = dump.lockBuffer(dump.size());
3472 char* start = text;
3473 while (*start != '\0') {
3474 char* end = strchr(start, '\n');
3475 if (*end == '\n') {
3476 *(end++) = '\0';
3477 }
Steve Block5baa3a62011-12-20 16:23:08 +00003478 ALOGD("%s", start);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07003479 start = end;
3480 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003481}
3482
3483void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003484 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
3485 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07003486
Jeff Brown9302c872011-07-13 22:51:29 -07003487 if (mFocusedApplicationHandle != NULL) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003488 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Browncc4f7db2011-08-30 20:34:48 -07003489 mFocusedApplicationHandle->getName().string(),
3490 mFocusedApplicationHandle->getDispatchingTimeout(
3491 DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07003492 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07003493 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003494 }
Jeff Brownf2f487182010-10-01 17:46:21 -07003495 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Browncc4f7db2011-08-30 20:34:48 -07003496 mFocusedWindowHandle != NULL ? mFocusedWindowHandle->getName().string() : "<null>");
Jeff Brownf2f487182010-10-01 17:46:21 -07003497
3498 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
3499 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
Jeff Brown95712852011-01-04 19:41:59 -08003500 dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
Jeff Brown58a2da82011-01-25 16:02:22 -08003501 dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
Jeff Brownf2f487182010-10-01 17:46:21 -07003502 if (!mTouchState.windows.isEmpty()) {
3503 dump.append(INDENT "TouchedWindows:\n");
3504 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
3505 const TouchedWindow& touchedWindow = mTouchState.windows[i];
3506 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
Jeff Browncc4f7db2011-08-30 20:34:48 -07003507 i, touchedWindow.windowHandle->getName().string(),
3508 touchedWindow.pointerIds.value,
Jeff Brownf2f487182010-10-01 17:46:21 -07003509 touchedWindow.targetFlags);
3510 }
3511 } else {
3512 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003513 }
3514
Jeff Brown9302c872011-07-13 22:51:29 -07003515 if (!mWindowHandles.isEmpty()) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003516 dump.append(INDENT "Windows:\n");
Jeff Brown9302c872011-07-13 22:51:29 -07003517 for (size_t i = 0; i < mWindowHandles.size(); i++) {
3518 const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
Jeff Browncc4f7db2011-08-30 20:34:48 -07003519 const InputWindowInfo* windowInfo = windowHandle->getInfo();
3520
Jeff Brownf2f487182010-10-01 17:46:21 -07003521 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
3522 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003523 "frame=[%d,%d][%d,%d], scale=%f, "
Jeff Brownfbf09772011-01-16 14:06:57 -08003524 "touchableRegion=",
Jeff Browncc4f7db2011-08-30 20:34:48 -07003525 i, windowInfo->name.string(),
3526 toString(windowInfo->paused),
3527 toString(windowInfo->hasFocus),
3528 toString(windowInfo->hasWallpaper),
3529 toString(windowInfo->visible),
3530 toString(windowInfo->canReceiveKeys),
3531 windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
3532 windowInfo->layer,
3533 windowInfo->frameLeft, windowInfo->frameTop,
3534 windowInfo->frameRight, windowInfo->frameBottom,
3535 windowInfo->scaleFactor);
3536 dumpRegion(dump, windowInfo->touchableRegion);
3537 dump.appendFormat(", inputFeatures=0x%08x", windowInfo->inputFeatures);
Jeff Brownfbf09772011-01-16 14:06:57 -08003538 dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Jeff Browncc4f7db2011-08-30 20:34:48 -07003539 windowInfo->ownerPid, windowInfo->ownerUid,
3540 windowInfo->dispatchingTimeout / 1000000.0);
Jeff Brownf2f487182010-10-01 17:46:21 -07003541 }
3542 } else {
3543 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003544 }
3545
Jeff Brownf2f487182010-10-01 17:46:21 -07003546 if (!mMonitoringChannels.isEmpty()) {
3547 dump.append(INDENT "MonitoringChannels:\n");
3548 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3549 const sp<InputChannel>& channel = mMonitoringChannels[i];
3550 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
3551 }
3552 } else {
3553 dump.append(INDENT "MonitoringChannels: <none>\n");
3554 }
Jeff Brown519e0242010-09-15 15:18:56 -07003555
Jeff Brownf2f487182010-10-01 17:46:21 -07003556 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
3557
3558 if (!mActiveConnections.isEmpty()) {
3559 dump.append(INDENT "ActiveConnections:\n");
3560 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3561 const Connection* connection = mActiveConnections[i];
Jeff Brown76860e32010-10-25 17:37:46 -07003562 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brownb6997262010-10-08 22:31:17 -07003563 "inputState.isNeutral=%s\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07003564 i, connection->getInputChannelName(), connection->getStatusLabel(),
3565 connection->outboundQueue.count(),
Jeff Brownb6997262010-10-08 22:31:17 -07003566 toString(connection->inputState.isNeutral()));
Jeff Brownf2f487182010-10-01 17:46:21 -07003567 }
3568 } else {
3569 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003570 }
3571
3572 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003573 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07003574 (mAppSwitchDueTime - now()) / 1000000.0);
3575 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07003576 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003577 }
3578}
3579
Jeff Brown928e0542011-01-10 11:17:36 -08003580status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
3581 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003582#if DEBUG_REGISTRATION
Steve Block5baa3a62011-12-20 16:23:08 +00003583 ALOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
Jeff Brownb88102f2010-09-08 11:49:43 -07003584 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07003585#endif
3586
Jeff Brown46b9ac02010-04-22 18:58:52 -07003587 { // acquire lock
3588 AutoMutex _l(mLock);
3589
Jeff Brown519e0242010-09-15 15:18:56 -07003590 if (getConnectionIndexLocked(inputChannel) >= 0) {
Steve Block8564c8d2012-01-05 23:22:43 +00003591 ALOGW("Attempted to register already registered input channel '%s'",
Jeff Brown46b9ac02010-04-22 18:58:52 -07003592 inputChannel->getName().string());
3593 return BAD_VALUE;
3594 }
3595
Jeff Browncc4f7db2011-08-30 20:34:48 -07003596 sp<Connection> connection = new Connection(inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07003597 status_t status = connection->initialize();
3598 if (status) {
Steve Block3762c312012-01-06 19:20:56 +00003599 ALOGE("Failed to initialize input publisher for input channel '%s', status=%d",
Jeff Brown46b9ac02010-04-22 18:58:52 -07003600 inputChannel->getName().string(), status);
3601 return status;
3602 }
3603
Jeff Brown2cbecea2010-08-17 15:59:26 -07003604 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac02010-04-22 18:58:52 -07003605 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003606
Jeff Brownb88102f2010-09-08 11:49:43 -07003607 if (monitor) {
3608 mMonitoringChannels.push(inputChannel);
3609 }
3610
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003611 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07003612
Jeff Brown9c3cda02010-06-15 01:31:58 -07003613 runCommandsLockedInterruptible();
Jeff Brown46b9ac02010-04-22 18:58:52 -07003614 } // release lock
Jeff Brown46b9ac02010-04-22 18:58:52 -07003615 return OK;
3616}
3617
3618status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003619#if DEBUG_REGISTRATION
Steve Block5baa3a62011-12-20 16:23:08 +00003620 ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07003621#endif
3622
Jeff Brown46b9ac02010-04-22 18:58:52 -07003623 { // acquire lock
3624 AutoMutex _l(mLock);
3625
Jeff Browncc4f7db2011-08-30 20:34:48 -07003626 status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
3627 if (status) {
3628 return status;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003629 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07003630 } // release lock
3631
Jeff Brown46b9ac02010-04-22 18:58:52 -07003632 // Wake the poll loop because removing the connection may have changed the current
3633 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07003634 mLooper->wake();
Jeff Brown46b9ac02010-04-22 18:58:52 -07003635 return OK;
3636}
3637
Jeff Browncc4f7db2011-08-30 20:34:48 -07003638status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
3639 bool notify) {
3640 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
3641 if (connectionIndex < 0) {
Steve Block8564c8d2012-01-05 23:22:43 +00003642 ALOGW("Attempted to unregister already unregistered input channel '%s'",
Jeff Browncc4f7db2011-08-30 20:34:48 -07003643 inputChannel->getName().string());
3644 return BAD_VALUE;
3645 }
3646
3647 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3648 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
3649
3650 if (connection->monitor) {
3651 removeMonitorChannelLocked(inputChannel);
3652 }
3653
3654 mLooper->removeFd(inputChannel->getReceivePipeFd());
3655
3656 nsecs_t currentTime = now();
3657 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
3658
3659 runCommandsLockedInterruptible();
3660
3661 connection->status = Connection::STATUS_ZOMBIE;
3662 return OK;
3663}
3664
3665void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
3666 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3667 if (mMonitoringChannels[i] == inputChannel) {
3668 mMonitoringChannels.removeAt(i);
3669 break;
3670 }
3671 }
3672}
3673
Jeff Brown519e0242010-09-15 15:18:56 -07003674ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07003675 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
3676 if (connectionIndex >= 0) {
3677 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3678 if (connection->inputChannel.get() == inputChannel.get()) {
3679 return connectionIndex;
3680 }
3681 }
3682
3683 return -1;
3684}
3685
Jeff Brown46b9ac02010-04-22 18:58:52 -07003686void InputDispatcher::activateConnectionLocked(Connection* connection) {
3687 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3688 if (mActiveConnections.itemAt(i) == connection) {
3689 return;
3690 }
3691 }
3692 mActiveConnections.add(connection);
3693}
3694
3695void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
3696 for (size_t i = 0; i < mActiveConnections.size(); i++) {
3697 if (mActiveConnections.itemAt(i) == connection) {
3698 mActiveConnections.removeAt(i);
3699 return;
3700 }
3701 }
3702}
3703
Jeff Brown9c3cda02010-06-15 01:31:58 -07003704void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003705 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07003706}
3707
Jeff Brown9c3cda02010-06-15 01:31:58 -07003708void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown3915bb82010-11-05 15:02:16 -07003709 nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
3710 CommandEntry* commandEntry = postCommandLocked(
3711 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
3712 commandEntry->connection = connection;
3713 commandEntry->handled = handled;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003714}
3715
Jeff Brown9c3cda02010-06-15 01:31:58 -07003716void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07003717 nsecs_t currentTime, const sp<Connection>& connection) {
Steve Block3762c312012-01-06 19:20:56 +00003718 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Jeff Brown46b9ac02010-04-22 18:58:52 -07003719 connection->getInputChannelName());
3720
Jeff Brown9c3cda02010-06-15 01:31:58 -07003721 CommandEntry* commandEntry = postCommandLocked(
3722 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003723 commandEntry->connection = connection;
Jeff Brown46b9ac02010-04-22 18:58:52 -07003724}
3725
Jeff Brown519e0242010-09-15 15:18:56 -07003726void InputDispatcher::onANRLocked(
Jeff Brown9302c872011-07-13 22:51:29 -07003727 nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
3728 const sp<InputWindowHandle>& windowHandle,
Jeff Brown519e0242010-09-15 15:18:56 -07003729 nsecs_t eventTime, nsecs_t waitStartTime) {
Steve Block6215d3f2012-01-04 20:05:49 +00003730 ALOGI("Application is not responding: %s. "
Jeff Brown519e0242010-09-15 15:18:56 -07003731 "%01.1fms since event, %01.1fms since wait started",
Jeff Brown9302c872011-07-13 22:51:29 -07003732 getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
Jeff Brown519e0242010-09-15 15:18:56 -07003733 (currentTime - eventTime) / 1000000.0,
3734 (currentTime - waitStartTime) / 1000000.0);
3735
3736 CommandEntry* commandEntry = postCommandLocked(
3737 & InputDispatcher::doNotifyANRLockedInterruptible);
Jeff Brown9302c872011-07-13 22:51:29 -07003738 commandEntry->inputApplicationHandle = applicationHandle;
3739 commandEntry->inputWindowHandle = windowHandle;
Jeff Brown519e0242010-09-15 15:18:56 -07003740}
3741
Jeff Brownb88102f2010-09-08 11:49:43 -07003742void InputDispatcher::doNotifyConfigurationChangedInterruptible(
3743 CommandEntry* commandEntry) {
3744 mLock.unlock();
3745
3746 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
3747
3748 mLock.lock();
3749}
3750
Jeff Brown9c3cda02010-06-15 01:31:58 -07003751void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
3752 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003753 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07003754
Jeff Brown7fbdc842010-06-17 20:52:56 -07003755 if (connection->status != Connection::STATUS_ZOMBIE) {
3756 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003757
Jeff Brown928e0542011-01-10 11:17:36 -08003758 mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003759
3760 mLock.lock();
3761 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07003762}
3763
Jeff Brown519e0242010-09-15 15:18:56 -07003764void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07003765 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07003766 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003767
Jeff Brown519e0242010-09-15 15:18:56 -07003768 nsecs_t newTimeout = mPolicy->notifyANR(
Jeff Brown928e0542011-01-10 11:17:36 -08003769 commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003770
Jeff Brown519e0242010-09-15 15:18:56 -07003771 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07003772
Jeff Brown9302c872011-07-13 22:51:29 -07003773 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
3774 commandEntry->inputWindowHandle != NULL
Jeff Browncc4f7db2011-08-30 20:34:48 -07003775 ? commandEntry->inputWindowHandle->getInputChannel() : NULL);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003776}
3777
Jeff Brownb88102f2010-09-08 11:49:43 -07003778void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3779 CommandEntry* commandEntry) {
3780 KeyEntry* entry = commandEntry->keyEntry;
Jeff Brown1f245102010-11-18 20:53:46 -08003781
3782 KeyEvent event;
3783 initializeKeyEvent(&event, entry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003784
3785 mLock.unlock();
3786
Jeff Brown905805a2011-10-12 13:57:59 -07003787 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
Jeff Brown1f245102010-11-18 20:53:46 -08003788 &event, entry->policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -07003789
3790 mLock.lock();
3791
Jeff Brown905805a2011-10-12 13:57:59 -07003792 if (delay < 0) {
3793 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
3794 } else if (!delay) {
3795 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3796 } else {
3797 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
3798 entry->interceptKeyWakeupTime = now() + delay;
3799 }
Jeff Brownac386072011-07-20 15:19:50 -07003800 entry->release();
Jeff Brownb88102f2010-09-08 11:49:43 -07003801}
3802
Jeff Brown3915bb82010-11-05 15:02:16 -07003803void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3804 CommandEntry* commandEntry) {
3805 sp<Connection> connection = commandEntry->connection;
3806 bool handled = commandEntry->handled;
3807
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003808 bool skipNext = false;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003809 if (!connection->outboundQueue.isEmpty()) {
Jeff Brownac386072011-07-20 15:19:50 -07003810 DispatchEntry* dispatchEntry = connection->outboundQueue.head;
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003811 if (dispatchEntry->inProgress) {
3812 if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3813 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
3814 skipNext = afterKeyEventLockedInterruptible(connection,
3815 dispatchEntry, keyEntry, handled);
3816 } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
3817 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
3818 skipNext = afterMotionEventLockedInterruptible(connection,
3819 dispatchEntry, motionEntry, handled);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003820 }
Jeff Brown3915bb82010-11-05 15:02:16 -07003821 }
3822 }
3823
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003824 if (!skipNext) {
3825 startNextDispatchCycleLocked(now(), connection);
3826 }
3827}
3828
3829bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
3830 DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
3831 if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
3832 // Get the fallback key state.
3833 // Clear it out after dispatching the UP.
3834 int32_t originalKeyCode = keyEntry->keyCode;
3835 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
3836 if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
3837 connection->inputState.removeFallbackKey(originalKeyCode);
3838 }
3839
3840 if (handled || !dispatchEntry->hasForegroundTarget()) {
3841 // If the application handles the original key for which we previously
3842 // generated a fallback or if the window is not a foreground window,
3843 // then cancel the associated fallback key, if any.
3844 if (fallbackKeyCode != -1) {
3845 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
3846 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
3847 "application handled the original non-fallback key "
3848 "or is no longer a foreground target, "
3849 "canceling previously dispatched fallback key");
3850 options.keyCode = fallbackKeyCode;
3851 synthesizeCancelationEventsForConnectionLocked(connection, options);
3852 }
3853 connection->inputState.removeFallbackKey(originalKeyCode);
3854 }
3855 } else {
3856 // If the application did not handle a non-fallback key, first check
3857 // that we are in a good state to perform unhandled key event processing
3858 // Then ask the policy what to do with it.
3859 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
3860 && keyEntry->repeatCount == 0;
3861 if (fallbackKeyCode == -1 && !initialDown) {
3862#if DEBUG_OUTBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00003863 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003864 "since this is not an initial down. "
3865 "keyCode=%d, action=%d, repeatCount=%d",
3866 originalKeyCode, keyEntry->action, keyEntry->repeatCount);
3867#endif
3868 return false;
3869 }
3870
3871 // Dispatch the unhandled key to the policy.
3872#if DEBUG_OUTBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00003873 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003874 "keyCode=%d, action=%d, repeatCount=%d",
3875 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount);
3876#endif
3877 KeyEvent event;
3878 initializeKeyEvent(&event, keyEntry);
3879
3880 mLock.unlock();
3881
3882 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
3883 &event, keyEntry->policyFlags, &event);
3884
3885 mLock.lock();
3886
3887 if (connection->status != Connection::STATUS_NORMAL) {
3888 connection->inputState.removeFallbackKey(originalKeyCode);
3889 return true; // skip next cycle
3890 }
3891
Steve Blockec193de2012-01-09 18:35:44 +00003892 ALOG_ASSERT(connection->outboundQueue.head == dispatchEntry);
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003893
3894 // Latch the fallback keycode for this key on an initial down.
3895 // The fallback keycode cannot change at any other point in the lifecycle.
3896 if (initialDown) {
3897 if (fallback) {
3898 fallbackKeyCode = event.getKeyCode();
3899 } else {
3900 fallbackKeyCode = AKEYCODE_UNKNOWN;
3901 }
3902 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
3903 }
3904
Steve Blockec193de2012-01-09 18:35:44 +00003905 ALOG_ASSERT(fallbackKeyCode != -1);
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003906
3907 // Cancel the fallback key if the policy decides not to send it anymore.
3908 // We will continue to dispatch the key to the policy but we will no
3909 // longer dispatch a fallback key to the application.
3910 if (fallbackKeyCode != AKEYCODE_UNKNOWN
3911 && (!fallback || fallbackKeyCode != event.getKeyCode())) {
3912#if DEBUG_OUTBOUND_EVENT_DETAILS
3913 if (fallback) {
Steve Block5baa3a62011-12-20 16:23:08 +00003914 ALOGD("Unhandled key event: Policy requested to send key %d"
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003915 "as a fallback for %d, but on the DOWN it had requested "
3916 "to send %d instead. Fallback canceled.",
3917 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
3918 } else {
Steve Block5baa3a62011-12-20 16:23:08 +00003919 ALOGD("Unhandled key event: Policy did not request fallback for %d,"
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003920 "but on the DOWN it had requested to send %d. "
3921 "Fallback canceled.",
3922 originalKeyCode, fallbackKeyCode);
3923 }
3924#endif
3925
3926 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
3927 "canceling fallback, policy no longer desires it");
3928 options.keyCode = fallbackKeyCode;
3929 synthesizeCancelationEventsForConnectionLocked(connection, options);
3930
3931 fallback = false;
3932 fallbackKeyCode = AKEYCODE_UNKNOWN;
3933 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
3934 connection->inputState.setFallbackKey(originalKeyCode,
3935 fallbackKeyCode);
3936 }
3937 }
3938
3939#if DEBUG_OUTBOUND_EVENT_DETAILS
3940 {
3941 String8 msg;
3942 const KeyedVector<int32_t, int32_t>& fallbackKeys =
3943 connection->inputState.getFallbackKeys();
3944 for (size_t i = 0; i < fallbackKeys.size(); i++) {
3945 msg.appendFormat(", %d->%d", fallbackKeys.keyAt(i),
3946 fallbackKeys.valueAt(i));
3947 }
Steve Block5baa3a62011-12-20 16:23:08 +00003948 ALOGD("Unhandled key event: %d currently tracked fallback keys%s.",
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003949 fallbackKeys.size(), msg.string());
3950 }
3951#endif
3952
3953 if (fallback) {
3954 // Restart the dispatch cycle using the fallback key.
3955 keyEntry->eventTime = event.getEventTime();
3956 keyEntry->deviceId = event.getDeviceId();
3957 keyEntry->source = event.getSource();
3958 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
3959 keyEntry->keyCode = fallbackKeyCode;
3960 keyEntry->scanCode = event.getScanCode();
3961 keyEntry->metaState = event.getMetaState();
3962 keyEntry->repeatCount = event.getRepeatCount();
3963 keyEntry->downTime = event.getDownTime();
3964 keyEntry->syntheticRepeat = false;
3965
3966#if DEBUG_OUTBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00003967 ALOGD("Unhandled key event: Dispatching fallback key. "
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003968 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
3969 originalKeyCode, fallbackKeyCode, keyEntry->metaState);
3970#endif
3971
3972 dispatchEntry->inProgress = false;
3973 startDispatchCycleLocked(now(), connection);
3974 return true; // already started next cycle
3975 } else {
3976#if DEBUG_OUTBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00003977 ALOGD("Unhandled key event: No fallback key.");
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07003978#endif
3979 }
3980 }
3981 }
3982 return false;
3983}
3984
3985bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
3986 DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
3987 return false;
Jeff Brown3915bb82010-11-05 15:02:16 -07003988}
3989
Jeff Brownb88102f2010-09-08 11:49:43 -07003990void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3991 mLock.unlock();
3992
Jeff Brown01ce2e92010-09-26 22:20:12 -07003993 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07003994
3995 mLock.lock();
3996}
3997
Jeff Brown3915bb82010-11-05 15:02:16 -07003998void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
3999 event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
4000 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
4001 entry->downTime, entry->eventTime);
4002}
4003
Jeff Brown519e0242010-09-15 15:18:56 -07004004void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
4005 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
4006 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07004007}
4008
4009void InputDispatcher::dump(String8& dump) {
Jeff Brown89ef0722011-08-10 16:25:21 -07004010 AutoMutex _l(mLock);
4011
Jeff Brownf2f487182010-10-01 17:46:21 -07004012 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07004013 dumpDispatchStateLocked(dump);
Jeff Brown214eaf42011-05-26 19:17:02 -07004014
4015 dump.append(INDENT "Configuration:\n");
Jeff Brown214eaf42011-05-26 19:17:02 -07004016 dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
4017 dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n", mConfig.keyRepeatTimeout * 0.000001f);
Jeff Brownb88102f2010-09-08 11:49:43 -07004018}
4019
Jeff Brown89ef0722011-08-10 16:25:21 -07004020void InputDispatcher::monitor() {
4021 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
4022 mLock.lock();
Jeff Brown112b5f52012-01-27 17:32:06 -08004023 mLooper->wake();
4024 mDispatcherIsAliveCondition.wait(mLock);
Jeff Brown89ef0722011-08-10 16:25:21 -07004025 mLock.unlock();
4026}
4027
Jeff Brown9c3cda02010-06-15 01:31:58 -07004028
Jeff Brown519e0242010-09-15 15:18:56 -07004029// --- InputDispatcher::Queue ---
4030
4031template <typename T>
4032uint32_t InputDispatcher::Queue<T>::count() const {
4033 uint32_t result = 0;
Jeff Brownac386072011-07-20 15:19:50 -07004034 for (const T* entry = head; entry; entry = entry->next) {
Jeff Brown519e0242010-09-15 15:18:56 -07004035 result += 1;
4036 }
4037 return result;
4038}
4039
4040
Jeff Brownac386072011-07-20 15:19:50 -07004041// --- InputDispatcher::InjectionState ---
Jeff Brown46b9ac02010-04-22 18:58:52 -07004042
Jeff Brownac386072011-07-20 15:19:50 -07004043InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
4044 refCount(1),
4045 injectorPid(injectorPid), injectorUid(injectorUid),
4046 injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
4047 pendingForegroundDispatches(0) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07004048}
4049
Jeff Brownac386072011-07-20 15:19:50 -07004050InputDispatcher::InjectionState::~InjectionState() {
Jeff Brown01ce2e92010-09-26 22:20:12 -07004051}
4052
Jeff Brownac386072011-07-20 15:19:50 -07004053void InputDispatcher::InjectionState::release() {
4054 refCount -= 1;
4055 if (refCount == 0) {
4056 delete this;
4057 } else {
Steve Blockec193de2012-01-09 18:35:44 +00004058 ALOG_ASSERT(refCount > 0);
Jeff Brown01ce2e92010-09-26 22:20:12 -07004059 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07004060}
4061
Jeff Brownac386072011-07-20 15:19:50 -07004062
4063// --- InputDispatcher::EventEntry ---
4064
4065InputDispatcher::EventEntry::EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags) :
4066 refCount(1), type(type), eventTime(eventTime), policyFlags(policyFlags),
4067 injectionState(NULL), dispatchInProgress(false) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07004068}
4069
Jeff Brownac386072011-07-20 15:19:50 -07004070InputDispatcher::EventEntry::~EventEntry() {
4071 releaseInjectionState();
4072}
4073
4074void InputDispatcher::EventEntry::release() {
4075 refCount -= 1;
4076 if (refCount == 0) {
4077 delete this;
4078 } else {
Steve Blockec193de2012-01-09 18:35:44 +00004079 ALOG_ASSERT(refCount > 0);
Jeff Brownac386072011-07-20 15:19:50 -07004080 }
4081}
4082
4083void InputDispatcher::EventEntry::releaseInjectionState() {
4084 if (injectionState) {
4085 injectionState->release();
4086 injectionState = NULL;
4087 }
4088}
4089
4090
4091// --- InputDispatcher::ConfigurationChangedEntry ---
4092
4093InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(nsecs_t eventTime) :
4094 EventEntry(TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
4095}
4096
4097InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
4098}
4099
4100
Jeff Brown65fd2512011-08-18 11:20:58 -07004101// --- InputDispatcher::DeviceResetEntry ---
4102
4103InputDispatcher::DeviceResetEntry::DeviceResetEntry(nsecs_t eventTime, int32_t deviceId) :
4104 EventEntry(TYPE_DEVICE_RESET, eventTime, 0),
4105 deviceId(deviceId) {
4106}
4107
4108InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
4109}
4110
4111
Jeff Brownac386072011-07-20 15:19:50 -07004112// --- InputDispatcher::KeyEntry ---
4113
4114InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
Jeff Brown58a2da82011-01-25 16:02:22 -08004115 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07004116 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
Jeff Brownac386072011-07-20 15:19:50 -07004117 int32_t repeatCount, nsecs_t downTime) :
4118 EventEntry(TYPE_KEY, eventTime, policyFlags),
4119 deviceId(deviceId), source(source), action(action), flags(flags),
4120 keyCode(keyCode), scanCode(scanCode), metaState(metaState),
4121 repeatCount(repeatCount), downTime(downTime),
Jeff Brown905805a2011-10-12 13:57:59 -07004122 syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
4123 interceptKeyWakeupTime(0) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07004124}
4125
Jeff Brownac386072011-07-20 15:19:50 -07004126InputDispatcher::KeyEntry::~KeyEntry() {
4127}
Jeff Brown7fbdc842010-06-17 20:52:56 -07004128
Jeff Brownac386072011-07-20 15:19:50 -07004129void InputDispatcher::KeyEntry::recycle() {
4130 releaseInjectionState();
4131
4132 dispatchInProgress = false;
4133 syntheticRepeat = false;
4134 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown905805a2011-10-12 13:57:59 -07004135 interceptKeyWakeupTime = 0;
Jeff Brownac386072011-07-20 15:19:50 -07004136}
4137
4138
4139// --- InputDispatcher::MotionSample ---
4140
4141InputDispatcher::MotionSample::MotionSample(nsecs_t eventTime,
4142 const PointerCoords* pointerCoords, uint32_t pointerCount) :
4143 next(NULL), eventTime(eventTime), eventTimeBeforeCoalescing(eventTime) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07004144 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brownac386072011-07-20 15:19:50 -07004145 this->pointerCoords[i].copyFrom(pointerCoords[i]);
Jeff Brown7fbdc842010-06-17 20:52:56 -07004146 }
Jeff Brownb88102f2010-09-08 11:49:43 -07004147}
4148
4149
Jeff Brownae9fc032010-08-18 15:51:08 -07004150// --- InputDispatcher::MotionEntry ---
4151
Jeff Brownac386072011-07-20 15:19:50 -07004152InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,
4153 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
4154 int32_t metaState, int32_t buttonState,
4155 int32_t edgeFlags, float xPrecision, float yPrecision,
4156 nsecs_t downTime, uint32_t pointerCount,
4157 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) :
4158 EventEntry(TYPE_MOTION, eventTime, policyFlags),
4159 deviceId(deviceId), source(source), action(action), flags(flags),
4160 metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
4161 xPrecision(xPrecision), yPrecision(yPrecision),
4162 downTime(downTime), pointerCount(pointerCount),
4163 firstSample(eventTime, pointerCoords, pointerCount),
4164 lastSample(&firstSample) {
4165 for (uint32_t i = 0; i < pointerCount; i++) {
4166 this->pointerProperties[i].copyFrom(pointerProperties[i]);
4167 }
4168}
4169
4170InputDispatcher::MotionEntry::~MotionEntry() {
4171 for (MotionSample* sample = firstSample.next; sample != NULL; ) {
4172 MotionSample* next = sample->next;
4173 delete sample;
4174 sample = next;
4175 }
4176}
4177
Jeff Brownae9fc032010-08-18 15:51:08 -07004178uint32_t InputDispatcher::MotionEntry::countSamples() const {
4179 uint32_t count = 1;
4180 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
4181 count += 1;
4182 }
4183 return count;
4184}
4185
Jeff Brown4e91a182011-04-07 11:38:09 -07004186bool InputDispatcher::MotionEntry::canAppendSamples(int32_t action, uint32_t pointerCount,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07004187 const PointerProperties* pointerProperties) const {
Jeff Brown4e91a182011-04-07 11:38:09 -07004188 if (this->action != action
4189 || this->pointerCount != pointerCount
4190 || this->isInjected()) {
4191 return false;
4192 }
4193 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07004194 if (this->pointerProperties[i] != pointerProperties[i]) {
Jeff Brown4e91a182011-04-07 11:38:09 -07004195 return false;
4196 }
4197 }
4198 return true;
4199}
4200
Jeff Brownac386072011-07-20 15:19:50 -07004201void InputDispatcher::MotionEntry::appendSample(
4202 nsecs_t eventTime, const PointerCoords* pointerCoords) {
4203 MotionSample* sample = new MotionSample(eventTime, pointerCoords, pointerCount);
4204
4205 lastSample->next = sample;
4206 lastSample = sample;
4207}
4208
4209
4210// --- InputDispatcher::DispatchEntry ---
4211
4212InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
4213 int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) :
4214 eventEntry(eventEntry), targetFlags(targetFlags),
4215 xOffset(xOffset), yOffset(yOffset), scaleFactor(scaleFactor),
4216 inProgress(false),
4217 resolvedAction(0), resolvedFlags(0),
4218 headMotionSample(NULL), tailMotionSample(NULL) {
4219 eventEntry->refCount += 1;
4220}
4221
4222InputDispatcher::DispatchEntry::~DispatchEntry() {
4223 eventEntry->release();
4224}
4225
Jeff Brownb88102f2010-09-08 11:49:43 -07004226
4227// --- InputDispatcher::InputState ---
4228
Jeff Brownb6997262010-10-08 22:31:17 -07004229InputDispatcher::InputState::InputState() {
Jeff Brownb88102f2010-09-08 11:49:43 -07004230}
4231
4232InputDispatcher::InputState::~InputState() {
4233}
4234
4235bool InputDispatcher::InputState::isNeutral() const {
4236 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
4237}
4238
Jeff Brown81346812011-06-28 20:08:48 -07004239bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source) const {
4240 for (size_t i = 0; i < mMotionMementos.size(); i++) {
4241 const MotionMemento& memento = mMotionMementos.itemAt(i);
4242 if (memento.deviceId == deviceId
4243 && memento.source == source
4244 && memento.hovering) {
4245 return true;
4246 }
4247 }
4248 return false;
4249}
Jeff Brownb88102f2010-09-08 11:49:43 -07004250
Jeff Brown81346812011-06-28 20:08:48 -07004251bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
4252 int32_t action, int32_t flags) {
4253 switch (action) {
4254 case AKEY_EVENT_ACTION_UP: {
4255 if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
4256 for (size_t i = 0; i < mFallbackKeys.size(); ) {
4257 if (mFallbackKeys.valueAt(i) == entry->keyCode) {
4258 mFallbackKeys.removeItemsAt(i);
4259 } else {
4260 i += 1;
4261 }
4262 }
4263 }
4264 ssize_t index = findKeyMemento(entry);
4265 if (index >= 0) {
4266 mKeyMementos.removeAt(index);
4267 return true;
4268 }
Jeff Brown68b909d2011-12-07 16:36:01 -08004269 /* FIXME: We can't just drop the key up event because that prevents creating
4270 * popup windows that are automatically shown when a key is held and then
4271 * dismissed when the key is released. The problem is that the popup will
4272 * not have received the original key down, so the key up will be considered
4273 * to be inconsistent with its observed state. We could perhaps handle this
4274 * by synthesizing a key down but that will cause other problems.
4275 *
4276 * So for now, allow inconsistent key up events to be dispatched.
4277 *
Jeff Brown81346812011-06-28 20:08:48 -07004278#if DEBUG_OUTBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00004279 ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
Jeff Brown81346812011-06-28 20:08:48 -07004280 "keyCode=%d, scanCode=%d",
4281 entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
4282#endif
4283 return false;
Jeff Brown68b909d2011-12-07 16:36:01 -08004284 */
4285 return true;
Jeff Brown81346812011-06-28 20:08:48 -07004286 }
4287
4288 case AKEY_EVENT_ACTION_DOWN: {
4289 ssize_t index = findKeyMemento(entry);
4290 if (index >= 0) {
4291 mKeyMementos.removeAt(index);
4292 }
4293 addKeyMemento(entry, flags);
4294 return true;
4295 }
4296
4297 default:
4298 return true;
Jeff Brownb88102f2010-09-08 11:49:43 -07004299 }
4300}
4301
Jeff Brown81346812011-06-28 20:08:48 -07004302bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
4303 int32_t action, int32_t flags) {
4304 int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
4305 switch (actionMasked) {
4306 case AMOTION_EVENT_ACTION_UP:
4307 case AMOTION_EVENT_ACTION_CANCEL: {
4308 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4309 if (index >= 0) {
4310 mMotionMementos.removeAt(index);
4311 return true;
Jeff Brownda3d5a92011-03-29 15:11:34 -07004312 }
Jeff Brown81346812011-06-28 20:08:48 -07004313#if DEBUG_OUTBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00004314 ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
Jeff Brown81346812011-06-28 20:08:48 -07004315 "actionMasked=%d",
4316 entry->deviceId, entry->source, actionMasked);
4317#endif
4318 return false;
Jeff Brownda3d5a92011-03-29 15:11:34 -07004319 }
4320
Jeff Brown81346812011-06-28 20:08:48 -07004321 case AMOTION_EVENT_ACTION_DOWN: {
4322 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4323 if (index >= 0) {
4324 mMotionMementos.removeAt(index);
4325 }
4326 addMotionMemento(entry, flags, false /*hovering*/);
4327 return true;
4328 }
4329
4330 case AMOTION_EVENT_ACTION_POINTER_UP:
4331 case AMOTION_EVENT_ACTION_POINTER_DOWN:
4332 case AMOTION_EVENT_ACTION_MOVE: {
4333 ssize_t index = findMotionMemento(entry, false /*hovering*/);
4334 if (index >= 0) {
4335 MotionMemento& memento = mMotionMementos.editItemAt(index);
4336 memento.setPointers(entry);
4337 return true;
4338 }
Jeff Brown2e45fb62011-06-29 21:19:05 -07004339 if (actionMasked == AMOTION_EVENT_ACTION_MOVE
4340 && (entry->source & (AINPUT_SOURCE_CLASS_JOYSTICK
4341 | AINPUT_SOURCE_CLASS_NAVIGATION))) {
4342 // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
4343 return true;
4344 }
Jeff Brown81346812011-06-28 20:08:48 -07004345#if DEBUG_OUTBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00004346 ALOGD("Dropping inconsistent motion pointer up/down or move event: "
Jeff Brown81346812011-06-28 20:08:48 -07004347 "deviceId=%d, source=%08x, actionMasked=%d",
4348 entry->deviceId, entry->source, actionMasked);
4349#endif
4350 return false;
4351 }
4352
4353 case AMOTION_EVENT_ACTION_HOVER_EXIT: {
4354 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4355 if (index >= 0) {
4356 mMotionMementos.removeAt(index);
4357 return true;
4358 }
4359#if DEBUG_OUTBOUND_EVENT_DETAILS
Steve Block5baa3a62011-12-20 16:23:08 +00004360 ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x",
Jeff Brown81346812011-06-28 20:08:48 -07004361 entry->deviceId, entry->source);
4362#endif
4363 return false;
4364 }
4365
4366 case AMOTION_EVENT_ACTION_HOVER_ENTER:
4367 case AMOTION_EVENT_ACTION_HOVER_MOVE: {
4368 ssize_t index = findMotionMemento(entry, true /*hovering*/);
4369 if (index >= 0) {
4370 mMotionMementos.removeAt(index);
4371 }
4372 addMotionMemento(entry, flags, true /*hovering*/);
4373 return true;
4374 }
4375
4376 default:
4377 return true;
4378 }
4379}
4380
4381ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07004382 for (size_t i = 0; i < mKeyMementos.size(); i++) {
Jeff Brown81346812011-06-28 20:08:48 -07004383 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07004384 if (memento.deviceId == entry->deviceId
4385 && memento.source == entry->source
4386 && memento.keyCode == entry->keyCode
4387 && memento.scanCode == entry->scanCode) {
Jeff Brown81346812011-06-28 20:08:48 -07004388 return i;
Jeff Brownb88102f2010-09-08 11:49:43 -07004389 }
4390 }
Jeff Brown81346812011-06-28 20:08:48 -07004391 return -1;
Jeff Brownb88102f2010-09-08 11:49:43 -07004392}
4393
Jeff Brown81346812011-06-28 20:08:48 -07004394ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
4395 bool hovering) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07004396 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Jeff Brown81346812011-06-28 20:08:48 -07004397 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07004398 if (memento.deviceId == entry->deviceId
Jeff Brown81346812011-06-28 20:08:48 -07004399 && memento.source == entry->source
4400 && memento.hovering == hovering) {
4401 return i;
Jeff Brownb88102f2010-09-08 11:49:43 -07004402 }
4403 }
Jeff Brown81346812011-06-28 20:08:48 -07004404 return -1;
4405}
Jeff Brownb88102f2010-09-08 11:49:43 -07004406
Jeff Brown81346812011-06-28 20:08:48 -07004407void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
4408 mKeyMementos.push();
4409 KeyMemento& memento = mKeyMementos.editTop();
4410 memento.deviceId = entry->deviceId;
4411 memento.source = entry->source;
4412 memento.keyCode = entry->keyCode;
4413 memento.scanCode = entry->scanCode;
4414 memento.flags = flags;
4415 memento.downTime = entry->downTime;
4416}
4417
4418void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
4419 int32_t flags, bool hovering) {
4420 mMotionMementos.push();
4421 MotionMemento& memento = mMotionMementos.editTop();
4422 memento.deviceId = entry->deviceId;
4423 memento.source = entry->source;
4424 memento.flags = flags;
4425 memento.xPrecision = entry->xPrecision;
4426 memento.yPrecision = entry->yPrecision;
4427 memento.downTime = entry->downTime;
4428 memento.setPointers(entry);
4429 memento.hovering = hovering;
Jeff Brownb88102f2010-09-08 11:49:43 -07004430}
4431
4432void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
4433 pointerCount = entry->pointerCount;
4434 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07004435 pointerProperties[i].copyFrom(entry->pointerProperties[i]);
Jeff Brownace13b12011-03-09 17:39:48 -08004436 pointerCoords[i].copyFrom(entry->lastSample->pointerCoords[i]);
Jeff Brownb88102f2010-09-08 11:49:43 -07004437 }
4438}
4439
Jeff Brownb6997262010-10-08 22:31:17 -07004440void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
Jeff Brownac386072011-07-20 15:19:50 -07004441 Vector<EventEntry*>& outEvents, const CancelationOptions& options) {
Jeff Brown81346812011-06-28 20:08:48 -07004442 for (size_t i = 0; i < mKeyMementos.size(); i++) {
Jeff Brownb88102f2010-09-08 11:49:43 -07004443 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08004444 if (shouldCancelKey(memento, options)) {
Jeff Brownac386072011-07-20 15:19:50 -07004445 outEvents.push(new KeyEntry(currentTime,
Jeff Brownb6997262010-10-08 22:31:17 -07004446 memento.deviceId, memento.source, 0,
Jeff Brown49ed71d2010-12-06 17:13:33 -08004447 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
Jeff Brownb6997262010-10-08 22:31:17 -07004448 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
Jeff Brownb6997262010-10-08 22:31:17 -07004449 }
Jeff Brownb88102f2010-09-08 11:49:43 -07004450 }
4451
Jeff Brown81346812011-06-28 20:08:48 -07004452 for (size_t i = 0; i < mMotionMementos.size(); i++) {
Jeff Brownb88102f2010-09-08 11:49:43 -07004453 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08004454 if (shouldCancelMotion(memento, options)) {
Jeff Brownac386072011-07-20 15:19:50 -07004455 outEvents.push(new MotionEntry(currentTime,
Jeff Brownb6997262010-10-08 22:31:17 -07004456 memento.deviceId, memento.source, 0,
Jeff Browna032cc02011-03-07 16:56:21 -08004457 memento.hovering
4458 ? AMOTION_EVENT_ACTION_HOVER_EXIT
4459 : AMOTION_EVENT_ACTION_CANCEL,
Jeff Brown81346812011-06-28 20:08:48 -07004460 memento.flags, 0, 0, 0,
Jeff Brownb6997262010-10-08 22:31:17 -07004461 memento.xPrecision, memento.yPrecision, memento.downTime,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -07004462 memento.pointerCount, memento.pointerProperties, memento.pointerCoords));
Jeff Brownb6997262010-10-08 22:31:17 -07004463 }
Jeff Brownb88102f2010-09-08 11:49:43 -07004464 }
4465}
4466
4467void InputDispatcher::InputState::clear() {
4468 mKeyMementos.clear();
4469 mMotionMementos.clear();
Jeff Brownda3d5a92011-03-29 15:11:34 -07004470 mFallbackKeys.clear();
Jeff Brownb6997262010-10-08 22:31:17 -07004471}
4472
Jeff Brown9c9f1a32010-10-11 18:32:20 -07004473void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
4474 for (size_t i = 0; i < mMotionMementos.size(); i++) {
4475 const MotionMemento& memento = mMotionMementos.itemAt(i);
4476 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
4477 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
4478 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
4479 if (memento.deviceId == otherMemento.deviceId
4480 && memento.source == otherMemento.source) {
4481 other.mMotionMementos.removeAt(j);
4482 } else {
4483 j += 1;
4484 }
4485 }
4486 other.mMotionMementos.push(memento);
4487 }
4488 }
4489}
4490
Jeff Brownda3d5a92011-03-29 15:11:34 -07004491int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
4492 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
4493 return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
4494}
4495
4496void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
4497 int32_t fallbackKeyCode) {
4498 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
4499 if (index >= 0) {
4500 mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
4501 } else {
4502 mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
4503 }
4504}
4505
4506void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
4507 mFallbackKeys.removeItem(originalKeyCode);
4508}
4509
Jeff Brown49ed71d2010-12-06 17:13:33 -08004510bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
Jeff Brownda3d5a92011-03-29 15:11:34 -07004511 const CancelationOptions& options) {
4512 if (options.keyCode != -1 && memento.keyCode != options.keyCode) {
4513 return false;
4514 }
4515
Jeff Brown65fd2512011-08-18 11:20:58 -07004516 if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
4517 return false;
4518 }
4519
Jeff Brownda3d5a92011-03-29 15:11:34 -07004520 switch (options.mode) {
4521 case CancelationOptions::CANCEL_ALL_EVENTS:
4522 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07004523 return true;
Jeff Brownda3d5a92011-03-29 15:11:34 -07004524 case CancelationOptions::CANCEL_FALLBACK_EVENTS:
Jeff Brown49ed71d2010-12-06 17:13:33 -08004525 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
4526 default:
4527 return false;
4528 }
4529}
4530
4531bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
Jeff Brownda3d5a92011-03-29 15:11:34 -07004532 const CancelationOptions& options) {
Jeff Brown65fd2512011-08-18 11:20:58 -07004533 if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
4534 return false;
4535 }
4536
Jeff Brownda3d5a92011-03-29 15:11:34 -07004537 switch (options.mode) {
4538 case CancelationOptions::CANCEL_ALL_EVENTS:
Jeff Brown49ed71d2010-12-06 17:13:33 -08004539 return true;
Jeff Brownda3d5a92011-03-29 15:11:34 -07004540 case CancelationOptions::CANCEL_POINTER_EVENTS:
Jeff Brown49ed71d2010-12-06 17:13:33 -08004541 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
Jeff Brownda3d5a92011-03-29 15:11:34 -07004542 case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
Jeff Brown49ed71d2010-12-06 17:13:33 -08004543 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
4544 default:
4545 return false;
Jeff Brownb6997262010-10-08 22:31:17 -07004546 }
Jeff Brownb88102f2010-09-08 11:49:43 -07004547}
4548
4549
Jeff Brown46b9ac02010-04-22 18:58:52 -07004550// --- InputDispatcher::Connection ---
4551
Jeff Brown928e0542011-01-10 11:17:36 -08004552InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
Jeff Browncc4f7db2011-08-30 20:34:48 -07004553 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) :
Jeff Brown928e0542011-01-10 11:17:36 -08004554 status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
Jeff Browncc4f7db2011-08-30 20:34:48 -07004555 monitor(monitor),
Jeff Brown928e0542011-01-10 11:17:36 -08004556 inputPublisher(inputChannel),
Jeff Brownda3d5a92011-03-29 15:11:34 -07004557 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07004558}
4559
4560InputDispatcher::Connection::~Connection() {
4561}
4562
4563status_t InputDispatcher::Connection::initialize() {
4564 return inputPublisher.initialize();
4565}
4566
Jeff Brown9c3cda02010-06-15 01:31:58 -07004567const char* InputDispatcher::Connection::getStatusLabel() const {
4568 switch (status) {
4569 case STATUS_NORMAL:
4570 return "NORMAL";
4571
4572 case STATUS_BROKEN:
4573 return "BROKEN";
4574
Jeff Brown9c3cda02010-06-15 01:31:58 -07004575 case STATUS_ZOMBIE:
4576 return "ZOMBIE";
4577
4578 default:
4579 return "UNKNOWN";
4580 }
4581}
4582
Jeff Brown46b9ac02010-04-22 18:58:52 -07004583InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
4584 const EventEntry* eventEntry) const {
Jeff Brownac386072011-07-20 15:19:50 -07004585 for (DispatchEntry* dispatchEntry = outboundQueue.tail; dispatchEntry;
4586 dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07004587 if (dispatchEntry->eventEntry == eventEntry) {
4588 return dispatchEntry;
4589 }
4590 }
4591 return NULL;
4592}
4593
Jeff Brownb88102f2010-09-08 11:49:43 -07004594
Jeff Brown9c3cda02010-06-15 01:31:58 -07004595// --- InputDispatcher::CommandEntry ---
4596
Jeff Brownac386072011-07-20 15:19:50 -07004597InputDispatcher::CommandEntry::CommandEntry(Command command) :
4598 command(command), eventTime(0), keyEntry(NULL), userActivityEventType(0), handled(false) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07004599}
4600
4601InputDispatcher::CommandEntry::~CommandEntry() {
4602}
4603
Jeff Brown46b9ac02010-04-22 18:58:52 -07004604
Jeff Brown01ce2e92010-09-26 22:20:12 -07004605// --- InputDispatcher::TouchState ---
4606
4607InputDispatcher::TouchState::TouchState() :
Jeff Brown58a2da82011-01-25 16:02:22 -08004608 down(false), split(false), deviceId(-1), source(0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07004609}
4610
4611InputDispatcher::TouchState::~TouchState() {
4612}
4613
4614void InputDispatcher::TouchState::reset() {
4615 down = false;
4616 split = false;
Jeff Brown95712852011-01-04 19:41:59 -08004617 deviceId = -1;
Jeff Brown58a2da82011-01-25 16:02:22 -08004618 source = 0;
Jeff Brown01ce2e92010-09-26 22:20:12 -07004619 windows.clear();
4620}
4621
4622void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
4623 down = other.down;
4624 split = other.split;
Jeff Brown95712852011-01-04 19:41:59 -08004625 deviceId = other.deviceId;
Jeff Brown58a2da82011-01-25 16:02:22 -08004626 source = other.source;
Jeff Brown9302c872011-07-13 22:51:29 -07004627 windows = other.windows;
Jeff Brown01ce2e92010-09-26 22:20:12 -07004628}
4629
Jeff Brown9302c872011-07-13 22:51:29 -07004630void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
Jeff Brown01ce2e92010-09-26 22:20:12 -07004631 int32_t targetFlags, BitSet32 pointerIds) {
4632 if (targetFlags & InputTarget::FLAG_SPLIT) {
4633 split = true;
4634 }
4635
4636 for (size_t i = 0; i < windows.size(); i++) {
4637 TouchedWindow& touchedWindow = windows.editItemAt(i);
Jeff Brown9302c872011-07-13 22:51:29 -07004638 if (touchedWindow.windowHandle == windowHandle) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07004639 touchedWindow.targetFlags |= targetFlags;
Jeff Brown98db5fa2011-06-08 15:37:10 -07004640 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
4641 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
4642 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07004643 touchedWindow.pointerIds.value |= pointerIds.value;
4644 return;
4645 }
4646 }
4647
4648 windows.push();
4649
4650 TouchedWindow& touchedWindow = windows.editTop();
Jeff Brown9302c872011-07-13 22:51:29 -07004651 touchedWindow.windowHandle = windowHandle;
Jeff Brown01ce2e92010-09-26 22:20:12 -07004652 touchedWindow.targetFlags = targetFlags;
4653 touchedWindow.pointerIds = pointerIds;
Jeff Brown01ce2e92010-09-26 22:20:12 -07004654}
4655
Jeff Browna032cc02011-03-07 16:56:21 -08004656void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
Jeff Brown01ce2e92010-09-26 22:20:12 -07004657 for (size_t i = 0 ; i < windows.size(); ) {
Jeff Browna032cc02011-03-07 16:56:21 -08004658 TouchedWindow& window = windows.editItemAt(i);
Jeff Brown98db5fa2011-06-08 15:37:10 -07004659 if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
4660 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
Jeff Browna032cc02011-03-07 16:56:21 -08004661 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
4662 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
Jeff Brown01ce2e92010-09-26 22:20:12 -07004663 i += 1;
Jeff Browna032cc02011-03-07 16:56:21 -08004664 } else {
4665 windows.removeAt(i);
Jeff Brown01ce2e92010-09-26 22:20:12 -07004666 }
4667 }
4668}
4669
Jeff Brown9302c872011-07-13 22:51:29 -07004670sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
Jeff Brown01ce2e92010-09-26 22:20:12 -07004671 for (size_t i = 0; i < windows.size(); i++) {
Jeff Brown98db5fa2011-06-08 15:37:10 -07004672 const TouchedWindow& window = windows.itemAt(i);
4673 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Brown9302c872011-07-13 22:51:29 -07004674 return window.windowHandle;
Jeff Brown01ce2e92010-09-26 22:20:12 -07004675 }
4676 }
4677 return NULL;
4678}
4679
Jeff Brown98db5fa2011-06-08 15:37:10 -07004680bool InputDispatcher::TouchState::isSlippery() const {
4681 // Must have exactly one foreground window.
4682 bool haveSlipperyForegroundWindow = false;
4683 for (size_t i = 0; i < windows.size(); i++) {
4684 const TouchedWindow& window = windows.itemAt(i);
4685 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
Jeff Browncc4f7db2011-08-30 20:34:48 -07004686 if (haveSlipperyForegroundWindow
4687 || !(window.windowHandle->getInfo()->layoutParamsFlags
4688 & InputWindowInfo::FLAG_SLIPPERY)) {
Jeff Brown98db5fa2011-06-08 15:37:10 -07004689 return false;
4690 }
4691 haveSlipperyForegroundWindow = true;
4692 }
4693 }
4694 return haveSlipperyForegroundWindow;
4695}
4696
Jeff Brown01ce2e92010-09-26 22:20:12 -07004697
Jeff Brown46b9ac02010-04-22 18:58:52 -07004698// --- InputDispatcherThread ---
4699
4700InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
4701 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
4702}
4703
4704InputDispatcherThread::~InputDispatcherThread() {
4705}
4706
4707bool InputDispatcherThread::threadLoop() {
4708 mDispatcher->dispatchOnce();
4709 return true;
4710}
4711
4712} // namespace android