blob: 89a7751a35fdd0acec752f8b9d844351547cf6c8 [file] [log] [blame]
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070017#define LOG_TAG "InputDispatcher"
18
19//#define LOG_NDEBUG 0
20
21// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070022#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070023
24// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070025#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070026
27// Log debug messages about batching.
Jeff Brown349703e2010-06-22 01:27:15 -070028#define DEBUG_BATCHING 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070029
30// Log debug messages about the dispatch cycle.
Jeff Brown349703e2010-06-22 01:27:15 -070031#define DEBUG_DISPATCH_CYCLE 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070032
Jeff Brown9c3cda02010-06-15 01:31:58 -070033// Log debug messages about registrations.
Jeff Brown349703e2010-06-22 01:27:15 -070034#define DEBUG_REGISTRATION 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070035
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070036// Log debug messages about performance statistics.
Jeff Brown349703e2010-06-22 01:27:15 -070037#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070038
Jeff Brown7fbdc842010-06-17 20:52:56 -070039// Log debug messages about input event injection.
Jeff Brown349703e2010-06-22 01:27:15 -070040#define DEBUG_INJECTION 0
Jeff Brown7fbdc842010-06-17 20:52:56 -070041
Jeff Brownae9fc032010-08-18 15:51:08 -070042// Log debug messages about input event throttling.
43#define DEBUG_THROTTLING 0
44
Jeff Brownb88102f2010-09-08 11:49:43 -070045// Log debug messages about input focus tracking.
46#define DEBUG_FOCUS 0
47
48// Log debug messages about the app switch latency optimization.
49#define DEBUG_APP_SWITCH 0
50
Jeff Brownb4ff35d2011-01-02 16:37:43 -080051#include "InputDispatcher.h"
52
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070053#include <cutils/log.h>
Jeff Brownb88102f2010-09-08 11:49:43 -070054#include <ui/PowerManager.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070055
56#include <stddef.h>
57#include <unistd.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070058#include <errno.h>
59#include <limits.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070060
Jeff Brownf2f487182010-10-01 17:46:21 -070061#define INDENT " "
62#define INDENT2 " "
63
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070064namespace android {
65
Jeff Brownb88102f2010-09-08 11:49:43 -070066// Default input dispatching timeout if there is no focused application or paused window
67// from which to determine an appropriate dispatching timeout.
68const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
69
70// Amount of time to allow for all pending events to be processed when an app switch
71// key is on the way. This is used to preempt input dispatch and drop input events
72// when an application takes too long to respond and the user has pressed an app switch key.
73const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
74
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070075
Jeff Brown7fbdc842010-06-17 20:52:56 -070076static inline nsecs_t now() {
77 return systemTime(SYSTEM_TIME_MONOTONIC);
78}
79
Jeff Brownb88102f2010-09-08 11:49:43 -070080static inline const char* toString(bool value) {
81 return value ? "true" : "false";
82}
83
Jeff Brown01ce2e92010-09-26 22:20:12 -070084static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
85 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
86 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
87}
88
89static bool isValidKeyAction(int32_t action) {
90 switch (action) {
91 case AKEY_EVENT_ACTION_DOWN:
92 case AKEY_EVENT_ACTION_UP:
93 return true;
94 default:
95 return false;
96 }
97}
98
99static bool validateKeyEvent(int32_t action) {
100 if (! isValidKeyAction(action)) {
101 LOGE("Key event has invalid action code 0x%x", action);
102 return false;
103 }
104 return true;
105}
106
Jeff Brownb6997262010-10-08 22:31:17 -0700107static bool isValidMotionAction(int32_t action, size_t pointerCount) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700108 switch (action & AMOTION_EVENT_ACTION_MASK) {
109 case AMOTION_EVENT_ACTION_DOWN:
110 case AMOTION_EVENT_ACTION_UP:
111 case AMOTION_EVENT_ACTION_CANCEL:
112 case AMOTION_EVENT_ACTION_MOVE:
Jeff Brown01ce2e92010-09-26 22:20:12 -0700113 case AMOTION_EVENT_ACTION_OUTSIDE:
114 return true;
Jeff Brownb6997262010-10-08 22:31:17 -0700115 case AMOTION_EVENT_ACTION_POINTER_DOWN:
116 case AMOTION_EVENT_ACTION_POINTER_UP: {
117 int32_t index = getMotionEventActionPointerIndex(action);
118 return index >= 0 && size_t(index) < pointerCount;
119 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700120 default:
121 return false;
122 }
123}
124
125static bool validateMotionEvent(int32_t action, size_t pointerCount,
126 const int32_t* pointerIds) {
Jeff Brownb6997262010-10-08 22:31:17 -0700127 if (! isValidMotionAction(action, pointerCount)) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700128 LOGE("Motion event has invalid action code 0x%x", action);
129 return false;
130 }
131 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
132 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
133 pointerCount, MAX_POINTERS);
134 return false;
135 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700136 BitSet32 pointerIdBits;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700137 for (size_t i = 0; i < pointerCount; i++) {
Jeff Brownc3db8582010-10-20 15:33:38 -0700138 int32_t id = pointerIds[i];
139 if (id < 0 || id > MAX_POINTER_ID) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700140 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
Jeff Brownc3db8582010-10-20 15:33:38 -0700141 id, MAX_POINTER_ID);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700142 return false;
143 }
Jeff Brownc3db8582010-10-20 15:33:38 -0700144 if (pointerIdBits.hasBit(id)) {
145 LOGE("Motion event has duplicate pointer id %d", id);
146 return false;
147 }
148 pointerIdBits.markBit(id);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700149 }
150 return true;
151}
152
Jeff Brownb88102f2010-09-08 11:49:43 -0700153
154// --- InputWindow ---
155
Jeff Brownb88102f2010-09-08 11:49:43 -0700156bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
157 return x >= touchableAreaLeft && x <= touchableAreaRight
158 && y >= touchableAreaTop && y <= touchableAreaBottom;
159}
160
Jeff Brown19dfc832010-10-05 12:26:23 -0700161bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
162 return x >= frameLeft && x <= frameRight
163 && y >= frameTop && y <= frameBottom;
164}
165
166bool InputWindow::isTrustedOverlay() const {
167 return layoutParamsType == TYPE_INPUT_METHOD
Jeff Brown3b2b3542010-10-15 00:54:27 -0700168 || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
169 || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
Jeff Brown19dfc832010-10-05 12:26:23 -0700170}
171
Jeff Brown46e75292010-11-10 16:53:45 -0800172bool InputWindow::supportsSplitTouch() const {
173 return layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH;
174}
175
Jeff Brownb88102f2010-09-08 11:49:43 -0700176
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700177// --- InputDispatcher ---
178
Jeff Brown9c3cda02010-06-15 01:31:58 -0700179InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Brownb88102f2010-09-08 11:49:43 -0700180 mPolicy(policy),
181 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
182 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brown01ce2e92010-09-26 22:20:12 -0700183 mFocusedWindow(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700184 mFocusedApplication(NULL),
185 mCurrentInputTargetsValid(false),
186 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700187 mLooper = new Looper(false);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700188
Jeff Brownb88102f2010-09-08 11:49:43 -0700189 mInboundQueue.headSentinel.refCount = -1;
190 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
191 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700192
Jeff Brownb88102f2010-09-08 11:49:43 -0700193 mInboundQueue.tailSentinel.refCount = -1;
194 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
195 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700196
197 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700198
Jeff Brownae9fc032010-08-18 15:51:08 -0700199 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
200 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
201 mThrottleState.lastDeviceId = -1;
202
203#if DEBUG_THROTTLING
204 mThrottleState.originalSampleCount = 0;
205 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
206#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700207}
208
209InputDispatcher::~InputDispatcher() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700210 { // acquire lock
211 AutoMutex _l(mLock);
212
213 resetKeyRepeatLocked();
Jeff Brown54a18252010-09-16 14:07:33 -0700214 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700215 drainInboundQueueLocked();
216 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700217
218 while (mConnectionsByReceiveFd.size() != 0) {
219 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
220 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700221}
222
223void InputDispatcher::dispatchOnce() {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700224 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700225 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700226
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700227 nsecs_t nextWakeupTime = LONG_LONG_MAX;
228 { // acquire lock
229 AutoMutex _l(mLock);
Jeff Brownb88102f2010-09-08 11:49:43 -0700230 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700231
Jeff Brownb88102f2010-09-08 11:49:43 -0700232 if (runCommandsLockedInterruptible()) {
233 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700234 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700235 } // release lock
236
Jeff Brownb88102f2010-09-08 11:49:43 -0700237 // Wait for callback or timeout or wake. (make sure we round up, not down)
238 nsecs_t currentTime = now();
239 int32_t timeoutMillis;
240 if (nextWakeupTime > currentTime) {
241 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
242 timeout = (timeout + 999999LL) / 1000000LL;
243 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
244 } else {
245 timeoutMillis = 0;
246 }
247
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700248 mLooper->pollOnce(timeoutMillis);
Jeff Brownb88102f2010-09-08 11:49:43 -0700249}
250
251void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
252 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
253 nsecs_t currentTime = now();
254
255 // Reset the key repeat timer whenever we disallow key events, even if the next event
256 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
257 // out of sleep.
258 if (keyRepeatTimeout < 0) {
259 resetKeyRepeatLocked();
260 }
261
Jeff Brownb88102f2010-09-08 11:49:43 -0700262 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
263 if (mDispatchFrozen) {
264#if DEBUG_FOCUS
265 LOGD("Dispatch frozen. Waiting some more.");
266#endif
267 return;
268 }
269
270 // Optimize latency of app switches.
271 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
272 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
273 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
274 if (mAppSwitchDueTime < *nextWakeupTime) {
275 *nextWakeupTime = mAppSwitchDueTime;
276 }
277
Jeff Brownb88102f2010-09-08 11:49:43 -0700278 // Ready to start a new event.
279 // If we don't already have a pending event, go grab one.
280 if (! mPendingEvent) {
281 if (mInboundQueue.isEmpty()) {
282 if (isAppSwitchDue) {
283 // The inbound queue is empty so the app switch key we were waiting
284 // for will never arrive. Stop waiting for it.
285 resetPendingAppSwitchLocked(false);
286 isAppSwitchDue = false;
287 }
288
289 // Synthesize a key repeat if appropriate.
290 if (mKeyRepeatState.lastKeyEntry) {
291 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
292 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
293 } else {
294 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
295 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
296 }
297 }
298 }
299 if (! mPendingEvent) {
300 return;
301 }
302 } else {
303 // Inbound queue has at least one entry.
304 EventEntry* entry = mInboundQueue.headSentinel.next;
305
306 // Throttle the entry if it is a move event and there are no
307 // other events behind it in the queue. Due to movement batching, additional
308 // samples may be appended to this event by the time the throttling timeout
309 // expires.
310 // TODO Make this smarter and consider throttling per device independently.
Jeff Brownb6997262010-10-08 22:31:17 -0700311 if (entry->type == EventEntry::TYPE_MOTION
312 && !isAppSwitchDue
313 && mDispatchEnabled
314 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
315 && !entry->isInjected()) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700316 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
317 int32_t deviceId = motionEntry->deviceId;
318 uint32_t source = motionEntry->source;
319 if (! isAppSwitchDue
320 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
321 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
322 && deviceId == mThrottleState.lastDeviceId
323 && source == mThrottleState.lastSource) {
324 nsecs_t nextTime = mThrottleState.lastEventTime
325 + mThrottleState.minTimeBetweenEvents;
326 if (currentTime < nextTime) {
327 // Throttle it!
328#if DEBUG_THROTTLING
329 LOGD("Throttling - Delaying motion event for "
Jeff Brown90655042010-12-02 13:50:46 -0800330 "device %d, source 0x%08x by up to %0.3fms.",
Jeff Brownb88102f2010-09-08 11:49:43 -0700331 deviceId, source, (nextTime - currentTime) * 0.000001);
332#endif
333 if (nextTime < *nextWakeupTime) {
334 *nextWakeupTime = nextTime;
335 }
336 if (mThrottleState.originalSampleCount == 0) {
337 mThrottleState.originalSampleCount =
338 motionEntry->countSamples();
339 }
340 return;
341 }
342 }
343
344#if DEBUG_THROTTLING
345 if (mThrottleState.originalSampleCount != 0) {
346 uint32_t count = motionEntry->countSamples();
347 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
348 count - mThrottleState.originalSampleCount,
349 mThrottleState.originalSampleCount, count);
350 mThrottleState.originalSampleCount = 0;
351 }
352#endif
353
354 mThrottleState.lastEventTime = entry->eventTime < currentTime
355 ? entry->eventTime : currentTime;
356 mThrottleState.lastDeviceId = deviceId;
357 mThrottleState.lastSource = source;
358 }
359
360 mInboundQueue.dequeue(entry);
361 mPendingEvent = entry;
362 }
Jeff Browne2fe69e2010-10-18 13:21:23 -0700363
364 // Poke user activity for this event.
365 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
366 pokeUserActivityLocked(mPendingEvent);
367 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700368 }
369
370 // Now we have an event to dispatch.
371 assert(mPendingEvent != NULL);
Jeff Brown54a18252010-09-16 14:07:33 -0700372 bool done = false;
Jeff Brownb6997262010-10-08 22:31:17 -0700373 DropReason dropReason = DROP_REASON_NOT_DROPPED;
374 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
375 dropReason = DROP_REASON_POLICY;
376 } else if (!mDispatchEnabled) {
377 dropReason = DROP_REASON_DISABLED;
378 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700379 switch (mPendingEvent->type) {
380 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
381 ConfigurationChangedEntry* typedEntry =
382 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700383 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brownb6997262010-10-08 22:31:17 -0700384 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
Jeff Brownb88102f2010-09-08 11:49:43 -0700385 break;
386 }
387
388 case EventEntry::TYPE_KEY: {
389 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700390 if (isAppSwitchDue) {
391 if (isAppSwitchKeyEventLocked(typedEntry)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700392 resetPendingAppSwitchLocked(true);
Jeff Brownb6997262010-10-08 22:31:17 -0700393 isAppSwitchDue = false;
394 } else if (dropReason == DROP_REASON_NOT_DROPPED) {
395 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700396 }
397 }
Jeff Brownb6997262010-10-08 22:31:17 -0700398 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
Jeff Browne20c9e02010-10-11 14:20:19 -0700399 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700400 break;
401 }
402
403 case EventEntry::TYPE_MOTION: {
404 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brownb6997262010-10-08 22:31:17 -0700405 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
406 dropReason = DROP_REASON_APP_SWITCH;
Jeff Brownb88102f2010-09-08 11:49:43 -0700407 }
Jeff Brownb6997262010-10-08 22:31:17 -0700408 done = dispatchMotionLocked(currentTime, typedEntry,
Jeff Browne20c9e02010-10-11 14:20:19 -0700409 &dropReason, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700410 break;
411 }
412
413 default:
414 assert(false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700415 break;
416 }
417
Jeff Brown54a18252010-09-16 14:07:33 -0700418 if (done) {
Jeff Brownb6997262010-10-08 22:31:17 -0700419 if (dropReason != DROP_REASON_NOT_DROPPED) {
420 dropInboundEventLocked(mPendingEvent, dropReason);
421 }
422
Jeff Brown54a18252010-09-16 14:07:33 -0700423 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700424 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
425 }
426}
427
428bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
429 bool needWake = mInboundQueue.isEmpty();
430 mInboundQueue.enqueueAtTail(entry);
431
432 switch (entry->type) {
Jeff Brownb6997262010-10-08 22:31:17 -0700433 case EventEntry::TYPE_KEY: {
434 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
435 if (isAppSwitchKeyEventLocked(keyEntry)) {
436 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
437 mAppSwitchSawKeyDown = true;
438 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
439 if (mAppSwitchSawKeyDown) {
440#if DEBUG_APP_SWITCH
441 LOGD("App switch is pending!");
442#endif
443 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
444 mAppSwitchSawKeyDown = false;
445 needWake = true;
446 }
447 }
448 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700449 break;
450 }
Jeff Brownb6997262010-10-08 22:31:17 -0700451 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700452
453 return needWake;
454}
455
Jeff Brownb6997262010-10-08 22:31:17 -0700456void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
457 const char* reason;
458 switch (dropReason) {
459 case DROP_REASON_POLICY:
Jeff Browne20c9e02010-10-11 14:20:19 -0700460#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown3122e442010-10-11 23:32:49 -0700461 LOGD("Dropped event because policy consumed it.");
Jeff Browne20c9e02010-10-11 14:20:19 -0700462#endif
Jeff Brown3122e442010-10-11 23:32:49 -0700463 reason = "inbound event was dropped because the policy consumed it";
Jeff Brownb6997262010-10-08 22:31:17 -0700464 break;
465 case DROP_REASON_DISABLED:
466 LOGI("Dropped event because input dispatch is disabled.");
467 reason = "inbound event was dropped because input dispatch is disabled";
468 break;
469 case DROP_REASON_APP_SWITCH:
470 LOGI("Dropped event because of pending overdue app switch.");
471 reason = "inbound event was dropped because of pending overdue app switch";
472 break;
473 default:
474 assert(false);
475 return;
476 }
477
478 switch (entry->type) {
479 case EventEntry::TYPE_KEY:
480 synthesizeCancelationEventsForAllConnectionsLocked(
481 InputState::CANCEL_NON_POINTER_EVENTS, reason);
482 break;
483 case EventEntry::TYPE_MOTION: {
484 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
485 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
486 synthesizeCancelationEventsForAllConnectionsLocked(
487 InputState::CANCEL_POINTER_EVENTS, reason);
488 } else {
489 synthesizeCancelationEventsForAllConnectionsLocked(
490 InputState::CANCEL_NON_POINTER_EVENTS, reason);
491 }
492 break;
493 }
494 }
495}
496
497bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700498 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
499}
500
Jeff Brownb6997262010-10-08 22:31:17 -0700501bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
502 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
503 && isAppSwitchKeyCode(keyEntry->keyCode)
Jeff Browne20c9e02010-10-11 14:20:19 -0700504 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
Jeff Brownb6997262010-10-08 22:31:17 -0700505 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
506}
507
Jeff Brownb88102f2010-09-08 11:49:43 -0700508bool InputDispatcher::isAppSwitchPendingLocked() {
509 return mAppSwitchDueTime != LONG_LONG_MAX;
510}
511
Jeff Brownb88102f2010-09-08 11:49:43 -0700512void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
513 mAppSwitchDueTime = LONG_LONG_MAX;
514
515#if DEBUG_APP_SWITCH
516 if (handled) {
517 LOGD("App switch has arrived.");
518 } else {
519 LOGD("App switch was abandoned.");
520 }
521#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700522}
523
Jeff Brown9c3cda02010-06-15 01:31:58 -0700524bool InputDispatcher::runCommandsLockedInterruptible() {
525 if (mCommandQueue.isEmpty()) {
526 return false;
527 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700528
Jeff Brown9c3cda02010-06-15 01:31:58 -0700529 do {
530 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
531
532 Command command = commandEntry->command;
533 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
534
Jeff Brown7fbdc842010-06-17 20:52:56 -0700535 commandEntry->connection.clear();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700536 mAllocator.releaseCommandEntry(commandEntry);
537 } while (! mCommandQueue.isEmpty());
538 return true;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700539}
540
Jeff Brown9c3cda02010-06-15 01:31:58 -0700541InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
542 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
543 mCommandQueue.enqueueAtTail(commandEntry);
544 return commandEntry;
545}
546
Jeff Brownb88102f2010-09-08 11:49:43 -0700547void InputDispatcher::drainInboundQueueLocked() {
548 while (! mInboundQueue.isEmpty()) {
549 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700550 releaseInboundEventLocked(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700551 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700552}
553
Jeff Brown54a18252010-09-16 14:07:33 -0700554void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700555 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700556 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700557 mPendingEvent = NULL;
558 }
559}
560
Jeff Brown54a18252010-09-16 14:07:33 -0700561void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700562 InjectionState* injectionState = entry->injectionState;
563 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700564#if DEBUG_DISPATCH_CYCLE
Jeff Brown01ce2e92010-09-26 22:20:12 -0700565 LOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700566#endif
567 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
568 }
569 mAllocator.releaseEventEntry(entry);
570}
571
Jeff Brownb88102f2010-09-08 11:49:43 -0700572void InputDispatcher::resetKeyRepeatLocked() {
573 if (mKeyRepeatState.lastKeyEntry) {
574 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
575 mKeyRepeatState.lastKeyEntry = NULL;
576 }
577}
578
579InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brownb21fb102010-09-07 10:44:57 -0700580 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown349703e2010-06-22 01:27:15 -0700581 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
582
Jeff Brown349703e2010-06-22 01:27:15 -0700583 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Browne20c9e02010-10-11 14:20:19 -0700584 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
585 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700586 if (entry->refCount == 1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700587 mAllocator.recycleKeyEntry(entry);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700588 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700589 entry->policyFlags = policyFlags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700590 entry->repeatCount += 1;
591 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700592 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700593 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700594 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700595 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700596
597 mKeyRepeatState.lastKeyEntry = newEntry;
598 mAllocator.releaseKeyEntry(entry);
599
600 entry = newEntry;
601 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700602 entry->syntheticRepeat = true;
603
604 // Increment reference count since we keep a reference to the event in
605 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
606 entry->refCount += 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700607
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700608 if (entry->repeatCount == 1) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700609 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700610 }
611
Jeff Brownb21fb102010-09-07 10:44:57 -0700612 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700613 return entry;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700614}
615
Jeff Brownb88102f2010-09-08 11:49:43 -0700616bool InputDispatcher::dispatchConfigurationChangedLocked(
617 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700618#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownb88102f2010-09-08 11:49:43 -0700619 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
620#endif
621
622 // Reset key repeating in case a keyboard device was added or removed or something.
623 resetKeyRepeatLocked();
624
625 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
626 CommandEntry* commandEntry = postCommandLocked(
627 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
628 commandEntry->eventTime = entry->eventTime;
629 return true;
630}
631
632bool InputDispatcher::dispatchKeyLocked(
633 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Browne20c9e02010-10-11 14:20:19 -0700634 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700635 // Preprocessing.
636 if (! entry->dispatchInProgress) {
637 if (entry->repeatCount == 0
638 && entry->action == AKEY_EVENT_ACTION_DOWN
639 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
640 && !entry->isInjected()) {
641 if (mKeyRepeatState.lastKeyEntry
642 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
643 // We have seen two identical key downs in a row which indicates that the device
644 // driver is automatically generating key repeats itself. We take note of the
645 // repeat here, but we disable our own next key repeat timer since it is clear that
646 // we will not need to synthesize key repeats ourselves.
647 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
648 resetKeyRepeatLocked();
649 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
650 } else {
651 // Not a repeat. Save key down state in case we do see a repeat later.
652 resetKeyRepeatLocked();
653 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
654 }
655 mKeyRepeatState.lastKeyEntry = entry;
656 entry->refCount += 1;
657 } else if (! entry->syntheticRepeat) {
658 resetKeyRepeatLocked();
659 }
660
661 entry->dispatchInProgress = true;
662 resetTargetsLocked();
663
664 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
665 }
666
Jeff Brown54a18252010-09-16 14:07:33 -0700667 // Give the policy a chance to intercept the key.
668 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700669 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Jeff Brown54a18252010-09-16 14:07:33 -0700670 CommandEntry* commandEntry = postCommandLocked(
671 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Jeff Browne20c9e02010-10-11 14:20:19 -0700672 if (mFocusedWindow) {
Jeff Brown54a18252010-09-16 14:07:33 -0700673 commandEntry->inputChannel = mFocusedWindow->inputChannel;
674 }
675 commandEntry->keyEntry = entry;
676 entry->refCount += 1;
677 return false; // wait for the command to run
678 } else {
679 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
680 }
681 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Jeff Browne20c9e02010-10-11 14:20:19 -0700682 if (*dropReason == DROP_REASON_NOT_DROPPED) {
683 *dropReason = DROP_REASON_POLICY;
684 }
Jeff Brown54a18252010-09-16 14:07:33 -0700685 }
686
687 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700688 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700689 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700690 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
691 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700692 return true;
693 }
694
Jeff Brownb88102f2010-09-08 11:49:43 -0700695 // Identify targets.
696 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700697 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
698 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700699 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
700 return false;
701 }
702
703 setInjectionResultLocked(entry, injectionResult);
704 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
705 return true;
706 }
707
708 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700709 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700710 }
711
712 // Dispatch the key.
713 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700714 return true;
715}
716
717void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
718#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800719 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brownb88102f2010-09-08 11:49:43 -0700720 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
Jeff Browne46a0a42010-11-02 17:58:22 -0700721 "repeatCount=%d, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700722 prefix,
723 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
724 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
Jeff Browne46a0a42010-11-02 17:58:22 -0700725 entry->repeatCount, entry->downTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700726#endif
727}
728
729bool InputDispatcher::dispatchMotionLocked(
Jeff Browne20c9e02010-10-11 14:20:19 -0700730 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
Jeff Browne46a0a42010-11-02 17:58:22 -0700731 // Preprocessing.
732 if (! entry->dispatchInProgress) {
733 entry->dispatchInProgress = true;
734 resetTargetsLocked();
735
736 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
737 }
738
Jeff Brown54a18252010-09-16 14:07:33 -0700739 // Clean up if dropping the event.
Jeff Browne20c9e02010-10-11 14:20:19 -0700740 if (*dropReason != DROP_REASON_NOT_DROPPED) {
Jeff Brown54a18252010-09-16 14:07:33 -0700741 resetTargetsLocked();
Jeff Brown3122e442010-10-11 23:32:49 -0700742 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
743 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
Jeff Brown54a18252010-09-16 14:07:33 -0700744 return true;
745 }
746
Jeff Brownb88102f2010-09-08 11:49:43 -0700747 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
748
749 // Identify targets.
750 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700751 int32_t injectionResult;
752 if (isPointerEvent) {
753 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700754 injectionResult = findTouchedWindowTargetsLocked(currentTime,
755 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700756 } else {
757 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700758 injectionResult = findFocusedWindowTargetsLocked(currentTime,
759 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700760 }
761 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
762 return false;
763 }
764
765 setInjectionResultLocked(entry, injectionResult);
766 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
767 return true;
768 }
769
770 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700771 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700772 }
773
774 // Dispatch the motion.
775 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700776 return true;
777}
778
779
780void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
781#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -0800782 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700783 "action=0x%x, flags=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700784 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700785 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700786 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
787 entry->action, entry->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700788 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
789 entry->downTime);
790
791 // Print the most recent sample that we have available, this may change due to batching.
792 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700793 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700794 for (; sample->next != NULL; sample = sample->next) {
795 sampleCount += 1;
796 }
797 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -0700798 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700799 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700800 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700801 i, entry->pointerIds[i],
Jeff Brown8d608662010-08-30 03:02:23 -0700802 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
803 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
804 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
805 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
806 sample->pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700807 }
808
809 // Keep in mind that due to batching, it is possible for the number of samples actually
810 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700811 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700812 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
813 }
814#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700815}
816
817void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
818 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
819#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -0700820 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700821 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700822 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700823#endif
824
Jeff Brown9c3cda02010-06-15 01:31:58 -0700825 assert(eventEntry->dispatchInProgress); // should already have been set to true
826
Jeff Browne2fe69e2010-10-18 13:21:23 -0700827 pokeUserActivityLocked(eventEntry);
828
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700829 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
830 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
831
Jeff Brown519e0242010-09-15 15:18:56 -0700832 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700833 if (connectionIndex >= 0) {
834 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700835 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700836 resumeWithAppendedMotionSample);
837 } else {
Jeff Brownb6997262010-10-08 22:31:17 -0700838#if DEBUG_FOCUS
839 LOGD("Dropping event delivery to target with channel '%s' because it "
840 "is no longer registered with the input dispatcher.",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700841 inputTarget.inputChannel->getName().string());
Jeff Brownb6997262010-10-08 22:31:17 -0700842#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700843 }
844 }
845}
846
Jeff Brown54a18252010-09-16 14:07:33 -0700847void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700848 mCurrentInputTargetsValid = false;
849 mCurrentInputTargets.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700850 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
851}
852
Jeff Brown01ce2e92010-09-26 22:20:12 -0700853void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700854 mCurrentInputTargetsValid = true;
855}
856
857int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
858 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
859 nsecs_t* nextWakeupTime) {
860 if (application == NULL && window == NULL) {
861 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
862#if DEBUG_FOCUS
863 LOGD("Waiting for system to become ready for input.");
864#endif
865 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
866 mInputTargetWaitStartTime = currentTime;
867 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
868 mInputTargetWaitTimeoutExpired = false;
869 }
870 } else {
871 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
872#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700873 LOGD("Waiting for application to become ready for input: %s",
874 getApplicationWindowLabelLocked(application, window).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700875#endif
876 nsecs_t timeout = window ? window->dispatchingTimeout :
877 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
878
879 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
880 mInputTargetWaitStartTime = currentTime;
881 mInputTargetWaitTimeoutTime = currentTime + timeout;
882 mInputTargetWaitTimeoutExpired = false;
883 }
884 }
885
886 if (mInputTargetWaitTimeoutExpired) {
887 return INPUT_EVENT_INJECTION_TIMED_OUT;
888 }
889
890 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown519e0242010-09-15 15:18:56 -0700891 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700892
893 // Force poll loop to wake up immediately on next iteration once we get the
894 // ANR response back from the policy.
895 *nextWakeupTime = LONG_LONG_MIN;
896 return INPUT_EVENT_INJECTION_PENDING;
897 } else {
898 // Force poll loop to wake up when timeout is due.
899 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
900 *nextWakeupTime = mInputTargetWaitTimeoutTime;
901 }
902 return INPUT_EVENT_INJECTION_PENDING;
903 }
904}
905
Jeff Brown519e0242010-09-15 15:18:56 -0700906void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
907 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700908 if (newTimeout > 0) {
909 // Extend the timeout.
910 mInputTargetWaitTimeoutTime = now() + newTimeout;
911 } else {
912 // Give up.
913 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -0700914
Jeff Brown01ce2e92010-09-26 22:20:12 -0700915 // Release the touch targets.
916 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -0700917
Jeff Brown519e0242010-09-15 15:18:56 -0700918 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -0700919 if (inputChannel.get()) {
920 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
921 if (connectionIndex >= 0) {
922 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown00045a72010-12-09 18:10:30 -0800923 if (connection->status == Connection::STATUS_NORMAL) {
924 synthesizeCancelationEventsForConnectionLocked(
925 connection, InputState::CANCEL_ALL_EVENTS,
926 "application not responding");
927 }
Jeff Browndc3e0052010-09-16 11:02:16 -0700928 }
Jeff Brown519e0242010-09-15 15:18:56 -0700929 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700930 }
931}
932
Jeff Brown519e0242010-09-15 15:18:56 -0700933nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -0700934 nsecs_t currentTime) {
935 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
936 return currentTime - mInputTargetWaitStartTime;
937 }
938 return 0;
939}
940
941void InputDispatcher::resetANRTimeoutsLocked() {
942#if DEBUG_FOCUS
943 LOGD("Resetting ANR timeouts.");
944#endif
945
Jeff Brownb88102f2010-09-08 11:49:43 -0700946 // Reset input target wait timeout.
947 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
948}
949
Jeff Brown01ce2e92010-09-26 22:20:12 -0700950int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
951 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700952 mCurrentInputTargets.clear();
953
954 int32_t injectionResult;
955
956 // If there is no currently focused window and no focused application
957 // then drop the event.
958 if (! mFocusedWindow) {
959 if (mFocusedApplication) {
960#if DEBUG_FOCUS
961 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -0700962 "focused application that may eventually add a window: %s.",
963 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700964#endif
965 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
966 mFocusedApplication, NULL, nextWakeupTime);
967 goto Unresponsive;
968 }
969
970 LOGI("Dropping event because there is no focused window or focused application.");
971 injectionResult = INPUT_EVENT_INJECTION_FAILED;
972 goto Failed;
973 }
974
975 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700976 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700977 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
978 goto Failed;
979 }
980
981 // If the currently focused window is paused then keep waiting.
982 if (mFocusedWindow->paused) {
983#if DEBUG_FOCUS
984 LOGD("Waiting because focused window is paused.");
985#endif
986 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
987 mFocusedApplication, mFocusedWindow, nextWakeupTime);
988 goto Unresponsive;
989 }
990
Jeff Brown519e0242010-09-15 15:18:56 -0700991 // If the currently focused window is still working on previous events then keep waiting.
992 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
993#if DEBUG_FOCUS
994 LOGD("Waiting because focused window still processing previous input.");
995#endif
996 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
997 mFocusedApplication, mFocusedWindow, nextWakeupTime);
998 goto Unresponsive;
999 }
1000
Jeff Brownb88102f2010-09-08 11:49:43 -07001001 // Success! Output targets.
1002 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001003 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001004
1005 // Done.
1006Failed:
1007Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001008 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1009 updateDispatchStatisticsLocked(currentTime, entry,
1010 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001011#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -07001012 LOGD("findFocusedWindow finished: injectionResult=%d, "
1013 "timeSpendWaitingForApplication=%0.1fms",
1014 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001015#endif
1016 return injectionResult;
1017}
1018
Jeff Brown01ce2e92010-09-26 22:20:12 -07001019int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1020 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001021 enum InjectionPermission {
1022 INJECTION_PERMISSION_UNKNOWN,
1023 INJECTION_PERMISSION_GRANTED,
1024 INJECTION_PERMISSION_DENIED
1025 };
1026
Jeff Brownb88102f2010-09-08 11:49:43 -07001027 mCurrentInputTargets.clear();
1028
1029 nsecs_t startTime = now();
1030
1031 // For security reasons, we defer updating the touch state until we are sure that
1032 // event injection will be allowed.
1033 //
1034 // FIXME In the original code, screenWasOff could never be set to true.
1035 // The reason is that the POLICY_FLAG_WOKE_HERE
1036 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1037 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
1038 // actually enqueued using the policyFlags that appeared in the final EV_SYN
1039 // events upon which no preprocessing took place. So policyFlags was always 0.
1040 // In the new native input dispatcher we're a bit more careful about event
1041 // preprocessing so the touches we receive can actually have non-zero policyFlags.
1042 // Unfortunately we obtain undesirable behavior.
1043 //
1044 // Here's what happens:
1045 //
1046 // When the device dims in anticipation of going to sleep, touches
1047 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1048 // the device to brighten and reset the user activity timer.
1049 // Touches on other windows (such as the launcher window)
1050 // are dropped. Then after a moment, the device goes to sleep. Oops.
1051 //
1052 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1053 // instead of POLICY_FLAG_WOKE_HERE...
1054 //
1055 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1056
1057 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001058 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001059
1060 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001061 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1062 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Jeff Brown95712852011-01-04 19:41:59 -08001063 bool isSplit, wrongDevice;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001064 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1065 mTempTouchState.reset();
1066 mTempTouchState.down = true;
Jeff Brown95712852011-01-04 19:41:59 -08001067 mTempTouchState.deviceId = entry->deviceId;
1068 isSplit = false;
1069 wrongDevice = false;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001070 } else {
1071 mTempTouchState.copyFrom(mTouchState);
Jeff Brown95712852011-01-04 19:41:59 -08001072 isSplit = mTempTouchState.split;
1073 wrongDevice = mTempTouchState.down && mTempTouchState.deviceId != entry->deviceId;
1074 if (wrongDevice) {
1075#if DEBUG_INPUT_DISPATCHER_POLICY
1076 LOGD("Dropping event because a pointer for a different device is already down.");
1077#endif
1078 injectionResult = INPUT_EVENT_INJECTION_FAILED;
1079 goto Failed;
1080 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001081 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001082
Jeff Brown01ce2e92010-09-26 22:20:12 -07001083 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1084 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1085 /* Case 1: New splittable pointer going down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001086
Jeff Brown01ce2e92010-09-26 22:20:12 -07001087 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1088 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1089 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1090 const InputWindow* newTouchedWindow = NULL;
1091 const InputWindow* topErrorWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07001092
1093 // Traverse windows from front to back to find touched window and outside targets.
1094 size_t numWindows = mWindows.size();
1095 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001096 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001097 int32_t flags = window->layoutParamsFlags;
1098
1099 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1100 if (! topErrorWindow) {
1101 topErrorWindow = window;
1102 }
1103 }
1104
1105 if (window->visible) {
1106 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1107 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1108 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1109 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1110 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1111 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001112 }
1113 break; // found touched window, exit window loop
1114 }
1115 }
1116
Jeff Brown01ce2e92010-09-26 22:20:12 -07001117 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1118 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001119 int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
1120 if (isWindowObscuredAtPointLocked(window, x, y)) {
1121 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1122 }
1123
1124 mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001125 }
1126 }
1127 }
1128
1129 // If there is an error window but it is not taking focus (typically because
1130 // it is invisible) then wait for it. Any other focused window may in
1131 // fact be in ANR state.
1132 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1133#if DEBUG_FOCUS
1134 LOGD("Waiting because system error window is pending.");
1135#endif
1136 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1137 NULL, NULL, nextWakeupTime);
1138 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1139 goto Unresponsive;
1140 }
1141
Jeff Brown01ce2e92010-09-26 22:20:12 -07001142 // Figure out whether splitting will be allowed for this window.
Jeff Brown46e75292010-11-10 16:53:45 -08001143 if (newTouchedWindow && newTouchedWindow->supportsSplitTouch()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001144 // New window supports splitting.
1145 isSplit = true;
1146 } else if (isSplit) {
1147 // New window does not support splitting but we have already split events.
1148 // Assign the pointer to the first foreground window we find.
1149 // (May be NULL which is why we put this code block before the next check.)
1150 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1151 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001152
Jeff Brownb88102f2010-09-08 11:49:43 -07001153 // If we did not find a touched window then fail.
1154 if (! newTouchedWindow) {
1155 if (mFocusedApplication) {
1156#if DEBUG_FOCUS
1157 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001158 "focused application that may eventually add a new window: %s.",
1159 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001160#endif
1161 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1162 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001163 goto Unresponsive;
1164 }
1165
1166 LOGI("Dropping event because there is no touched window or focused application.");
1167 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001168 goto Failed;
1169 }
1170
Jeff Brown19dfc832010-10-05 12:26:23 -07001171 // Set target flags.
1172 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1173 if (isSplit) {
1174 targetFlags |= InputTarget::FLAG_SPLIT;
1175 }
1176 if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
1177 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1178 }
1179
Jeff Brown01ce2e92010-09-26 22:20:12 -07001180 // Update the temporary touch state.
1181 BitSet32 pointerIds;
1182 if (isSplit) {
1183 uint32_t pointerId = entry->pointerIds[pointerIndex];
1184 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001185 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001186 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001187 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001188 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001189
1190 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001191 if (! mTempTouchState.down) {
Jeff Brown76860e32010-10-25 17:37:46 -07001192#if DEBUG_INPUT_DISPATCHER_POLICY
1193 LOGD("Dropping event because the pointer is not down or we previously "
1194 "dropped the pointer down event.");
1195#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001196 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001197 goto Failed;
1198 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001199 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001200
Jeff Brown01ce2e92010-09-26 22:20:12 -07001201 // Check permission to inject into all touched foreground windows and ensure there
1202 // is at least one touched foreground window.
1203 {
1204 bool haveForegroundWindow = false;
1205 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1206 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1207 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1208 haveForegroundWindow = true;
1209 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1210 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1211 injectionPermission = INJECTION_PERMISSION_DENIED;
1212 goto Failed;
1213 }
1214 }
1215 }
1216 if (! haveForegroundWindow) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001217#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown01ce2e92010-09-26 22:20:12 -07001218 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001219#endif
1220 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001221 goto Failed;
1222 }
1223
Jeff Brown01ce2e92010-09-26 22:20:12 -07001224 // Permission granted to injection into all touched foreground windows.
1225 injectionPermission = INJECTION_PERMISSION_GRANTED;
1226 }
Jeff Brown519e0242010-09-15 15:18:56 -07001227
Jeff Brown01ce2e92010-09-26 22:20:12 -07001228 // Ensure all touched foreground windows are ready for new input.
1229 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1230 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1231 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1232 // If the touched window is paused then keep waiting.
1233 if (touchedWindow.window->paused) {
1234#if DEBUG_INPUT_DISPATCHER_POLICY
1235 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001236#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001237 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1238 NULL, touchedWindow.window, nextWakeupTime);
1239 goto Unresponsive;
1240 }
1241
1242 // If the touched window is still working on previous events then keep waiting.
1243 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1244#if DEBUG_FOCUS
1245 LOGD("Waiting because touched window still processing previous input.");
1246#endif
1247 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1248 NULL, touchedWindow.window, nextWakeupTime);
1249 goto Unresponsive;
1250 }
1251 }
1252 }
1253
1254 // If this is the first pointer going down and the touched window has a wallpaper
1255 // then also add the touched wallpaper windows so they are locked in for the duration
1256 // of the touch gesture.
1257 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1258 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1259 if (foregroundWindow->hasWallpaper) {
1260 for (size_t i = 0; i < mWindows.size(); i++) {
1261 const InputWindow* window = & mWindows[i];
1262 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
Jeff Brown19dfc832010-10-05 12:26:23 -07001263 mTempTouchState.addOrUpdateWindow(window,
1264 InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
Jeff Brown01ce2e92010-09-26 22:20:12 -07001265 }
1266 }
1267 }
1268 }
1269
Jeff Brownb88102f2010-09-08 11:49:43 -07001270 // Success! Output targets.
1271 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001272
Jeff Brown01ce2e92010-09-26 22:20:12 -07001273 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1274 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1275 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1276 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001277 }
1278
Jeff Brown01ce2e92010-09-26 22:20:12 -07001279 // Drop the outside touch window since we will not care about them in the next iteration.
1280 mTempTouchState.removeOutsideTouchWindows();
1281
Jeff Brownb88102f2010-09-08 11:49:43 -07001282Failed:
1283 // Check injection permission once and for all.
1284 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001285 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001286 injectionPermission = INJECTION_PERMISSION_GRANTED;
1287 } else {
1288 injectionPermission = INJECTION_PERMISSION_DENIED;
1289 }
1290 }
1291
1292 // Update final pieces of touch state if the injector had permission.
1293 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown95712852011-01-04 19:41:59 -08001294 if (!wrongDevice) {
1295 if (maskedAction == AMOTION_EVENT_ACTION_UP
1296 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1297 // All pointers up or canceled.
1298 mTempTouchState.reset();
1299 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1300 // First pointer went down.
1301 if (mTouchState.down) {
Jeff Brownb6997262010-10-08 22:31:17 -07001302#if DEBUG_FOCUS
Jeff Brown95712852011-01-04 19:41:59 -08001303 LOGD("Pointer down received while already down.");
Jeff Brownb6997262010-10-08 22:31:17 -07001304#endif
Jeff Brown95712852011-01-04 19:41:59 -08001305 }
1306 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1307 // One pointer went up.
1308 if (isSplit) {
1309 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1310 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001311
Jeff Brown95712852011-01-04 19:41:59 -08001312 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1313 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1314 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1315 touchedWindow.pointerIds.clearBit(pointerId);
1316 if (touchedWindow.pointerIds.isEmpty()) {
1317 mTempTouchState.windows.removeAt(i);
1318 continue;
1319 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001320 }
Jeff Brown95712852011-01-04 19:41:59 -08001321 i += 1;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001322 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001323 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001324 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001325
Jeff Brown95712852011-01-04 19:41:59 -08001326 // Save changes to touch state.
1327 mTouchState.copyFrom(mTempTouchState);
1328 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001329 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001330#if DEBUG_FOCUS
1331 LOGD("Not updating touch focus because injection was denied.");
1332#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001333 }
1334
1335Unresponsive:
Jeff Brown120a4592010-10-27 18:43:51 -07001336 // Reset temporary touch state to ensure we release unnecessary references to input channels.
1337 mTempTouchState.reset();
1338
Jeff Brown519e0242010-09-15 15:18:56 -07001339 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1340 updateDispatchStatisticsLocked(currentTime, entry,
1341 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001342#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001343 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1344 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001345 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001346#endif
1347 return injectionResult;
1348}
1349
Jeff Brown01ce2e92010-09-26 22:20:12 -07001350void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1351 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001352 mCurrentInputTargets.push();
1353
1354 InputTarget& target = mCurrentInputTargets.editTop();
1355 target.inputChannel = window->inputChannel;
1356 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001357 target.xOffset = - window->frameLeft;
1358 target.yOffset = - window->frameTop;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001359 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001360}
1361
1362void InputDispatcher::addMonitoringTargetsLocked() {
1363 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1364 mCurrentInputTargets.push();
1365
1366 InputTarget& target = mCurrentInputTargets.editTop();
1367 target.inputChannel = mMonitoringChannels[i];
1368 target.flags = 0;
Jeff Brownb88102f2010-09-08 11:49:43 -07001369 target.xOffset = 0;
1370 target.yOffset = 0;
1371 }
1372}
1373
1374bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001375 const InjectionState* injectionState) {
1376 if (injectionState
Jeff Brownb6997262010-10-08 22:31:17 -07001377 && (window == NULL || window->ownerUid != injectionState->injectorUid)
1378 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1379 if (window) {
1380 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1381 "with input channel %s owned by uid %d",
1382 injectionState->injectorPid, injectionState->injectorUid,
1383 window->inputChannel->getName().string(),
1384 window->ownerUid);
1385 } else {
1386 LOGW("Permission denied: injecting event from pid %d uid %d",
1387 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001388 }
Jeff Brownb6997262010-10-08 22:31:17 -07001389 return false;
Jeff Brownb88102f2010-09-08 11:49:43 -07001390 }
1391 return true;
1392}
1393
Jeff Brown19dfc832010-10-05 12:26:23 -07001394bool InputDispatcher::isWindowObscuredAtPointLocked(
1395 const InputWindow* window, int32_t x, int32_t y) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07001396 size_t numWindows = mWindows.size();
1397 for (size_t i = 0; i < numWindows; i++) {
1398 const InputWindow* other = & mWindows.itemAt(i);
1399 if (other == window) {
1400 break;
1401 }
Jeff Brown19dfc832010-10-05 12:26:23 -07001402 if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001403 return true;
1404 }
1405 }
1406 return false;
1407}
1408
Jeff Brown519e0242010-09-15 15:18:56 -07001409bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1410 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1411 if (connectionIndex >= 0) {
1412 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1413 return connection->outboundQueue.isEmpty();
1414 } else {
1415 return true;
1416 }
1417}
1418
1419String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1420 const InputWindow* window) {
1421 if (application) {
1422 if (window) {
1423 String8 label(application->name);
1424 label.append(" - ");
1425 label.append(window->name);
1426 return label;
1427 } else {
1428 return application->name;
1429 }
1430 } else if (window) {
1431 return window->name;
1432 } else {
1433 return String8("<unknown application or window>");
1434 }
1435}
1436
Jeff Browne2fe69e2010-10-18 13:21:23 -07001437void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1438 int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brown4d396052010-10-29 21:50:21 -07001439 switch (eventEntry->type) {
1440 case EventEntry::TYPE_MOTION: {
Jeff Browne2fe69e2010-10-18 13:21:23 -07001441 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
Jeff Brown4d396052010-10-29 21:50:21 -07001442 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1443 return;
1444 }
1445
Jeff Browne2fe69e2010-10-18 13:21:23 -07001446 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
Joe Onorato1a542c72010-11-08 09:48:20 -08001447 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001448 }
Jeff Brown4d396052010-10-29 21:50:21 -07001449 break;
1450 }
1451 case EventEntry::TYPE_KEY: {
1452 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1453 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1454 return;
1455 }
1456 break;
1457 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001458 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001459
Jeff Brownb88102f2010-09-08 11:49:43 -07001460 CommandEntry* commandEntry = postCommandLocked(
1461 & InputDispatcher::doPokeUserActivityLockedInterruptible);
Jeff Browne2fe69e2010-10-18 13:21:23 -07001462 commandEntry->eventTime = eventEntry->eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001463 commandEntry->userActivityEventType = eventType;
1464}
1465
Jeff Brown7fbdc842010-06-17 20:52:56 -07001466void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1467 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001468 bool resumeWithAppendedMotionSample) {
1469#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001470 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001471 "xOffset=%f, yOffset=%f, "
Jeff Brown83c09682010-12-23 17:50:18 -08001472 "pointerIds=0x%x, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001473 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001474 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001475 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brown83c09682010-12-23 17:50:18 -08001476 inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001477 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001478#endif
1479
Jeff Brown01ce2e92010-09-26 22:20:12 -07001480 // Make sure we are never called for streaming when splitting across multiple windows.
1481 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1482 assert(! (resumeWithAppendedMotionSample && isSplit));
1483
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001484 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001485 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001486 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb6997262010-10-08 22:31:17 -07001487#if DEBUG_DISPATCH_CYCLE
1488 LOGD("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001489 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brownb6997262010-10-08 22:31:17 -07001490#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001491 return;
1492 }
1493
Jeff Brown01ce2e92010-09-26 22:20:12 -07001494 // Split a motion event if needed.
1495 if (isSplit) {
1496 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1497
1498 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1499 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1500 MotionEntry* splitMotionEntry = splitMotionEvent(
1501 originalMotionEntry, inputTarget->pointerIds);
1502#if DEBUG_FOCUS
1503 LOGD("channel '%s' ~ Split motion event.",
1504 connection->getInputChannelName());
1505 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1506#endif
1507 eventEntry = splitMotionEntry;
1508 }
1509 }
1510
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001511 // Resume the dispatch cycle with a freshly appended motion sample.
1512 // First we check that the last dispatch entry in the outbound queue is for the same
1513 // motion event to which we appended the motion sample. If we find such a dispatch
1514 // entry, and if it is currently in progress then we try to stream the new sample.
1515 bool wasEmpty = connection->outboundQueue.isEmpty();
1516
1517 if (! wasEmpty && resumeWithAppendedMotionSample) {
1518 DispatchEntry* motionEventDispatchEntry =
1519 connection->findQueuedDispatchEntryForEvent(eventEntry);
1520 if (motionEventDispatchEntry) {
1521 // If the dispatch entry is not in progress, then we must be busy dispatching an
1522 // earlier event. Not a problem, the motion event is on the outbound queue and will
1523 // be dispatched later.
1524 if (! motionEventDispatchEntry->inProgress) {
1525#if DEBUG_BATCHING
1526 LOGD("channel '%s' ~ Not streaming because the motion event has "
1527 "not yet been dispatched. "
1528 "(Waiting for earlier events to be consumed.)",
1529 connection->getInputChannelName());
1530#endif
1531 return;
1532 }
1533
1534 // If the dispatch entry is in progress but it already has a tail of pending
1535 // motion samples, then it must mean that the shared memory buffer filled up.
1536 // Not a problem, when this dispatch cycle is finished, we will eventually start
1537 // a new dispatch cycle to process the tail and that tail includes the newly
1538 // appended motion sample.
1539 if (motionEventDispatchEntry->tailMotionSample) {
1540#if DEBUG_BATCHING
1541 LOGD("channel '%s' ~ Not streaming because no new samples can "
1542 "be appended to the motion event in this dispatch cycle. "
1543 "(Waiting for next dispatch cycle to start.)",
1544 connection->getInputChannelName());
1545#endif
1546 return;
1547 }
1548
1549 // The dispatch entry is in progress and is still potentially open for streaming.
1550 // Try to stream the new motion sample. This might fail if the consumer has already
1551 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001552 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1553 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001554 status_t status = connection->inputPublisher.appendMotionSample(
1555 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1556 if (status == OK) {
1557#if DEBUG_BATCHING
1558 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1559 connection->getInputChannelName());
1560#endif
1561 return;
1562 }
1563
1564#if DEBUG_BATCHING
1565 if (status == NO_MEMORY) {
1566 LOGD("channel '%s' ~ Could not append motion sample to currently "
1567 "dispatched move event because the shared memory buffer is full. "
1568 "(Waiting for next dispatch cycle to start.)",
1569 connection->getInputChannelName());
1570 } else if (status == status_t(FAILED_TRANSACTION)) {
1571 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001572 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001573 "(Waiting for next dispatch cycle to start.)",
1574 connection->getInputChannelName());
1575 } else {
1576 LOGD("channel '%s' ~ Could not append motion sample to currently "
1577 "dispatched move event due to an error, status=%d. "
1578 "(Waiting for next dispatch cycle to start.)",
1579 connection->getInputChannelName(), status);
1580 }
1581#endif
1582 // Failed to stream. Start a new tail of pending motion samples to dispatch
1583 // in the next cycle.
1584 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1585 return;
1586 }
1587 }
1588
1589 // This is a new event.
1590 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001591 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown519e0242010-09-15 15:18:56 -07001592 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1593 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001594 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001595 }
1596
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001597 // Handle the case where we could not stream a new motion sample because the consumer has
1598 // already consumed the motion event (otherwise the corresponding dispatch entry would
1599 // still be in the outbound queue for this connection). We set the head motion sample
1600 // to the list starting with the newly appended motion sample.
1601 if (resumeWithAppendedMotionSample) {
1602#if DEBUG_BATCHING
1603 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1604 "that cannot be streamed because the motion event has already been consumed.",
1605 connection->getInputChannelName());
1606#endif
1607 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1608 dispatchEntry->headMotionSample = appendedMotionSample;
1609 }
1610
1611 // Enqueue the dispatch entry.
1612 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1613
1614 // If the outbound queue was previously empty, start the dispatch cycle going.
1615 if (wasEmpty) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001616 activateConnectionLocked(connection.get());
Jeff Brown519e0242010-09-15 15:18:56 -07001617 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001618 }
1619}
1620
Jeff Brown7fbdc842010-06-17 20:52:56 -07001621void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001622 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001623#if DEBUG_DISPATCH_CYCLE
1624 LOGD("channel '%s' ~ startDispatchCycle",
1625 connection->getInputChannelName());
1626#endif
1627
1628 assert(connection->status == Connection::STATUS_NORMAL);
1629 assert(! connection->outboundQueue.isEmpty());
1630
Jeff Brownb88102f2010-09-08 11:49:43 -07001631 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001632 assert(! dispatchEntry->inProgress);
1633
Jeff Brownb88102f2010-09-08 11:49:43 -07001634 // Mark the dispatch entry as in progress.
1635 dispatchEntry->inProgress = true;
1636
1637 // Update the connection's input state.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001638 EventEntry* eventEntry = dispatchEntry->eventEntry;
1639 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001640
1641#if FILTER_INPUT_EVENTS
1642 // Filter out inconsistent sequences of input events.
1643 // The input system may drop or inject events in a way that could violate implicit
1644 // invariants on input state and potentially cause an application to crash
1645 // or think that a key or pointer is stuck down. Technically we make no guarantees
1646 // of consistency but it would be nice to improve on this where possible.
1647 // XXX: This code is a proof of concept only. Not ready for prime time.
1648 if (consistency == InputState::TOLERABLE) {
1649#if DEBUG_DISPATCH_CYCLE
1650 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1651 "current input state but that is likely to be tolerated by the application.",
1652 connection->getInputChannelName());
1653#endif
1654 } else if (consistency == InputState::BROKEN) {
1655 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1656 "current input state and that is likely to cause the application to crash.",
1657 connection->getInputChannelName());
1658 startNextDispatchCycleLocked(currentTime, connection);
1659 return;
1660 }
1661#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001662
1663 // Publish the event.
1664 status_t status;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001665 switch (eventEntry->type) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001666 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001667 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001668
1669 // Apply target flags.
1670 int32_t action = keyEntry->action;
1671 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001672
1673 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001674 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001675 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1676 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1677 keyEntry->eventTime);
1678
1679 if (status) {
1680 LOGE("channel '%s' ~ Could not publish key event, "
1681 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001682 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001683 return;
1684 }
1685 break;
1686 }
1687
1688 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001689 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001690
1691 // Apply target flags.
1692 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001693 int32_t flags = motionEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001694 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001695 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001696 }
Jeff Brown85a31762010-09-01 17:01:00 -07001697 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1698 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1699 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001700
1701 // If headMotionSample is non-NULL, then it points to the first new sample that we
1702 // were unable to dispatch during the previous cycle so we resume dispatching from
1703 // that point in the list of motion samples.
1704 // Otherwise, we just start from the first sample of the motion event.
1705 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1706 if (! firstMotionSample) {
1707 firstMotionSample = & motionEntry->firstSample;
1708 }
1709
Jeff Brownd3616592010-07-16 17:21:06 -07001710 // Set the X and Y offset depending on the input source.
1711 float xOffset, yOffset;
1712 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1713 xOffset = dispatchEntry->xOffset;
1714 yOffset = dispatchEntry->yOffset;
1715 } else {
1716 xOffset = 0.0f;
1717 yOffset = 0.0f;
1718 }
1719
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001720 // Publish the motion event and the first motion sample.
1721 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07001722 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownd3616592010-07-16 17:21:06 -07001723 xOffset, yOffset,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001724 motionEntry->xPrecision, motionEntry->yPrecision,
1725 motionEntry->downTime, firstMotionSample->eventTime,
1726 motionEntry->pointerCount, motionEntry->pointerIds,
1727 firstMotionSample->pointerCoords);
1728
1729 if (status) {
1730 LOGE("channel '%s' ~ Could not publish motion event, "
1731 "status=%d", connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001732 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001733 return;
1734 }
1735
1736 // Append additional motion samples.
1737 MotionSample* nextMotionSample = firstMotionSample->next;
1738 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1739 status = connection->inputPublisher.appendMotionSample(
1740 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1741 if (status == NO_MEMORY) {
1742#if DEBUG_DISPATCH_CYCLE
1743 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1744 "be sent in the next dispatch cycle.",
1745 connection->getInputChannelName());
1746#endif
1747 break;
1748 }
1749 if (status != OK) {
1750 LOGE("channel '%s' ~ Could not append motion sample "
1751 "for a reason other than out of memory, status=%d",
1752 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001753 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001754 return;
1755 }
1756 }
1757
1758 // Remember the next motion sample that we could not dispatch, in case we ran out
1759 // of space in the shared memory buffer.
1760 dispatchEntry->tailMotionSample = nextMotionSample;
1761 break;
1762 }
1763
1764 default: {
1765 assert(false);
1766 }
1767 }
1768
1769 // Send the dispatch signal.
1770 status = connection->inputPublisher.sendDispatchSignal();
1771 if (status) {
1772 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1773 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001774 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001775 return;
1776 }
1777
1778 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001779 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001780 connection->lastDispatchTime = currentTime;
1781
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001782 // Notify other system components.
1783 onDispatchCycleStartedLocked(currentTime, connection);
1784}
1785
Jeff Brown7fbdc842010-06-17 20:52:56 -07001786void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown3915bb82010-11-05 15:02:16 -07001787 const sp<Connection>& connection, bool handled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001788#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001789 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown3915bb82010-11-05 15:02:16 -07001790 "%01.1fms since dispatch, handled=%s",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001791 connection->getInputChannelName(),
1792 connection->getEventLatencyMillis(currentTime),
Jeff Brown3915bb82010-11-05 15:02:16 -07001793 connection->getDispatchLatencyMillis(currentTime),
1794 toString(handled));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001795#endif
1796
Jeff Brown9c3cda02010-06-15 01:31:58 -07001797 if (connection->status == Connection::STATUS_BROKEN
1798 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001799 return;
1800 }
1801
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001802 // Reset the publisher since the event has been consumed.
1803 // We do this now so that the publisher can release some of its internal resources
1804 // while waiting for the next dispatch cycle to begin.
1805 status_t status = connection->inputPublisher.reset();
1806 if (status) {
1807 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1808 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001809 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001810 return;
1811 }
1812
Jeff Brown3915bb82010-11-05 15:02:16 -07001813 // Notify other system components and prepare to start the next dispatch cycle.
1814 onDispatchCycleFinishedLocked(currentTime, connection, handled);
Jeff Brownb88102f2010-09-08 11:49:43 -07001815}
1816
1817void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1818 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001819 // Start the next dispatch cycle for this connection.
1820 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001821 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001822 if (dispatchEntry->inProgress) {
1823 // Finish or resume current event in progress.
1824 if (dispatchEntry->tailMotionSample) {
1825 // We have a tail of undispatched motion samples.
1826 // Reuse the same DispatchEntry and start a new cycle.
1827 dispatchEntry->inProgress = false;
1828 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1829 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07001830 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001831 return;
1832 }
1833 // Finished.
1834 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07001835 if (dispatchEntry->hasForegroundTarget()) {
1836 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001837 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001838 mAllocator.releaseDispatchEntry(dispatchEntry);
1839 } else {
1840 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07001841 // progress event, which means we actually aborted it.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001842 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07001843 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001844 return;
1845 }
1846 }
1847
1848 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07001849 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001850}
1851
Jeff Brownb6997262010-10-08 22:31:17 -07001852void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1853 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001854#if DEBUG_DISPATCH_CYCLE
Jeff Brown83c09682010-12-23 17:50:18 -08001855 LOGD("channel '%s' ~ abortBrokenDispatchCycle",
1856 connection->getInputChannelName());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001857#endif
1858
Jeff Brownb88102f2010-09-08 11:49:43 -07001859 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07001860 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001861
Jeff Brownb6997262010-10-08 22:31:17 -07001862 // The connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07001863 // Ignore already broken or zombie connections.
Jeff Brownb6997262010-10-08 22:31:17 -07001864 if (connection->status == Connection::STATUS_NORMAL) {
1865 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001866
Jeff Brownb6997262010-10-08 22:31:17 -07001867 // Notify other system components.
1868 onDispatchCycleBrokenLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001869 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001870}
1871
Jeff Brown519e0242010-09-15 15:18:56 -07001872void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1873 while (! connection->outboundQueue.isEmpty()) {
1874 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1875 if (dispatchEntry->hasForegroundTarget()) {
1876 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001877 }
1878 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001879 }
1880
Jeff Brown519e0242010-09-15 15:18:56 -07001881 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07001882}
1883
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001884int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001885 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1886
1887 { // acquire lock
1888 AutoMutex _l(d->mLock);
1889
1890 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1891 if (connectionIndex < 0) {
1892 LOGE("Received spurious receive callback for unknown input channel. "
1893 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001894 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001895 }
1896
Jeff Brown7fbdc842010-06-17 20:52:56 -07001897 nsecs_t currentTime = now();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001898
1899 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001900 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001901 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1902 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brownb6997262010-10-08 22:31:17 -07001903 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001904 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001905 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001906 }
1907
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001908 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001909 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1910 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001911 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001912 }
1913
Jeff Brown3915bb82010-11-05 15:02:16 -07001914 bool handled = false;
Jeff Brown49ed71d2010-12-06 17:13:33 -08001915 status_t status = connection->inputPublisher.receiveFinishedSignal(&handled);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001916 if (status) {
1917 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1918 connection->getInputChannelName(), status);
Jeff Brownb6997262010-10-08 22:31:17 -07001919 d->abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001920 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001921 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001922 }
1923
Jeff Brown3915bb82010-11-05 15:02:16 -07001924 d->finishDispatchCycleLocked(currentTime, connection, handled);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001925 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001926 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001927 } // release lock
1928}
1929
Jeff Brownb6997262010-10-08 22:31:17 -07001930void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
1931 InputState::CancelationOptions options, const char* reason) {
1932 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
1933 synthesizeCancelationEventsForConnectionLocked(
1934 mConnectionsByReceiveFd.valueAt(i), options, reason);
1935 }
1936}
1937
1938void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
1939 const sp<InputChannel>& channel, InputState::CancelationOptions options,
1940 const char* reason) {
1941 ssize_t index = getConnectionIndexLocked(channel);
1942 if (index >= 0) {
1943 synthesizeCancelationEventsForConnectionLocked(
1944 mConnectionsByReceiveFd.valueAt(index), options, reason);
1945 }
1946}
1947
1948void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
1949 const sp<Connection>& connection, InputState::CancelationOptions options,
1950 const char* reason) {
1951 nsecs_t currentTime = now();
1952
1953 mTempCancelationEvents.clear();
1954 connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
1955 mTempCancelationEvents, options);
1956
1957 if (! mTempCancelationEvents.isEmpty()
1958 && connection->status != Connection::STATUS_BROKEN) {
1959#if DEBUG_OUTBOUND_EVENT_DETAILS
1960 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
1961 "with reality: %s, options=%d.",
1962 connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
1963#endif
1964 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1965 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1966 switch (cancelationEventEntry->type) {
1967 case EventEntry::TYPE_KEY:
1968 logOutboundKeyDetailsLocked("cancel - ",
1969 static_cast<KeyEntry*>(cancelationEventEntry));
1970 break;
1971 case EventEntry::TYPE_MOTION:
1972 logOutboundMotionDetailsLocked("cancel - ",
1973 static_cast<MotionEntry*>(cancelationEventEntry));
1974 break;
1975 }
1976
1977 int32_t xOffset, yOffset;
1978 const InputWindow* window = getWindowLocked(connection->inputChannel);
1979 if (window) {
1980 xOffset = -window->frameLeft;
1981 yOffset = -window->frameTop;
1982 } else {
1983 xOffset = 0;
1984 yOffset = 0;
1985 }
1986
1987 DispatchEntry* cancelationDispatchEntry =
1988 mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
1989 0, xOffset, yOffset);
1990 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1991
1992 mAllocator.releaseEventEntry(cancelationEventEntry);
1993 }
1994
1995 if (!connection->outboundQueue.headSentinel.next->inProgress) {
1996 startDispatchCycleLocked(currentTime, connection);
1997 }
1998 }
1999}
2000
Jeff Brown01ce2e92010-09-26 22:20:12 -07002001InputDispatcher::MotionEntry*
2002InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2003 assert(pointerIds.value != 0);
2004
2005 uint32_t splitPointerIndexMap[MAX_POINTERS];
2006 int32_t splitPointerIds[MAX_POINTERS];
2007 PointerCoords splitPointerCoords[MAX_POINTERS];
2008
2009 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2010 uint32_t splitPointerCount = 0;
2011
2012 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2013 originalPointerIndex++) {
2014 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
2015 if (pointerIds.hasBit(pointerId)) {
2016 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2017 splitPointerIds[splitPointerCount] = pointerId;
2018 splitPointerCoords[splitPointerCount] =
2019 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
2020 splitPointerCount += 1;
2021 }
2022 }
2023 assert(splitPointerCount == pointerIds.count());
2024
2025 int32_t action = originalMotionEntry->action;
2026 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2027 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2028 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2029 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2030 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
2031 if (pointerIds.hasBit(pointerId)) {
2032 if (pointerIds.count() == 1) {
2033 // The first/last pointer went down/up.
2034 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2035 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07002036 } else {
2037 // A secondary pointer went down/up.
2038 uint32_t splitPointerIndex = 0;
2039 while (pointerId != splitPointerIds[splitPointerIndex]) {
2040 splitPointerIndex += 1;
2041 }
2042 action = maskedAction | (splitPointerIndex
2043 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002044 }
2045 } else {
2046 // An unrelated pointer changed.
2047 action = AMOTION_EVENT_ACTION_MOVE;
2048 }
2049 }
2050
2051 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
2052 originalMotionEntry->eventTime,
2053 originalMotionEntry->deviceId,
2054 originalMotionEntry->source,
2055 originalMotionEntry->policyFlags,
2056 action,
2057 originalMotionEntry->flags,
2058 originalMotionEntry->metaState,
2059 originalMotionEntry->edgeFlags,
2060 originalMotionEntry->xPrecision,
2061 originalMotionEntry->yPrecision,
2062 originalMotionEntry->downTime,
2063 splitPointerCount, splitPointerIds, splitPointerCoords);
2064
2065 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
2066 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
2067 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
2068 splitPointerIndex++) {
2069 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2070 splitPointerCoords[splitPointerIndex] =
2071 originalMotionSample->pointerCoords[originalPointerIndex];
2072 }
2073
2074 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
2075 splitPointerCoords);
2076 }
2077
2078 return splitMotionEntry;
2079}
2080
Jeff Brown9c3cda02010-06-15 01:31:58 -07002081void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002082#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07002083 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002084#endif
2085
Jeff Brownb88102f2010-09-08 11:49:43 -07002086 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002087 { // acquire lock
2088 AutoMutex _l(mLock);
2089
Jeff Brown7fbdc842010-06-17 20:52:56 -07002090 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07002091 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002092 } // release lock
2093
Jeff Brownb88102f2010-09-08 11:49:43 -07002094 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002095 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002096 }
2097}
2098
Jeff Brownc5ed5912010-07-14 18:48:53 -07002099void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002100 uint32_t policyFlags, int32_t action, int32_t flags,
2101 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
2102#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002103 LOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002104 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07002105 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002106 keyCode, scanCode, metaState, downTime);
2107#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002108 if (! validateKeyEvent(action)) {
2109 return;
2110 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002111
Jeff Brown1f245102010-11-18 20:53:46 -08002112 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2113 policyFlags |= POLICY_FLAG_VIRTUAL;
2114 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2115 }
2116
Jeff Browne20c9e02010-10-11 14:20:19 -07002117 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brown1f245102010-11-18 20:53:46 -08002118
2119 KeyEvent event;
2120 event.initialize(deviceId, source, action, flags, keyCode, scanCode,
2121 metaState, 0, downTime, eventTime);
2122
2123 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
2124
2125 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2126 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2127 }
Jeff Brownb6997262010-10-08 22:31:17 -07002128
Jeff Brownb88102f2010-09-08 11:49:43 -07002129 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002130 { // acquire lock
2131 AutoMutex _l(mLock);
2132
Jeff Brown7fbdc842010-06-17 20:52:56 -07002133 int32_t repeatCount = 0;
2134 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002135 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002136 metaState, repeatCount, downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002137
Jeff Brownb88102f2010-09-08 11:49:43 -07002138 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002139 } // release lock
2140
Jeff Brownb88102f2010-09-08 11:49:43 -07002141 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002142 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002143 }
2144}
2145
Jeff Brownc5ed5912010-07-14 18:48:53 -07002146void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002147 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002148 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2149 float xPrecision, float yPrecision, nsecs_t downTime) {
2150#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown90655042010-12-02 13:50:46 -08002151 LOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002152 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2153 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2154 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002155 xPrecision, yPrecision, downTime);
2156 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002157 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002158 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002159 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002160 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown8d608662010-08-30 03:02:23 -07002161 pointerCoords[i].pressure, pointerCoords[i].size,
2162 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2163 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2164 pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002165 }
2166#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002167 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2168 return;
2169 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002170
Jeff Browne20c9e02010-10-11 14:20:19 -07002171 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002172 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
2173
Jeff Brownb88102f2010-09-08 11:49:43 -07002174 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002175 { // acquire lock
2176 AutoMutex _l(mLock);
2177
2178 // Attempt batching and streaming of move events.
Jeff Brownc5ed5912010-07-14 18:48:53 -07002179 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002180 // BATCHING CASE
2181 //
2182 // Try to append a move sample to the tail of the inbound queue for this device.
2183 // Give up if we encounter a non-move motion event for this device since that
2184 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002185 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2186 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002187 if (entry->type != EventEntry::TYPE_MOTION) {
2188 // Keep looking for motion events.
2189 continue;
2190 }
2191
2192 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2193 if (motionEntry->deviceId != deviceId) {
2194 // Keep looking for this device.
2195 continue;
2196 }
2197
Jeff Brownc5ed5912010-07-14 18:48:53 -07002198 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown7fbdc842010-06-17 20:52:56 -07002199 || motionEntry->pointerCount != pointerCount
2200 || motionEntry->isInjected()) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002201 // Last motion event in the queue for this device is not compatible for
2202 // appending new samples. Stop here.
2203 goto NoBatchingOrStreaming;
2204 }
2205
2206 // The last motion event is a move and is compatible for appending.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002207 // Do the batching magic.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002208 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002209#if DEBUG_BATCHING
2210 LOGD("Appended motion sample onto batch for most recent "
2211 "motion event for this device in the inbound queue.");
2212#endif
Jeff Brown9c3cda02010-06-15 01:31:58 -07002213 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002214 }
2215
2216 // STREAMING CASE
2217 //
2218 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002219 // Search the outbound queue for the current foreground targets to find a dispatched
2220 // motion event that is still in progress. If found, then, appen the new sample to
2221 // that event and push it out to all current targets. The logic in
2222 // prepareDispatchCycleLocked takes care of the case where some targets may
2223 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002224 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002225 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2226 const InputTarget& inputTarget = mCurrentInputTargets[i];
2227 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2228 // Skip non-foreground targets. We only want to stream if there is at
2229 // least one foreground target whose dispatch is still in progress.
2230 continue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002231 }
Jeff Brown519e0242010-09-15 15:18:56 -07002232
2233 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2234 if (connectionIndex < 0) {
2235 // Connection must no longer be valid.
2236 continue;
2237 }
2238
2239 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2240 if (connection->outboundQueue.isEmpty()) {
2241 // This foreground target has an empty outbound queue.
2242 continue;
2243 }
2244
2245 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2246 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002247 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2248 || dispatchEntry->isSplit()) {
2249 // No motion event is being dispatched, or it is being split across
2250 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002251 continue;
2252 }
2253
2254 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2255 dispatchEntry->eventEntry);
2256 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2257 || motionEntry->deviceId != deviceId
2258 || motionEntry->pointerCount != pointerCount
2259 || motionEntry->isInjected()) {
2260 // The motion event is not compatible with this move.
2261 continue;
2262 }
2263
2264 // Hurray! This foreground target is currently dispatching a move event
2265 // that we can stream onto. Append the motion sample and resume dispatch.
2266 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2267#if DEBUG_BATCHING
2268 LOGD("Appended motion sample onto batch for most recently dispatched "
2269 "motion event for this device in the outbound queues. "
2270 "Attempting to stream the motion sample.");
2271#endif
2272 nsecs_t currentTime = now();
2273 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2274 true /*resumeWithAppendedMotionSample*/);
2275
2276 runCommandsLockedInterruptible();
2277 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002278 }
2279 }
2280
2281NoBatchingOrStreaming:;
2282 }
2283
2284 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002285 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002286 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002287 xPrecision, yPrecision, downTime,
2288 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002289
Jeff Brownb88102f2010-09-08 11:49:43 -07002290 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002291 } // release lock
2292
Jeff Brownb88102f2010-09-08 11:49:43 -07002293 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002294 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002295 }
2296}
2297
Jeff Brownb6997262010-10-08 22:31:17 -07002298void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
2299 uint32_t policyFlags) {
2300#if DEBUG_INBOUND_EVENT_DETAILS
2301 LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
2302 switchCode, switchValue, policyFlags);
2303#endif
2304
Jeff Browne20c9e02010-10-11 14:20:19 -07002305 policyFlags |= POLICY_FLAG_TRUSTED;
Jeff Brownb6997262010-10-08 22:31:17 -07002306 mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
2307}
2308
Jeff Brown7fbdc842010-06-17 20:52:56 -07002309int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002310 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002311#if DEBUG_INBOUND_EVENT_DETAILS
2312 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002313 "syncMode=%d, timeoutMillis=%d",
2314 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002315#endif
2316
2317 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
Jeff Browne20c9e02010-10-11 14:20:19 -07002318
2319 uint32_t policyFlags = POLICY_FLAG_INJECTED;
2320 if (hasInjectionPermission(injectorPid, injectorUid)) {
2321 policyFlags |= POLICY_FLAG_TRUSTED;
2322 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002323
Jeff Brownb6997262010-10-08 22:31:17 -07002324 EventEntry* injectedEntry;
2325 switch (event->getType()) {
2326 case AINPUT_EVENT_TYPE_KEY: {
2327 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2328 int32_t action = keyEvent->getAction();
2329 if (! validateKeyEvent(action)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002330 return INPUT_EVENT_INJECTION_FAILED;
2331 }
2332
Jeff Brownb6997262010-10-08 22:31:17 -07002333 int32_t flags = keyEvent->getFlags();
Jeff Brown1f245102010-11-18 20:53:46 -08002334 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2335 policyFlags |= POLICY_FLAG_VIRTUAL;
2336 }
2337
2338 mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
2339
2340 if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2341 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2342 }
Jeff Brown6ec402b2010-07-28 15:48:59 -07002343
Jeff Brownb6997262010-10-08 22:31:17 -07002344 mLock.lock();
Jeff Brown1f245102010-11-18 20:53:46 -08002345 injectedEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
2346 keyEvent->getDeviceId(), keyEvent->getSource(),
2347 policyFlags, action, flags,
2348 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
Jeff Brownb6997262010-10-08 22:31:17 -07002349 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2350 break;
2351 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002352
Jeff Brownb6997262010-10-08 22:31:17 -07002353 case AINPUT_EVENT_TYPE_MOTION: {
2354 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2355 int32_t action = motionEvent->getAction();
2356 size_t pointerCount = motionEvent->getPointerCount();
2357 const int32_t* pointerIds = motionEvent->getPointerIds();
2358 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2359 return INPUT_EVENT_INJECTION_FAILED;
2360 }
2361
2362 nsecs_t eventTime = motionEvent->getEventTime();
Jeff Browne20c9e02010-10-11 14:20:19 -07002363 mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -07002364
2365 mLock.lock();
2366 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2367 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2368 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
2369 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2370 action, motionEvent->getFlags(),
2371 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
2372 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2373 motionEvent->getDownTime(), uint32_t(pointerCount),
2374 pointerIds, samplePointerCoords);
2375 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2376 sampleEventTimes += 1;
2377 samplePointerCoords += pointerCount;
2378 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2379 }
2380 injectedEntry = motionEntry;
2381 break;
2382 }
2383
2384 default:
2385 LOGW("Cannot inject event of type %d", event->getType());
2386 return INPUT_EVENT_INJECTION_FAILED;
2387 }
2388
2389 InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
2390 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2391 injectionState->injectionIsAsync = true;
2392 }
2393
2394 injectionState->refCount += 1;
2395 injectedEntry->injectionState = injectionState;
2396
2397 bool needWake = enqueueInboundEventLocked(injectedEntry);
2398 mLock.unlock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002399
Jeff Brownb88102f2010-09-08 11:49:43 -07002400 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002401 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002402 }
2403
2404 int32_t injectionResult;
2405 { // acquire lock
2406 AutoMutex _l(mLock);
2407
Jeff Brown6ec402b2010-07-28 15:48:59 -07002408 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2409 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2410 } else {
2411 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002412 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002413 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2414 break;
2415 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002416
Jeff Brown7fbdc842010-06-17 20:52:56 -07002417 nsecs_t remainingTimeout = endTime - now();
2418 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002419#if DEBUG_INJECTION
2420 LOGD("injectInputEvent - Timed out waiting for injection result "
2421 "to become available.");
2422#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002423 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2424 break;
2425 }
2426
Jeff Brown6ec402b2010-07-28 15:48:59 -07002427 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2428 }
2429
2430 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2431 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002432 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002433#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002434 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002435 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002436#endif
2437 nsecs_t remainingTimeout = endTime - now();
2438 if (remainingTimeout <= 0) {
2439#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002440 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002441 "dispatches to finish.");
2442#endif
2443 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2444 break;
2445 }
2446
2447 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2448 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002449 }
2450 }
2451
Jeff Brown01ce2e92010-09-26 22:20:12 -07002452 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002453 } // release lock
2454
Jeff Brown6ec402b2010-07-28 15:48:59 -07002455#if DEBUG_INJECTION
2456 LOGD("injectInputEvent - Finished with result %d. "
2457 "injectorPid=%d, injectorUid=%d",
2458 injectionResult, injectorPid, injectorUid);
2459#endif
2460
Jeff Brown7fbdc842010-06-17 20:52:56 -07002461 return injectionResult;
2462}
2463
Jeff Brownb6997262010-10-08 22:31:17 -07002464bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2465 return injectorUid == 0
2466 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2467}
2468
Jeff Brown7fbdc842010-06-17 20:52:56 -07002469void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002470 InjectionState* injectionState = entry->injectionState;
2471 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002472#if DEBUG_INJECTION
2473 LOGD("Setting input event injection result to %d. "
2474 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002475 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002476#endif
2477
Jeff Brown01ce2e92010-09-26 22:20:12 -07002478 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002479 // Log the outcome since the injector did not wait for the injection result.
2480 switch (injectionResult) {
2481 case INPUT_EVENT_INJECTION_SUCCEEDED:
2482 LOGV("Asynchronous input event injection succeeded.");
2483 break;
2484 case INPUT_EVENT_INJECTION_FAILED:
2485 LOGW("Asynchronous input event injection failed.");
2486 break;
2487 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2488 LOGW("Asynchronous input event injection permission denied.");
2489 break;
2490 case INPUT_EVENT_INJECTION_TIMED_OUT:
2491 LOGW("Asynchronous input event injection timed out.");
2492 break;
2493 }
2494 }
2495
Jeff Brown01ce2e92010-09-26 22:20:12 -07002496 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002497 mInjectionResultAvailableCondition.broadcast();
2498 }
2499}
2500
Jeff Brown01ce2e92010-09-26 22:20:12 -07002501void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2502 InjectionState* injectionState = entry->injectionState;
2503 if (injectionState) {
2504 injectionState->pendingForegroundDispatches += 1;
2505 }
2506}
2507
Jeff Brown519e0242010-09-15 15:18:56 -07002508void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002509 InjectionState* injectionState = entry->injectionState;
2510 if (injectionState) {
2511 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002512
Jeff Brown01ce2e92010-09-26 22:20:12 -07002513 if (injectionState->pendingForegroundDispatches == 0) {
2514 mInjectionSyncFinishedCondition.broadcast();
2515 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002516 }
2517}
2518
Jeff Brown01ce2e92010-09-26 22:20:12 -07002519const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2520 for (size_t i = 0; i < mWindows.size(); i++) {
2521 const InputWindow* window = & mWindows[i];
2522 if (window->inputChannel == inputChannel) {
2523 return window;
2524 }
2525 }
2526 return NULL;
2527}
2528
Jeff Brownb88102f2010-09-08 11:49:43 -07002529void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2530#if DEBUG_FOCUS
2531 LOGD("setInputWindows");
2532#endif
2533 { // acquire lock
2534 AutoMutex _l(mLock);
2535
Jeff Brown01ce2e92010-09-26 22:20:12 -07002536 // Clear old window pointers.
Jeff Brownb6997262010-10-08 22:31:17 -07002537 sp<InputChannel> oldFocusedWindowChannel;
2538 if (mFocusedWindow) {
2539 oldFocusedWindowChannel = mFocusedWindow->inputChannel;
2540 mFocusedWindow = NULL;
2541 }
2542
Jeff Brownb88102f2010-09-08 11:49:43 -07002543 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002544
2545 // Loop over new windows and rebuild the necessary window pointers for
2546 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002547 mWindows.appendVector(inputWindows);
2548
2549 size_t numWindows = mWindows.size();
2550 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002551 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002552 if (window->hasFocus) {
2553 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002554 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002555 }
2556 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002557
Jeff Brownb6997262010-10-08 22:31:17 -07002558 if (oldFocusedWindowChannel != NULL) {
2559 if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
2560#if DEBUG_FOCUS
2561 LOGD("Focus left window: %s",
2562 oldFocusedWindowChannel->getName().string());
2563#endif
2564 synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
2565 InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
2566 oldFocusedWindowChannel.clear();
2567 }
2568 }
2569 if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
2570#if DEBUG_FOCUS
2571 LOGD("Focus entered window: %s",
2572 mFocusedWindow->inputChannel->getName().string());
2573#endif
2574 }
2575
Jeff Brown01ce2e92010-09-26 22:20:12 -07002576 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2577 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2578 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2579 if (window) {
2580 touchedWindow.window = window;
2581 i += 1;
2582 } else {
Jeff Brownb6997262010-10-08 22:31:17 -07002583#if DEBUG_FOCUS
2584 LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
2585#endif
Jeff Brownb6997262010-10-08 22:31:17 -07002586 synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
2587 InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
Jeff Brownaf48cae2010-10-15 16:20:51 -07002588 mTouchState.windows.removeAt(i);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002589 }
2590 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002591
Jeff Brownb88102f2010-09-08 11:49:43 -07002592#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002593 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002594#endif
2595 } // release lock
2596
2597 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002598 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002599}
2600
2601void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2602#if DEBUG_FOCUS
2603 LOGD("setFocusedApplication");
2604#endif
2605 { // acquire lock
2606 AutoMutex _l(mLock);
2607
2608 releaseFocusedApplicationLocked();
2609
2610 if (inputApplication) {
2611 mFocusedApplicationStorage = *inputApplication;
2612 mFocusedApplication = & mFocusedApplicationStorage;
2613 }
2614
2615#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002616 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002617#endif
2618 } // release lock
2619
2620 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002621 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002622}
2623
2624void InputDispatcher::releaseFocusedApplicationLocked() {
2625 if (mFocusedApplication) {
2626 mFocusedApplication = NULL;
2627 mFocusedApplicationStorage.handle.clear();
2628 }
2629}
2630
2631void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2632#if DEBUG_FOCUS
2633 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2634#endif
2635
2636 bool changed;
2637 { // acquire lock
2638 AutoMutex _l(mLock);
2639
2640 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
Jeff Brown120a4592010-10-27 18:43:51 -07002641 if (mDispatchFrozen && !frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002642 resetANRTimeoutsLocked();
2643 }
2644
Jeff Brown120a4592010-10-27 18:43:51 -07002645 if (mDispatchEnabled && !enabled) {
2646 resetAndDropEverythingLocked("dispatcher is being disabled");
2647 }
2648
Jeff Brownb88102f2010-09-08 11:49:43 -07002649 mDispatchEnabled = enabled;
2650 mDispatchFrozen = frozen;
2651 changed = true;
2652 } else {
2653 changed = false;
2654 }
2655
2656#if DEBUG_FOCUS
Jeff Brownb6997262010-10-08 22:31:17 -07002657 //logDispatchStateLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -07002658#endif
2659 } // release lock
2660
2661 if (changed) {
2662 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002663 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002664 }
2665}
2666
Jeff Browne6504122010-09-27 14:52:15 -07002667bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2668 const sp<InputChannel>& toChannel) {
2669#if DEBUG_FOCUS
2670 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2671 fromChannel->getName().string(), toChannel->getName().string());
2672#endif
2673 { // acquire lock
2674 AutoMutex _l(mLock);
2675
2676 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2677 const InputWindow* toWindow = getWindowLocked(toChannel);
2678 if (! fromWindow || ! toWindow) {
2679#if DEBUG_FOCUS
2680 LOGD("Cannot transfer focus because from or to window not found.");
2681#endif
2682 return false;
2683 }
2684 if (fromWindow == toWindow) {
2685#if DEBUG_FOCUS
2686 LOGD("Trivial transfer to same window.");
2687#endif
2688 return true;
2689 }
2690
2691 bool found = false;
2692 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2693 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2694 if (touchedWindow.window == fromWindow) {
2695 int32_t oldTargetFlags = touchedWindow.targetFlags;
2696 BitSet32 pointerIds = touchedWindow.pointerIds;
2697
2698 mTouchState.windows.removeAt(i);
2699
Jeff Brown46e75292010-11-10 16:53:45 -08002700 int32_t newTargetFlags = oldTargetFlags
2701 & (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT);
Jeff Browne6504122010-09-27 14:52:15 -07002702 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2703
2704 found = true;
2705 break;
2706 }
2707 }
2708
2709 if (! found) {
2710#if DEBUG_FOCUS
2711 LOGD("Focus transfer failed because from window did not have focus.");
2712#endif
2713 return false;
2714 }
2715
Jeff Brown9c9f1a32010-10-11 18:32:20 -07002716 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2717 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2718 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2719 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
2720 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
2721
2722 fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2723 synthesizeCancelationEventsForConnectionLocked(fromConnection,
2724 InputState::CANCEL_POINTER_EVENTS,
2725 "transferring touch focus from this window to another window");
2726 }
2727
Jeff Browne6504122010-09-27 14:52:15 -07002728#if DEBUG_FOCUS
2729 logDispatchStateLocked();
2730#endif
2731 } // release lock
2732
2733 // Wake up poll loop since it may need to make new input dispatching choices.
2734 mLooper->wake();
2735 return true;
2736}
2737
Jeff Brown120a4592010-10-27 18:43:51 -07002738void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2739#if DEBUG_FOCUS
2740 LOGD("Resetting and dropping all events (%s).", reason);
2741#endif
2742
2743 synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
2744
2745 resetKeyRepeatLocked();
2746 releasePendingEventLocked();
2747 drainInboundQueueLocked();
2748 resetTargetsLocked();
2749
2750 mTouchState.reset();
2751}
2752
Jeff Brownb88102f2010-09-08 11:49:43 -07002753void InputDispatcher::logDispatchStateLocked() {
2754 String8 dump;
2755 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002756
2757 char* text = dump.lockBuffer(dump.size());
2758 char* start = text;
2759 while (*start != '\0') {
2760 char* end = strchr(start, '\n');
2761 if (*end == '\n') {
2762 *(end++) = '\0';
2763 }
2764 LOGD("%s", start);
2765 start = end;
2766 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002767}
2768
2769void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002770 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2771 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
Jeff Brownb88102f2010-09-08 11:49:43 -07002772
2773 if (mFocusedApplication) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002774 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002775 mFocusedApplication->name.string(),
2776 mFocusedApplication->dispatchingTimeout / 1000000.0);
2777 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002778 dump.append(INDENT "FocusedApplication: <null>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002779 }
Jeff Brownf2f487182010-10-01 17:46:21 -07002780 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002781 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brownf2f487182010-10-01 17:46:21 -07002782
2783 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2784 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
Jeff Brown95712852011-01-04 19:41:59 -08002785 dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
Jeff Brownf2f487182010-10-01 17:46:21 -07002786 if (!mTouchState.windows.isEmpty()) {
2787 dump.append(INDENT "TouchedWindows:\n");
2788 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2789 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2790 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2791 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2792 touchedWindow.targetFlags);
2793 }
2794 } else {
2795 dump.append(INDENT "TouchedWindows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002796 }
2797
Jeff Brownf2f487182010-10-01 17:46:21 -07002798 if (!mWindows.isEmpty()) {
2799 dump.append(INDENT "Windows:\n");
2800 for (size_t i = 0; i < mWindows.size(); i++) {
2801 const InputWindow& window = mWindows[i];
2802 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2803 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2804 "frame=[%d,%d][%d,%d], "
2805 "visibleFrame=[%d,%d][%d,%d], "
2806 "touchableArea=[%d,%d][%d,%d], "
2807 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
2808 i, window.name.string(),
2809 toString(window.paused),
2810 toString(window.hasFocus),
2811 toString(window.hasWallpaper),
2812 toString(window.visible),
2813 toString(window.canReceiveKeys),
2814 window.layoutParamsFlags, window.layoutParamsType,
2815 window.layer,
2816 window.frameLeft, window.frameTop,
2817 window.frameRight, window.frameBottom,
2818 window.visibleFrameLeft, window.visibleFrameTop,
2819 window.visibleFrameRight, window.visibleFrameBottom,
2820 window.touchableAreaLeft, window.touchableAreaTop,
2821 window.touchableAreaRight, window.touchableAreaBottom,
2822 window.ownerPid, window.ownerUid,
2823 window.dispatchingTimeout / 1000000.0);
2824 }
2825 } else {
2826 dump.append(INDENT "Windows: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002827 }
2828
Jeff Brownf2f487182010-10-01 17:46:21 -07002829 if (!mMonitoringChannels.isEmpty()) {
2830 dump.append(INDENT "MonitoringChannels:\n");
2831 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2832 const sp<InputChannel>& channel = mMonitoringChannels[i];
2833 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
2834 }
2835 } else {
2836 dump.append(INDENT "MonitoringChannels: <none>\n");
2837 }
Jeff Brown519e0242010-09-15 15:18:56 -07002838
Jeff Brownf2f487182010-10-01 17:46:21 -07002839 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
2840
2841 if (!mActiveConnections.isEmpty()) {
2842 dump.append(INDENT "ActiveConnections:\n");
2843 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2844 const Connection* connection = mActiveConnections[i];
Jeff Brown76860e32010-10-25 17:37:46 -07002845 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
Jeff Brownb6997262010-10-08 22:31:17 -07002846 "inputState.isNeutral=%s\n",
Jeff Brownf2f487182010-10-01 17:46:21 -07002847 i, connection->getInputChannelName(), connection->getStatusLabel(),
2848 connection->outboundQueue.count(),
Jeff Brownb6997262010-10-08 22:31:17 -07002849 toString(connection->inputState.isNeutral()));
Jeff Brownf2f487182010-10-01 17:46:21 -07002850 }
2851 } else {
2852 dump.append(INDENT "ActiveConnections: <none>\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002853 }
2854
2855 if (isAppSwitchPendingLocked()) {
Jeff Brownf2f487182010-10-01 17:46:21 -07002856 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
Jeff Brownb88102f2010-09-08 11:49:43 -07002857 (mAppSwitchDueTime - now()) / 1000000.0);
2858 } else {
Jeff Brownf2f487182010-10-01 17:46:21 -07002859 dump.append(INDENT "AppSwitch: not pending\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07002860 }
2861}
2862
2863status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002864#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07002865 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2866 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07002867#endif
2868
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002869 { // acquire lock
2870 AutoMutex _l(mLock);
2871
Jeff Brown519e0242010-09-15 15:18:56 -07002872 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002873 LOGW("Attempted to register already registered input channel '%s'",
2874 inputChannel->getName().string());
2875 return BAD_VALUE;
2876 }
2877
2878 sp<Connection> connection = new Connection(inputChannel);
2879 status_t status = connection->initialize();
2880 if (status) {
2881 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2882 inputChannel->getName().string(), status);
2883 return status;
2884 }
2885
Jeff Brown2cbecea2010-08-17 15:59:26 -07002886 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002887 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002888
Jeff Brownb88102f2010-09-08 11:49:43 -07002889 if (monitor) {
2890 mMonitoringChannels.push(inputChannel);
2891 }
2892
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002893 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07002894
Jeff Brown9c3cda02010-06-15 01:31:58 -07002895 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002896 } // release lock
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002897 return OK;
2898}
2899
2900status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002901#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07002902 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07002903#endif
2904
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002905 { // acquire lock
2906 AutoMutex _l(mLock);
2907
Jeff Brown519e0242010-09-15 15:18:56 -07002908 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002909 if (connectionIndex < 0) {
2910 LOGW("Attempted to unregister already unregistered input channel '%s'",
2911 inputChannel->getName().string());
2912 return BAD_VALUE;
2913 }
2914
2915 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2916 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2917
2918 connection->status = Connection::STATUS_ZOMBIE;
2919
Jeff Brownb88102f2010-09-08 11:49:43 -07002920 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2921 if (mMonitoringChannels[i] == inputChannel) {
2922 mMonitoringChannels.removeAt(i);
2923 break;
2924 }
2925 }
2926
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002927 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07002928
Jeff Brown7fbdc842010-06-17 20:52:56 -07002929 nsecs_t currentTime = now();
Jeff Brownb6997262010-10-08 22:31:17 -07002930 abortBrokenDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002931
2932 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002933 } // release lock
2934
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002935 // Wake the poll loop because removing the connection may have changed the current
2936 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002937 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002938 return OK;
2939}
2940
Jeff Brown519e0242010-09-15 15:18:56 -07002941ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07002942 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2943 if (connectionIndex >= 0) {
2944 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2945 if (connection->inputChannel.get() == inputChannel.get()) {
2946 return connectionIndex;
2947 }
2948 }
2949
2950 return -1;
2951}
2952
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002953void InputDispatcher::activateConnectionLocked(Connection* connection) {
2954 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2955 if (mActiveConnections.itemAt(i) == connection) {
2956 return;
2957 }
2958 }
2959 mActiveConnections.add(connection);
2960}
2961
2962void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2963 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2964 if (mActiveConnections.itemAt(i) == connection) {
2965 mActiveConnections.removeAt(i);
2966 return;
2967 }
2968 }
2969}
2970
Jeff Brown9c3cda02010-06-15 01:31:58 -07002971void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002972 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002973}
2974
Jeff Brown9c3cda02010-06-15 01:31:58 -07002975void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown3915bb82010-11-05 15:02:16 -07002976 nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
2977 CommandEntry* commandEntry = postCommandLocked(
2978 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
2979 commandEntry->connection = connection;
2980 commandEntry->handled = handled;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002981}
2982
Jeff Brown9c3cda02010-06-15 01:31:58 -07002983void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002984 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002985 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2986 connection->getInputChannelName());
2987
Jeff Brown9c3cda02010-06-15 01:31:58 -07002988 CommandEntry* commandEntry = postCommandLocked(
2989 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002990 commandEntry->connection = connection;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002991}
2992
Jeff Brown519e0242010-09-15 15:18:56 -07002993void InputDispatcher::onANRLocked(
2994 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2995 nsecs_t eventTime, nsecs_t waitStartTime) {
2996 LOGI("Application is not responding: %s. "
2997 "%01.1fms since event, %01.1fms since wait started",
2998 getApplicationWindowLabelLocked(application, window).string(),
2999 (currentTime - eventTime) / 1000000.0,
3000 (currentTime - waitStartTime) / 1000000.0);
3001
3002 CommandEntry* commandEntry = postCommandLocked(
3003 & InputDispatcher::doNotifyANRLockedInterruptible);
3004 if (application) {
3005 commandEntry->inputApplicationHandle = application->handle;
3006 }
3007 if (window) {
3008 commandEntry->inputChannel = window->inputChannel;
3009 }
3010}
3011
Jeff Brownb88102f2010-09-08 11:49:43 -07003012void InputDispatcher::doNotifyConfigurationChangedInterruptible(
3013 CommandEntry* commandEntry) {
3014 mLock.unlock();
3015
3016 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
3017
3018 mLock.lock();
3019}
3020
Jeff Brown9c3cda02010-06-15 01:31:58 -07003021void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
3022 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003023 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07003024
Jeff Brown7fbdc842010-06-17 20:52:56 -07003025 if (connection->status != Connection::STATUS_ZOMBIE) {
3026 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003027
Jeff Brown7fbdc842010-06-17 20:52:56 -07003028 mPolicy->notifyInputChannelBroken(connection->inputChannel);
3029
3030 mLock.lock();
3031 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07003032}
3033
Jeff Brown519e0242010-09-15 15:18:56 -07003034void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07003035 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07003036 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07003037
Jeff Brown519e0242010-09-15 15:18:56 -07003038 nsecs_t newTimeout = mPolicy->notifyANR(
3039 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003040
Jeff Brown519e0242010-09-15 15:18:56 -07003041 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07003042
Jeff Brown519e0242010-09-15 15:18:56 -07003043 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003044}
3045
Jeff Brownb88102f2010-09-08 11:49:43 -07003046void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3047 CommandEntry* commandEntry) {
3048 KeyEntry* entry = commandEntry->keyEntry;
Jeff Brown1f245102010-11-18 20:53:46 -08003049
3050 KeyEvent event;
3051 initializeKeyEvent(&event, entry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003052
3053 mLock.unlock();
3054
3055 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
Jeff Brown1f245102010-11-18 20:53:46 -08003056 &event, entry->policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -07003057
3058 mLock.lock();
3059
3060 entry->interceptKeyResult = consumed
3061 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
3062 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3063 mAllocator.releaseKeyEntry(entry);
3064}
3065
Jeff Brown3915bb82010-11-05 15:02:16 -07003066void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3067 CommandEntry* commandEntry) {
3068 sp<Connection> connection = commandEntry->connection;
3069 bool handled = commandEntry->handled;
3070
Jeff Brown49ed71d2010-12-06 17:13:33 -08003071 if (!connection->outboundQueue.isEmpty()) {
Jeff Brown3915bb82010-11-05 15:02:16 -07003072 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
3073 if (dispatchEntry->inProgress
3074 && dispatchEntry->hasForegroundTarget()
3075 && dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3076 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003077 if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
3078 if (handled) {
3079 // If the application handled a non-fallback key, then immediately
3080 // cancel all fallback keys previously dispatched to the application.
3081 // This behavior will prevent chording with fallback keys (so they cannot
3082 // be used as modifiers) but it will ensure that fallback keys do not
3083 // get stuck. This takes care of the case where the application does not handle
3084 // the original DOWN so we generate a fallback DOWN but it does handle
3085 // the original UP in which case we would not generate the fallback UP.
3086 synthesizeCancelationEventsForConnectionLocked(connection,
3087 InputState::CANCEL_FALLBACK_EVENTS,
Jeff Brown00045a72010-12-09 18:10:30 -08003088 "application handled a non-fallback event, canceling all fallback events");
Jeff Brown49ed71d2010-12-06 17:13:33 -08003089 } else {
3090 // If the application did not handle a non-fallback key, then ask
3091 // the policy what to do with it. We might generate a fallback key
3092 // event here.
3093 KeyEvent event;
3094 initializeKeyEvent(&event, keyEntry);
Jeff Brown3915bb82010-11-05 15:02:16 -07003095
Jeff Brown49ed71d2010-12-06 17:13:33 -08003096 mLock.unlock();
Jeff Brown3915bb82010-11-05 15:02:16 -07003097
Jeff Brown49ed71d2010-12-06 17:13:33 -08003098 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputChannel,
3099 &event, keyEntry->policyFlags, &event);
Jeff Brown3915bb82010-11-05 15:02:16 -07003100
Jeff Brown49ed71d2010-12-06 17:13:33 -08003101 mLock.lock();
3102
Jeff Brown00045a72010-12-09 18:10:30 -08003103 if (connection->status != Connection::STATUS_NORMAL) {
3104 return;
3105 }
3106
3107 assert(connection->outboundQueue.headSentinel.next == dispatchEntry);
3108
Jeff Brown49ed71d2010-12-06 17:13:33 -08003109 if (fallback) {
3110 // Restart the dispatch cycle using the fallback key.
3111 keyEntry->eventTime = event.getEventTime();
3112 keyEntry->deviceId = event.getDeviceId();
3113 keyEntry->source = event.getSource();
3114 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
3115 keyEntry->keyCode = event.getKeyCode();
3116 keyEntry->scanCode = event.getScanCode();
3117 keyEntry->metaState = event.getMetaState();
3118 keyEntry->repeatCount = event.getRepeatCount();
3119 keyEntry->downTime = event.getDownTime();
3120 keyEntry->syntheticRepeat = false;
3121
3122 dispatchEntry->inProgress = false;
3123 startDispatchCycleLocked(now(), connection);
3124 return;
3125 }
3126 }
3127 }
Jeff Brown3915bb82010-11-05 15:02:16 -07003128 }
3129 }
3130
3131 startNextDispatchCycleLocked(now(), connection);
3132}
3133
Jeff Brownb88102f2010-09-08 11:49:43 -07003134void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3135 mLock.unlock();
3136
Jeff Brown01ce2e92010-09-26 22:20:12 -07003137 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07003138
3139 mLock.lock();
3140}
3141
Jeff Brown3915bb82010-11-05 15:02:16 -07003142void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
3143 event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3144 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3145 entry->downTime, entry->eventTime);
3146}
3147
Jeff Brown519e0242010-09-15 15:18:56 -07003148void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3149 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3150 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07003151}
3152
3153void InputDispatcher::dump(String8& dump) {
Jeff Brownf2f487182010-10-01 17:46:21 -07003154 dump.append("Input Dispatcher State:\n");
Jeff Brownb88102f2010-09-08 11:49:43 -07003155 dumpDispatchStateLocked(dump);
3156}
3157
Jeff Brown9c3cda02010-06-15 01:31:58 -07003158
Jeff Brown519e0242010-09-15 15:18:56 -07003159// --- InputDispatcher::Queue ---
3160
3161template <typename T>
3162uint32_t InputDispatcher::Queue<T>::count() const {
3163 uint32_t result = 0;
3164 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
3165 result += 1;
3166 }
3167 return result;
3168}
3169
3170
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003171// --- InputDispatcher::Allocator ---
3172
3173InputDispatcher::Allocator::Allocator() {
3174}
3175
Jeff Brown01ce2e92010-09-26 22:20:12 -07003176InputDispatcher::InjectionState*
3177InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
3178 InjectionState* injectionState = mInjectionStatePool.alloc();
3179 injectionState->refCount = 1;
3180 injectionState->injectorPid = injectorPid;
3181 injectionState->injectorUid = injectorUid;
3182 injectionState->injectionIsAsync = false;
3183 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
3184 injectionState->pendingForegroundDispatches = 0;
3185 return injectionState;
3186}
3187
Jeff Brown7fbdc842010-06-17 20:52:56 -07003188void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
Jeff Brownb6997262010-10-08 22:31:17 -07003189 nsecs_t eventTime, uint32_t policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07003190 entry->type = type;
3191 entry->refCount = 1;
3192 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07003193 entry->eventTime = eventTime;
Jeff Brownb6997262010-10-08 22:31:17 -07003194 entry->policyFlags = policyFlags;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003195 entry->injectionState = NULL;
3196}
3197
3198void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
3199 if (entry->injectionState) {
3200 releaseInjectionState(entry->injectionState);
3201 entry->injectionState = NULL;
3202 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07003203}
3204
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003205InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07003206InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003207 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003208 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003209 return entry;
3210}
3211
Jeff Brown7fbdc842010-06-17 20:52:56 -07003212InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07003213 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003214 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3215 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003216 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003217 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003218
3219 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003220 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003221 entry->action = action;
3222 entry->flags = flags;
3223 entry->keyCode = keyCode;
3224 entry->scanCode = scanCode;
3225 entry->metaState = metaState;
3226 entry->repeatCount = repeatCount;
3227 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07003228 entry->syntheticRepeat = false;
3229 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003230 return entry;
3231}
3232
Jeff Brown7fbdc842010-06-17 20:52:56 -07003233InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07003234 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003235 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
3236 nsecs_t downTime, uint32_t pointerCount,
3237 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003238 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brownb6997262010-10-08 22:31:17 -07003239 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
Jeff Brown7fbdc842010-06-17 20:52:56 -07003240
3241 entry->eventTime = eventTime;
3242 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07003243 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003244 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07003245 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003246 entry->metaState = metaState;
3247 entry->edgeFlags = edgeFlags;
3248 entry->xPrecision = xPrecision;
3249 entry->yPrecision = yPrecision;
3250 entry->downTime = downTime;
3251 entry->pointerCount = pointerCount;
3252 entry->firstSample.eventTime = eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003253 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003254 entry->lastSample = & entry->firstSample;
3255 for (uint32_t i = 0; i < pointerCount; i++) {
3256 entry->pointerIds[i] = pointerIds[i];
3257 entry->firstSample.pointerCoords[i] = pointerCoords[i];
3258 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003259 return entry;
3260}
3261
3262InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07003263 EventEntry* eventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07003264 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003265 DispatchEntry* entry = mDispatchEntryPool.alloc();
3266 entry->eventEntry = eventEntry;
3267 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07003268 entry->targetFlags = targetFlags;
3269 entry->xOffset = xOffset;
3270 entry->yOffset = yOffset;
Jeff Brownb88102f2010-09-08 11:49:43 -07003271 entry->inProgress = false;
3272 entry->headMotionSample = NULL;
3273 entry->tailMotionSample = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003274 return entry;
3275}
3276
Jeff Brown9c3cda02010-06-15 01:31:58 -07003277InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
3278 CommandEntry* entry = mCommandEntryPool.alloc();
3279 entry->command = command;
3280 return entry;
3281}
3282
Jeff Brown01ce2e92010-09-26 22:20:12 -07003283void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
3284 injectionState->refCount -= 1;
3285 if (injectionState->refCount == 0) {
3286 mInjectionStatePool.free(injectionState);
3287 } else {
3288 assert(injectionState->refCount > 0);
3289 }
3290}
3291
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003292void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
3293 switch (entry->type) {
3294 case EventEntry::TYPE_CONFIGURATION_CHANGED:
3295 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
3296 break;
3297 case EventEntry::TYPE_KEY:
3298 releaseKeyEntry(static_cast<KeyEntry*>(entry));
3299 break;
3300 case EventEntry::TYPE_MOTION:
3301 releaseMotionEntry(static_cast<MotionEntry*>(entry));
3302 break;
3303 default:
3304 assert(false);
3305 break;
3306 }
3307}
3308
3309void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
3310 ConfigurationChangedEntry* entry) {
3311 entry->refCount -= 1;
3312 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003313 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003314 mConfigurationChangeEntryPool.free(entry);
3315 } else {
3316 assert(entry->refCount > 0);
3317 }
3318}
3319
3320void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3321 entry->refCount -= 1;
3322 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003323 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003324 mKeyEntryPool.free(entry);
3325 } else {
3326 assert(entry->refCount > 0);
3327 }
3328}
3329
3330void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3331 entry->refCount -= 1;
3332 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003333 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003334 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3335 MotionSample* next = sample->next;
3336 mMotionSamplePool.free(sample);
3337 sample = next;
3338 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003339 mMotionEntryPool.free(entry);
3340 } else {
3341 assert(entry->refCount > 0);
3342 }
3343}
3344
3345void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3346 releaseEventEntry(entry->eventEntry);
3347 mDispatchEntryPool.free(entry);
3348}
3349
Jeff Brown9c3cda02010-06-15 01:31:58 -07003350void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3351 mCommandEntryPool.free(entry);
3352}
3353
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003354void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003355 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003356 MotionSample* sample = mMotionSamplePool.alloc();
3357 sample->eventTime = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003358 uint32_t pointerCount = motionEntry->pointerCount;
3359 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003360 sample->pointerCoords[i] = pointerCoords[i];
3361 }
3362
3363 sample->next = NULL;
3364 motionEntry->lastSample->next = sample;
3365 motionEntry->lastSample = sample;
3366}
3367
Jeff Brown01ce2e92010-09-26 22:20:12 -07003368void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3369 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003370
Jeff Brown01ce2e92010-09-26 22:20:12 -07003371 keyEntry->dispatchInProgress = false;
3372 keyEntry->syntheticRepeat = false;
3373 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003374}
3375
3376
Jeff Brownae9fc032010-08-18 15:51:08 -07003377// --- InputDispatcher::MotionEntry ---
3378
3379uint32_t InputDispatcher::MotionEntry::countSamples() const {
3380 uint32_t count = 1;
3381 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3382 count += 1;
3383 }
3384 return count;
3385}
3386
Jeff Brownb88102f2010-09-08 11:49:43 -07003387
3388// --- InputDispatcher::InputState ---
3389
Jeff Brownb6997262010-10-08 22:31:17 -07003390InputDispatcher::InputState::InputState() {
Jeff Brownb88102f2010-09-08 11:49:43 -07003391}
3392
3393InputDispatcher::InputState::~InputState() {
3394}
3395
3396bool InputDispatcher::InputState::isNeutral() const {
3397 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3398}
3399
Jeff Brownb88102f2010-09-08 11:49:43 -07003400InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3401 const EventEntry* entry) {
3402 switch (entry->type) {
3403 case EventEntry::TYPE_KEY:
3404 return trackKey(static_cast<const KeyEntry*>(entry));
3405
3406 case EventEntry::TYPE_MOTION:
3407 return trackMotion(static_cast<const MotionEntry*>(entry));
3408
3409 default:
3410 return CONSISTENT;
3411 }
3412}
3413
3414InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3415 const KeyEntry* entry) {
3416 int32_t action = entry->action;
3417 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3418 KeyMemento& memento = mKeyMementos.editItemAt(i);
3419 if (memento.deviceId == entry->deviceId
3420 && memento.source == entry->source
3421 && memento.keyCode == entry->keyCode
3422 && memento.scanCode == entry->scanCode) {
3423 switch (action) {
3424 case AKEY_EVENT_ACTION_UP:
3425 mKeyMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003426 return CONSISTENT;
3427
3428 case AKEY_EVENT_ACTION_DOWN:
3429 return TOLERABLE;
3430
3431 default:
3432 return BROKEN;
3433 }
3434 }
3435 }
3436
3437 switch (action) {
3438 case AKEY_EVENT_ACTION_DOWN: {
3439 mKeyMementos.push();
3440 KeyMemento& memento = mKeyMementos.editTop();
3441 memento.deviceId = entry->deviceId;
3442 memento.source = entry->source;
3443 memento.keyCode = entry->keyCode;
3444 memento.scanCode = entry->scanCode;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003445 memento.flags = entry->flags;
Jeff Brownb88102f2010-09-08 11:49:43 -07003446 memento.downTime = entry->downTime;
3447 return CONSISTENT;
3448 }
3449
3450 default:
3451 return BROKEN;
3452 }
3453}
3454
3455InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3456 const MotionEntry* entry) {
3457 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3458 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3459 MotionMemento& memento = mMotionMementos.editItemAt(i);
3460 if (memento.deviceId == entry->deviceId
3461 && memento.source == entry->source) {
3462 switch (action) {
3463 case AMOTION_EVENT_ACTION_UP:
3464 case AMOTION_EVENT_ACTION_CANCEL:
3465 mMotionMementos.removeAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07003466 return CONSISTENT;
3467
3468 case AMOTION_EVENT_ACTION_DOWN:
3469 return TOLERABLE;
3470
3471 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3472 if (entry->pointerCount == memento.pointerCount + 1) {
3473 memento.setPointers(entry);
3474 return CONSISTENT;
3475 }
3476 return BROKEN;
3477
3478 case AMOTION_EVENT_ACTION_POINTER_UP:
3479 if (entry->pointerCount == memento.pointerCount - 1) {
3480 memento.setPointers(entry);
3481 return CONSISTENT;
3482 }
3483 return BROKEN;
3484
3485 case AMOTION_EVENT_ACTION_MOVE:
3486 if (entry->pointerCount == memento.pointerCount) {
3487 return CONSISTENT;
3488 }
3489 return BROKEN;
3490
3491 default:
3492 return BROKEN;
3493 }
3494 }
3495 }
3496
3497 switch (action) {
3498 case AMOTION_EVENT_ACTION_DOWN: {
3499 mMotionMementos.push();
3500 MotionMemento& memento = mMotionMementos.editTop();
3501 memento.deviceId = entry->deviceId;
3502 memento.source = entry->source;
3503 memento.xPrecision = entry->xPrecision;
3504 memento.yPrecision = entry->yPrecision;
3505 memento.downTime = entry->downTime;
3506 memento.setPointers(entry);
3507 return CONSISTENT;
3508 }
3509
3510 default:
3511 return BROKEN;
3512 }
3513}
3514
3515void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3516 pointerCount = entry->pointerCount;
3517 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3518 pointerIds[i] = entry->pointerIds[i];
3519 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3520 }
3521}
3522
Jeff Brownb6997262010-10-08 22:31:17 -07003523void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3524 Allocator* allocator, Vector<EventEntry*>& outEvents,
3525 CancelationOptions options) {
3526 for (size_t i = 0; i < mKeyMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003527 const KeyMemento& memento = mKeyMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003528 if (shouldCancelKey(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003529 outEvents.push(allocator->obtainKeyEntry(currentTime,
3530 memento.deviceId, memento.source, 0,
Jeff Brown49ed71d2010-12-06 17:13:33 -08003531 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
Jeff Brownb6997262010-10-08 22:31:17 -07003532 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3533 mKeyMementos.removeAt(i);
3534 } else {
3535 i += 1;
3536 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003537 }
3538
Jeff Browna1160a72010-10-11 18:22:53 -07003539 for (size_t i = 0; i < mMotionMementos.size(); ) {
Jeff Brownb88102f2010-09-08 11:49:43 -07003540 const MotionMemento& memento = mMotionMementos.itemAt(i);
Jeff Brown49ed71d2010-12-06 17:13:33 -08003541 if (shouldCancelMotion(memento, options)) {
Jeff Brownb6997262010-10-08 22:31:17 -07003542 outEvents.push(allocator->obtainMotionEntry(currentTime,
3543 memento.deviceId, memento.source, 0,
3544 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3545 memento.xPrecision, memento.yPrecision, memento.downTime,
3546 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3547 mMotionMementos.removeAt(i);
3548 } else {
3549 i += 1;
3550 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003551 }
3552}
3553
3554void InputDispatcher::InputState::clear() {
3555 mKeyMementos.clear();
3556 mMotionMementos.clear();
Jeff Brownb6997262010-10-08 22:31:17 -07003557}
3558
Jeff Brown9c9f1a32010-10-11 18:32:20 -07003559void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3560 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3561 const MotionMemento& memento = mMotionMementos.itemAt(i);
3562 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3563 for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3564 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3565 if (memento.deviceId == otherMemento.deviceId
3566 && memento.source == otherMemento.source) {
3567 other.mMotionMementos.removeAt(j);
3568 } else {
3569 j += 1;
3570 }
3571 }
3572 other.mMotionMementos.push(memento);
3573 }
3574 }
3575}
3576
Jeff Brown49ed71d2010-12-06 17:13:33 -08003577bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
Jeff Brownb6997262010-10-08 22:31:17 -07003578 CancelationOptions options) {
3579 switch (options) {
Jeff Brown49ed71d2010-12-06 17:13:33 -08003580 case CANCEL_ALL_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003581 case CANCEL_NON_POINTER_EVENTS:
Jeff Brownb6997262010-10-08 22:31:17 -07003582 return true;
Jeff Brown49ed71d2010-12-06 17:13:33 -08003583 case CANCEL_FALLBACK_EVENTS:
3584 return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
3585 default:
3586 return false;
3587 }
3588}
3589
3590bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
3591 CancelationOptions options) {
3592 switch (options) {
3593 case CANCEL_ALL_EVENTS:
3594 return true;
3595 case CANCEL_POINTER_EVENTS:
3596 return memento.source & AINPUT_SOURCE_CLASS_POINTER;
3597 case CANCEL_NON_POINTER_EVENTS:
3598 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
3599 default:
3600 return false;
Jeff Brownb6997262010-10-08 22:31:17 -07003601 }
Jeff Brownb88102f2010-09-08 11:49:43 -07003602}
3603
3604
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003605// --- InputDispatcher::Connection ---
3606
3607InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3608 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown519e0242010-09-15 15:18:56 -07003609 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003610}
3611
3612InputDispatcher::Connection::~Connection() {
3613}
3614
3615status_t InputDispatcher::Connection::initialize() {
3616 return inputPublisher.initialize();
3617}
3618
Jeff Brown9c3cda02010-06-15 01:31:58 -07003619const char* InputDispatcher::Connection::getStatusLabel() const {
3620 switch (status) {
3621 case STATUS_NORMAL:
3622 return "NORMAL";
3623
3624 case STATUS_BROKEN:
3625 return "BROKEN";
3626
Jeff Brown9c3cda02010-06-15 01:31:58 -07003627 case STATUS_ZOMBIE:
3628 return "ZOMBIE";
3629
3630 default:
3631 return "UNKNOWN";
3632 }
3633}
3634
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003635InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3636 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07003637 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3638 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003639 if (dispatchEntry->eventEntry == eventEntry) {
3640 return dispatchEntry;
3641 }
3642 }
3643 return NULL;
3644}
3645
Jeff Brownb88102f2010-09-08 11:49:43 -07003646
Jeff Brown9c3cda02010-06-15 01:31:58 -07003647// --- InputDispatcher::CommandEntry ---
3648
Jeff Brownb88102f2010-09-08 11:49:43 -07003649InputDispatcher::CommandEntry::CommandEntry() :
3650 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003651}
3652
3653InputDispatcher::CommandEntry::~CommandEntry() {
3654}
3655
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003656
Jeff Brown01ce2e92010-09-26 22:20:12 -07003657// --- InputDispatcher::TouchState ---
3658
3659InputDispatcher::TouchState::TouchState() :
Jeff Brown95712852011-01-04 19:41:59 -08003660 down(false), split(false), deviceId(-1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003661}
3662
3663InputDispatcher::TouchState::~TouchState() {
3664}
3665
3666void InputDispatcher::TouchState::reset() {
3667 down = false;
3668 split = false;
Jeff Brown95712852011-01-04 19:41:59 -08003669 deviceId = -1;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003670 windows.clear();
3671}
3672
3673void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3674 down = other.down;
3675 split = other.split;
Jeff Brown95712852011-01-04 19:41:59 -08003676 deviceId = other.deviceId;
Jeff Brown01ce2e92010-09-26 22:20:12 -07003677 windows.clear();
3678 windows.appendVector(other.windows);
3679}
3680
3681void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3682 int32_t targetFlags, BitSet32 pointerIds) {
3683 if (targetFlags & InputTarget::FLAG_SPLIT) {
3684 split = true;
3685 }
3686
3687 for (size_t i = 0; i < windows.size(); i++) {
3688 TouchedWindow& touchedWindow = windows.editItemAt(i);
3689 if (touchedWindow.window == window) {
3690 touchedWindow.targetFlags |= targetFlags;
3691 touchedWindow.pointerIds.value |= pointerIds.value;
3692 return;
3693 }
3694 }
3695
3696 windows.push();
3697
3698 TouchedWindow& touchedWindow = windows.editTop();
3699 touchedWindow.window = window;
3700 touchedWindow.targetFlags = targetFlags;
3701 touchedWindow.pointerIds = pointerIds;
3702 touchedWindow.channel = window->inputChannel;
3703}
3704
3705void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3706 for (size_t i = 0 ; i < windows.size(); ) {
3707 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3708 windows.removeAt(i);
3709 } else {
3710 i += 1;
3711 }
3712 }
3713}
3714
3715const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3716 for (size_t i = 0; i < windows.size(); i++) {
3717 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3718 return windows[i].window;
3719 }
3720 }
3721 return NULL;
3722}
3723
3724
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003725// --- InputDispatcherThread ---
3726
3727InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3728 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3729}
3730
3731InputDispatcherThread::~InputDispatcherThread() {
3732}
3733
3734bool InputDispatcherThread::threadLoop() {
3735 mDispatcher->dispatchOnce();
3736 return true;
3737}
3738
3739} // namespace android