InputDispatcher.cpp revision 8b4be56030c3b8c93dfa45bccac7365f90f377ce
1/*
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
17#define LOG_TAG "InputDispatcher"
18
19//#define LOG_NDEBUG 0
20
21// Log detailed debug messages about each inbound event notification to the dispatcher.
22#define DEBUG_INBOUND_EVENT_DETAILS 0
23
24// Log detailed debug messages about each outbound event processed by the dispatcher.
25#define DEBUG_OUTBOUND_EVENT_DETAILS 0
26
27// Log debug messages about the dispatch cycle.
28#define DEBUG_DISPATCH_CYCLE 0
29
30// Log debug messages about registrations.
31#define DEBUG_REGISTRATION 0
32
33// Log debug messages about input event injection.
34#define DEBUG_INJECTION 0
35
36// Log debug messages about input focus tracking.
37#define DEBUG_FOCUS 0
38
39// Log debug messages about the app switch latency optimization.
40#define DEBUG_APP_SWITCH 0
41
42// Log debug messages about hover events.
43#define DEBUG_HOVER 0
44
45#include "InputDispatcher.h"
46
47#include <cutils/log.h>
48#include <ui/PowerManager.h>
49
50#include <stddef.h>
51#include <unistd.h>
52#include <errno.h>
53#include <limits.h>
54
55#define INDENT "  "
56#define INDENT2 "    "
57
58namespace android {
59
60// Default input dispatching timeout if there is no focused application or paused window
61// from which to determine an appropriate dispatching timeout.
62const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
63
64// Amount of time to allow for all pending events to be processed when an app switch
65// key is on the way.  This is used to preempt input dispatch and drop input events
66// when an application takes too long to respond and the user has pressed an app switch key.
67const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
68
69// Amount of time to allow for an event to be dispatched (measured since its eventTime)
70// before considering it stale and dropping it.
71const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
72
73
74static inline nsecs_t now() {
75    return systemTime(SYSTEM_TIME_MONOTONIC);
76}
77
78static inline const char* toString(bool value) {
79    return value ? "true" : "false";
80}
81
82static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
83    return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
84            >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
85}
86
87static bool isValidKeyAction(int32_t action) {
88    switch (action) {
89    case AKEY_EVENT_ACTION_DOWN:
90    case AKEY_EVENT_ACTION_UP:
91        return true;
92    default:
93        return false;
94    }
95}
96
97static bool validateKeyEvent(int32_t action) {
98    if (! isValidKeyAction(action)) {
99        ALOGE("Key event has invalid action code 0x%x", action);
100        return false;
101    }
102    return true;
103}
104
105static bool isValidMotionAction(int32_t action, size_t pointerCount) {
106    switch (action & AMOTION_EVENT_ACTION_MASK) {
107    case AMOTION_EVENT_ACTION_DOWN:
108    case AMOTION_EVENT_ACTION_UP:
109    case AMOTION_EVENT_ACTION_CANCEL:
110    case AMOTION_EVENT_ACTION_MOVE:
111    case AMOTION_EVENT_ACTION_OUTSIDE:
112    case AMOTION_EVENT_ACTION_HOVER_ENTER:
113    case AMOTION_EVENT_ACTION_HOVER_MOVE:
114    case AMOTION_EVENT_ACTION_HOVER_EXIT:
115    case AMOTION_EVENT_ACTION_SCROLL:
116        return true;
117    case AMOTION_EVENT_ACTION_POINTER_DOWN:
118    case AMOTION_EVENT_ACTION_POINTER_UP: {
119        int32_t index = getMotionEventActionPointerIndex(action);
120        return index >= 0 && size_t(index) < pointerCount;
121    }
122    default:
123        return false;
124    }
125}
126
127static bool validateMotionEvent(int32_t action, size_t pointerCount,
128        const PointerProperties* pointerProperties) {
129    if (! isValidMotionAction(action, pointerCount)) {
130        ALOGE("Motion event has invalid action code 0x%x", action);
131        return false;
132    }
133    if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
134        ALOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
135                pointerCount, MAX_POINTERS);
136        return false;
137    }
138    BitSet32 pointerIdBits;
139    for (size_t i = 0; i < pointerCount; i++) {
140        int32_t id = pointerProperties[i].id;
141        if (id < 0 || id > MAX_POINTER_ID) {
142            ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
143                    id, MAX_POINTER_ID);
144            return false;
145        }
146        if (pointerIdBits.hasBit(id)) {
147            ALOGE("Motion event has duplicate pointer id %d", id);
148            return false;
149        }
150        pointerIdBits.markBit(id);
151    }
152    return true;
153}
154
155static void dumpRegion(String8& dump, const SkRegion& region) {
156    if (region.isEmpty()) {
157        dump.append("<empty>");
158        return;
159    }
160
161    bool first = true;
162    for (SkRegion::Iterator it(region); !it.done(); it.next()) {
163        if (first) {
164            first = false;
165        } else {
166            dump.append("|");
167        }
168        const SkIRect& rect = it.rect();
169        dump.appendFormat("[%d,%d][%d,%d]", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
170    }
171}
172
173
174// --- InputDispatcher ---
175
176InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
177    mPolicy(policy),
178    mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
179    mNextUnblockedEvent(NULL),
180    mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false),
181    mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
182    mLooper = new Looper(false);
183
184    mKeyRepeatState.lastKeyEntry = NULL;
185
186    policy->getDispatcherConfiguration(&mConfig);
187}
188
189InputDispatcher::~InputDispatcher() {
190    { // acquire lock
191        AutoMutex _l(mLock);
192
193        resetKeyRepeatLocked();
194        releasePendingEventLocked();
195        drainInboundQueueLocked();
196    }
197
198    while (mConnectionsByFd.size() != 0) {
199        unregisterInputChannel(mConnectionsByFd.valueAt(0)->inputChannel);
200    }
201}
202
203void InputDispatcher::dispatchOnce() {
204    nsecs_t nextWakeupTime = LONG_LONG_MAX;
205    { // acquire lock
206        AutoMutex _l(mLock);
207        mDispatcherIsAliveCondition.broadcast();
208
209        dispatchOnceInnerLocked(&nextWakeupTime);
210
211        if (runCommandsLockedInterruptible()) {
212            nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately
213        }
214    } // release lock
215
216    // Wait for callback or timeout or wake.  (make sure we round up, not down)
217    nsecs_t currentTime = now();
218    int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
219    mLooper->pollOnce(timeoutMillis);
220}
221
222void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
223    nsecs_t currentTime = now();
224
225    // Reset the key repeat timer whenever we disallow key events, even if the next event
226    // is not a key.  This is to ensure that we abort a key repeat if the device is just coming
227    // out of sleep.
228    if (!mPolicy->isKeyRepeatEnabled()) {
229        resetKeyRepeatLocked();
230    }
231
232    // If dispatching is frozen, do not process timeouts or try to deliver any new events.
233    if (mDispatchFrozen) {
234#if DEBUG_FOCUS
235        ALOGD("Dispatch frozen.  Waiting some more.");
236#endif
237        return;
238    }
239
240    // Optimize latency of app switches.
241    // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
242    // been pressed.  When it expires, we preempt dispatch and drop all other pending events.
243    bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
244    if (mAppSwitchDueTime < *nextWakeupTime) {
245        *nextWakeupTime = mAppSwitchDueTime;
246    }
247
248    // Ready to start a new event.
249    // If we don't already have a pending event, go grab one.
250    if (! mPendingEvent) {
251        if (mInboundQueue.isEmpty()) {
252            if (isAppSwitchDue) {
253                // The inbound queue is empty so the app switch key we were waiting
254                // for will never arrive.  Stop waiting for it.
255                resetPendingAppSwitchLocked(false);
256                isAppSwitchDue = false;
257            }
258
259            // Synthesize a key repeat if appropriate.
260            if (mKeyRepeatState.lastKeyEntry) {
261                if (currentTime >= mKeyRepeatState.nextRepeatTime) {
262                    mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
263                } else {
264                    if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
265                        *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
266                    }
267                }
268            }
269
270            // Nothing to do if there is no pending event.
271            if (!mPendingEvent) {
272                return;
273            }
274        } else {
275            // Inbound queue has at least one entry.
276            mPendingEvent = mInboundQueue.dequeueAtHead();
277        }
278
279        // Poke user activity for this event.
280        if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
281            pokeUserActivityLocked(mPendingEvent);
282        }
283
284        // Get ready to dispatch the event.
285        resetANRTimeoutsLocked();
286    }
287
288    // Now we have an event to dispatch.
289    // All events are eventually dequeued and processed this way, even if we intend to drop them.
290    ALOG_ASSERT(mPendingEvent != NULL);
291    bool done = false;
292    DropReason dropReason = DROP_REASON_NOT_DROPPED;
293    if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
294        dropReason = DROP_REASON_POLICY;
295    } else if (!mDispatchEnabled) {
296        dropReason = DROP_REASON_DISABLED;
297    }
298
299    if (mNextUnblockedEvent == mPendingEvent) {
300        mNextUnblockedEvent = NULL;
301    }
302
303    switch (mPendingEvent->type) {
304    case EventEntry::TYPE_CONFIGURATION_CHANGED: {
305        ConfigurationChangedEntry* typedEntry =
306                static_cast<ConfigurationChangedEntry*>(mPendingEvent);
307        done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
308        dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
309        break;
310    }
311
312    case EventEntry::TYPE_DEVICE_RESET: {
313        DeviceResetEntry* typedEntry =
314                static_cast<DeviceResetEntry*>(mPendingEvent);
315        done = dispatchDeviceResetLocked(currentTime, typedEntry);
316        dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
317        break;
318    }
319
320    case EventEntry::TYPE_KEY: {
321        KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
322        if (isAppSwitchDue) {
323            if (isAppSwitchKeyEventLocked(typedEntry)) {
324                resetPendingAppSwitchLocked(true);
325                isAppSwitchDue = false;
326            } else if (dropReason == DROP_REASON_NOT_DROPPED) {
327                dropReason = DROP_REASON_APP_SWITCH;
328            }
329        }
330        if (dropReason == DROP_REASON_NOT_DROPPED
331                && isStaleEventLocked(currentTime, typedEntry)) {
332            dropReason = DROP_REASON_STALE;
333        }
334        if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
335            dropReason = DROP_REASON_BLOCKED;
336        }
337        done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
338        break;
339    }
340
341    case EventEntry::TYPE_MOTION: {
342        MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
343        if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
344            dropReason = DROP_REASON_APP_SWITCH;
345        }
346        if (dropReason == DROP_REASON_NOT_DROPPED
347                && isStaleEventLocked(currentTime, typedEntry)) {
348            dropReason = DROP_REASON_STALE;
349        }
350        if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
351            dropReason = DROP_REASON_BLOCKED;
352        }
353        done = dispatchMotionLocked(currentTime, typedEntry,
354                &dropReason, nextWakeupTime);
355        break;
356    }
357
358    default:
359        ALOG_ASSERT(false);
360        break;
361    }
362
363    if (done) {
364        if (dropReason != DROP_REASON_NOT_DROPPED) {
365            dropInboundEventLocked(mPendingEvent, dropReason);
366        }
367
368        releasePendingEventLocked();
369        *nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately
370    }
371}
372
373bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
374    bool needWake = mInboundQueue.isEmpty();
375    mInboundQueue.enqueueAtTail(entry);
376
377    switch (entry->type) {
378    case EventEntry::TYPE_KEY: {
379        // Optimize app switch latency.
380        // If the application takes too long to catch up then we drop all events preceding
381        // the app switch key.
382        KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
383        if (isAppSwitchKeyEventLocked(keyEntry)) {
384            if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
385                mAppSwitchSawKeyDown = true;
386            } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
387                if (mAppSwitchSawKeyDown) {
388#if DEBUG_APP_SWITCH
389                    ALOGD("App switch is pending!");
390#endif
391                    mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
392                    mAppSwitchSawKeyDown = false;
393                    needWake = true;
394                }
395            }
396        }
397        break;
398    }
399
400    case EventEntry::TYPE_MOTION: {
401        // Optimize case where the current application is unresponsive and the user
402        // decides to touch a window in a different application.
403        // If the application takes too long to catch up then we drop all events preceding
404        // the touch into the other window.
405        MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
406        if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
407                && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
408                && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
409                && mInputTargetWaitApplicationHandle != NULL) {
410            int32_t x = int32_t(motionEntry->pointerCoords[0].
411                    getAxisValue(AMOTION_EVENT_AXIS_X));
412            int32_t y = int32_t(motionEntry->pointerCoords[0].
413                    getAxisValue(AMOTION_EVENT_AXIS_Y));
414            sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(x, y);
415            if (touchedWindowHandle != NULL
416                    && touchedWindowHandle->inputApplicationHandle
417                            != mInputTargetWaitApplicationHandle) {
418                // User touched a different application than the one we are waiting on.
419                // Flag the event, and start pruning the input queue.
420                mNextUnblockedEvent = motionEntry;
421                needWake = true;
422            }
423        }
424        break;
425    }
426    }
427
428    return needWake;
429}
430
431sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
432    // Traverse windows from front to back to find touched window.
433    size_t numWindows = mWindowHandles.size();
434    for (size_t i = 0; i < numWindows; i++) {
435        sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
436        const InputWindowInfo* windowInfo = windowHandle->getInfo();
437        int32_t flags = windowInfo->layoutParamsFlags;
438
439        if (windowInfo->visible) {
440            if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
441                bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
442                        | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
443                if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
444                    // Found window.
445                    return windowHandle;
446                }
447            }
448        }
449
450        if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
451            // Error window is on top but not visible, so touch is dropped.
452            return NULL;
453        }
454    }
455    return NULL;
456}
457
458void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
459    const char* reason;
460    switch (dropReason) {
461    case DROP_REASON_POLICY:
462#if DEBUG_INBOUND_EVENT_DETAILS
463        ALOGD("Dropped event because policy consumed it.");
464#endif
465        reason = "inbound event was dropped because the policy consumed it";
466        break;
467    case DROP_REASON_DISABLED:
468        ALOGI("Dropped event because input dispatch is disabled.");
469        reason = "inbound event was dropped because input dispatch is disabled";
470        break;
471    case DROP_REASON_APP_SWITCH:
472        ALOGI("Dropped event because of pending overdue app switch.");
473        reason = "inbound event was dropped because of pending overdue app switch";
474        break;
475    case DROP_REASON_BLOCKED:
476        ALOGI("Dropped event because the current application is not responding and the user "
477                "has started interacting with a different application.");
478        reason = "inbound event was dropped because the current application is not responding "
479                "and the user has started interacting with a different application";
480        break;
481    case DROP_REASON_STALE:
482        ALOGI("Dropped event because it is stale.");
483        reason = "inbound event was dropped because it is stale";
484        break;
485    default:
486        ALOG_ASSERT(false);
487        return;
488    }
489
490    switch (entry->type) {
491    case EventEntry::TYPE_KEY: {
492        CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
493        synthesizeCancelationEventsForAllConnectionsLocked(options);
494        break;
495    }
496    case EventEntry::TYPE_MOTION: {
497        MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
498        if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
499            CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
500            synthesizeCancelationEventsForAllConnectionsLocked(options);
501        } else {
502            CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
503            synthesizeCancelationEventsForAllConnectionsLocked(options);
504        }
505        break;
506    }
507    }
508}
509
510bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
511    return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
512}
513
514bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
515    return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
516            && isAppSwitchKeyCode(keyEntry->keyCode)
517            && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
518            && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
519}
520
521bool InputDispatcher::isAppSwitchPendingLocked() {
522    return mAppSwitchDueTime != LONG_LONG_MAX;
523}
524
525void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
526    mAppSwitchDueTime = LONG_LONG_MAX;
527
528#if DEBUG_APP_SWITCH
529    if (handled) {
530        ALOGD("App switch has arrived.");
531    } else {
532        ALOGD("App switch was abandoned.");
533    }
534#endif
535}
536
537bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
538    return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
539}
540
541bool InputDispatcher::runCommandsLockedInterruptible() {
542    if (mCommandQueue.isEmpty()) {
543        return false;
544    }
545
546    do {
547        CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
548
549        Command command = commandEntry->command;
550        (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
551
552        commandEntry->connection.clear();
553        delete commandEntry;
554    } while (! mCommandQueue.isEmpty());
555    return true;
556}
557
558InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
559    CommandEntry* commandEntry = new CommandEntry(command);
560    mCommandQueue.enqueueAtTail(commandEntry);
561    return commandEntry;
562}
563
564void InputDispatcher::drainInboundQueueLocked() {
565    while (! mInboundQueue.isEmpty()) {
566        EventEntry* entry = mInboundQueue.dequeueAtHead();
567        releaseInboundEventLocked(entry);
568    }
569}
570
571void InputDispatcher::releasePendingEventLocked() {
572    if (mPendingEvent) {
573        resetANRTimeoutsLocked();
574        releaseInboundEventLocked(mPendingEvent);
575        mPendingEvent = NULL;
576    }
577}
578
579void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
580    InjectionState* injectionState = entry->injectionState;
581    if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
582#if DEBUG_DISPATCH_CYCLE
583        ALOGD("Injected inbound event was dropped.");
584#endif
585        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
586    }
587    if (entry == mNextUnblockedEvent) {
588        mNextUnblockedEvent = NULL;
589    }
590    entry->release();
591}
592
593void InputDispatcher::resetKeyRepeatLocked() {
594    if (mKeyRepeatState.lastKeyEntry) {
595        mKeyRepeatState.lastKeyEntry->release();
596        mKeyRepeatState.lastKeyEntry = NULL;
597    }
598}
599
600InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
601    KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
602
603    // Reuse the repeated key entry if it is otherwise unreferenced.
604    uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
605            | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
606    if (entry->refCount == 1) {
607        entry->recycle();
608        entry->eventTime = currentTime;
609        entry->policyFlags = policyFlags;
610        entry->repeatCount += 1;
611    } else {
612        KeyEntry* newEntry = new KeyEntry(currentTime,
613                entry->deviceId, entry->source, policyFlags,
614                entry->action, entry->flags, entry->keyCode, entry->scanCode,
615                entry->metaState, entry->repeatCount + 1, entry->downTime);
616
617        mKeyRepeatState.lastKeyEntry = newEntry;
618        entry->release();
619
620        entry = newEntry;
621    }
622    entry->syntheticRepeat = true;
623
624    // Increment reference count since we keep a reference to the event in
625    // mKeyRepeatState.lastKeyEntry in addition to the one we return.
626    entry->refCount += 1;
627
628    mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
629    return entry;
630}
631
632bool InputDispatcher::dispatchConfigurationChangedLocked(
633        nsecs_t currentTime, ConfigurationChangedEntry* entry) {
634#if DEBUG_OUTBOUND_EVENT_DETAILS
635    ALOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
636#endif
637
638    // Reset key repeating in case a keyboard device was added or removed or something.
639    resetKeyRepeatLocked();
640
641    // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
642    CommandEntry* commandEntry = postCommandLocked(
643            & InputDispatcher::doNotifyConfigurationChangedInterruptible);
644    commandEntry->eventTime = entry->eventTime;
645    return true;
646}
647
648bool InputDispatcher::dispatchDeviceResetLocked(
649        nsecs_t currentTime, DeviceResetEntry* entry) {
650#if DEBUG_OUTBOUND_EVENT_DETAILS
651    ALOGD("dispatchDeviceReset - eventTime=%lld, deviceId=%d", entry->eventTime, entry->deviceId);
652#endif
653
654    CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
655            "device was reset");
656    options.deviceId = entry->deviceId;
657    synthesizeCancelationEventsForAllConnectionsLocked(options);
658    return true;
659}
660
661bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
662        DropReason* dropReason, nsecs_t* nextWakeupTime) {
663    // Preprocessing.
664    if (! entry->dispatchInProgress) {
665        if (entry->repeatCount == 0
666                && entry->action == AKEY_EVENT_ACTION_DOWN
667                && (entry->policyFlags & POLICY_FLAG_TRUSTED)
668                && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
669            if (mKeyRepeatState.lastKeyEntry
670                    && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
671                // We have seen two identical key downs in a row which indicates that the device
672                // driver is automatically generating key repeats itself.  We take note of the
673                // repeat here, but we disable our own next key repeat timer since it is clear that
674                // we will not need to synthesize key repeats ourselves.
675                entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
676                resetKeyRepeatLocked();
677                mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
678            } else {
679                // Not a repeat.  Save key down state in case we do see a repeat later.
680                resetKeyRepeatLocked();
681                mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
682            }
683            mKeyRepeatState.lastKeyEntry = entry;
684            entry->refCount += 1;
685        } else if (! entry->syntheticRepeat) {
686            resetKeyRepeatLocked();
687        }
688
689        if (entry->repeatCount == 1) {
690            entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
691        } else {
692            entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
693        }
694
695        entry->dispatchInProgress = true;
696
697        logOutboundKeyDetailsLocked("dispatchKey - ", entry);
698    }
699
700    // Handle case where the policy asked us to try again later last time.
701    if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
702        if (currentTime < entry->interceptKeyWakeupTime) {
703            if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
704                *nextWakeupTime = entry->interceptKeyWakeupTime;
705            }
706            return false; // wait until next wakeup
707        }
708        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
709        entry->interceptKeyWakeupTime = 0;
710    }
711
712    // Give the policy a chance to intercept the key.
713    if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
714        if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
715            CommandEntry* commandEntry = postCommandLocked(
716                    & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
717            if (mFocusedWindowHandle != NULL) {
718                commandEntry->inputWindowHandle = mFocusedWindowHandle;
719            }
720            commandEntry->keyEntry = entry;
721            entry->refCount += 1;
722            return false; // wait for the command to run
723        } else {
724            entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
725        }
726    } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
727        if (*dropReason == DROP_REASON_NOT_DROPPED) {
728            *dropReason = DROP_REASON_POLICY;
729        }
730    }
731
732    // Clean up if dropping the event.
733    if (*dropReason != DROP_REASON_NOT_DROPPED) {
734        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
735                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
736        return true;
737    }
738
739    // Identify targets.
740    Vector<InputTarget> inputTargets;
741    int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
742            entry, inputTargets, nextWakeupTime);
743    if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
744        return false;
745    }
746
747    setInjectionResultLocked(entry, injectionResult);
748    if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
749        return true;
750    }
751
752    addMonitoringTargetsLocked(inputTargets);
753
754    // Dispatch the key.
755    dispatchEventLocked(currentTime, entry, inputTargets);
756    return true;
757}
758
759void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
760#if DEBUG_OUTBOUND_EVENT_DETAILS
761    ALOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
762            "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
763            "repeatCount=%d, downTime=%lld",
764            prefix,
765            entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
766            entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
767            entry->repeatCount, entry->downTime);
768#endif
769}
770
771bool InputDispatcher::dispatchMotionLocked(
772        nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
773    // Preprocessing.
774    if (! entry->dispatchInProgress) {
775        entry->dispatchInProgress = true;
776
777        logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
778    }
779
780    // Clean up if dropping the event.
781    if (*dropReason != DROP_REASON_NOT_DROPPED) {
782        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
783                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
784        return true;
785    }
786
787    bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
788
789    // Identify targets.
790    Vector<InputTarget> inputTargets;
791
792    bool conflictingPointerActions = false;
793    int32_t injectionResult;
794    if (isPointerEvent) {
795        // Pointer event.  (eg. touchscreen)
796        injectionResult = findTouchedWindowTargetsLocked(currentTime,
797                entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
798    } else {
799        // Non touch event.  (eg. trackball)
800        injectionResult = findFocusedWindowTargetsLocked(currentTime,
801                entry, inputTargets, nextWakeupTime);
802    }
803    if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
804        return false;
805    }
806
807    setInjectionResultLocked(entry, injectionResult);
808    if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
809        return true;
810    }
811
812    addMonitoringTargetsLocked(inputTargets);
813
814    // Dispatch the motion.
815    if (conflictingPointerActions) {
816        CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
817                "conflicting pointer actions");
818        synthesizeCancelationEventsForAllConnectionsLocked(options);
819    }
820    dispatchEventLocked(currentTime, entry, inputTargets);
821    return true;
822}
823
824
825void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
826#if DEBUG_OUTBOUND_EVENT_DETAILS
827    ALOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
828            "action=0x%x, flags=0x%x, "
829            "metaState=0x%x, buttonState=0x%x, "
830            "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
831            prefix,
832            entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
833            entry->action, entry->flags,
834            entry->metaState, entry->buttonState,
835            entry->edgeFlags, entry->xPrecision, entry->yPrecision,
836            entry->downTime);
837
838    for (uint32_t i = 0; i < entry->pointerCount; i++) {
839        ALOGD("  Pointer %d: id=%d, toolType=%d, "
840                "x=%f, y=%f, pressure=%f, size=%f, "
841                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
842                "orientation=%f",
843                i, entry->pointerProperties[i].id,
844                entry->pointerProperties[i].toolType,
845                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
846                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
847                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
848                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
849                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
850                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
851                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
852                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
853                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
854    }
855#endif
856}
857
858void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
859        EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
860#if DEBUG_DISPATCH_CYCLE
861    ALOGD("dispatchEventToCurrentInputTargets");
862#endif
863
864    ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
865
866    pokeUserActivityLocked(eventEntry);
867
868    for (size_t i = 0; i < inputTargets.size(); i++) {
869        const InputTarget& inputTarget = inputTargets.itemAt(i);
870
871        ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
872        if (connectionIndex >= 0) {
873            sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
874            prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
875        } else {
876#if DEBUG_FOCUS
877            ALOGD("Dropping event delivery to target with channel '%s' because it "
878                    "is no longer registered with the input dispatcher.",
879                    inputTarget.inputChannel->getName().string());
880#endif
881        }
882    }
883}
884
885int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
886        const EventEntry* entry,
887        const sp<InputApplicationHandle>& applicationHandle,
888        const sp<InputWindowHandle>& windowHandle,
889        nsecs_t* nextWakeupTime) {
890    if (applicationHandle == NULL && windowHandle == NULL) {
891        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
892#if DEBUG_FOCUS
893            ALOGD("Waiting for system to become ready for input.");
894#endif
895            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
896            mInputTargetWaitStartTime = currentTime;
897            mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
898            mInputTargetWaitTimeoutExpired = false;
899            mInputTargetWaitApplicationHandle.clear();
900        }
901    } else {
902        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
903#if DEBUG_FOCUS
904            ALOGD("Waiting for application to become ready for input: %s",
905                    getApplicationWindowLabelLocked(applicationHandle, windowHandle).string());
906#endif
907            nsecs_t timeout;
908            if (windowHandle != NULL) {
909                timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
910            } else if (applicationHandle != NULL) {
911                timeout = applicationHandle->getDispatchingTimeout(
912                        DEFAULT_INPUT_DISPATCHING_TIMEOUT);
913            } else {
914                timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
915            }
916
917            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
918            mInputTargetWaitStartTime = currentTime;
919            mInputTargetWaitTimeoutTime = currentTime + timeout;
920            mInputTargetWaitTimeoutExpired = false;
921            mInputTargetWaitApplicationHandle.clear();
922
923            if (windowHandle != NULL) {
924                mInputTargetWaitApplicationHandle = windowHandle->inputApplicationHandle;
925            }
926            if (mInputTargetWaitApplicationHandle == NULL && applicationHandle != NULL) {
927                mInputTargetWaitApplicationHandle = applicationHandle;
928            }
929        }
930    }
931
932    if (mInputTargetWaitTimeoutExpired) {
933        return INPUT_EVENT_INJECTION_TIMED_OUT;
934    }
935
936    if (currentTime >= mInputTargetWaitTimeoutTime) {
937        onANRLocked(currentTime, applicationHandle, windowHandle,
938                entry->eventTime, mInputTargetWaitStartTime);
939
940        // Force poll loop to wake up immediately on next iteration once we get the
941        // ANR response back from the policy.
942        *nextWakeupTime = LONG_LONG_MIN;
943        return INPUT_EVENT_INJECTION_PENDING;
944    } else {
945        // Force poll loop to wake up when timeout is due.
946        if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
947            *nextWakeupTime = mInputTargetWaitTimeoutTime;
948        }
949        return INPUT_EVENT_INJECTION_PENDING;
950    }
951}
952
953void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
954        const sp<InputChannel>& inputChannel) {
955    if (newTimeout > 0) {
956        // Extend the timeout.
957        mInputTargetWaitTimeoutTime = now() + newTimeout;
958    } else {
959        // Give up.
960        mInputTargetWaitTimeoutExpired = true;
961
962        // Release the touch targets.
963        mTouchState.reset();
964
965        // Input state will not be realistic.  Mark it out of sync.
966        if (inputChannel.get()) {
967            ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
968            if (connectionIndex >= 0) {
969                sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
970                if (connection->status == Connection::STATUS_NORMAL) {
971                    CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
972                            "application not responding");
973                    synthesizeCancelationEventsForConnectionLocked(connection, options);
974                }
975            }
976        }
977    }
978}
979
980nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
981        nsecs_t currentTime) {
982    if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
983        return currentTime - mInputTargetWaitStartTime;
984    }
985    return 0;
986}
987
988void InputDispatcher::resetANRTimeoutsLocked() {
989#if DEBUG_FOCUS
990        ALOGD("Resetting ANR timeouts.");
991#endif
992
993    // Reset input target wait timeout.
994    mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
995    mInputTargetWaitApplicationHandle.clear();
996}
997
998int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
999        const EventEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
1000    int32_t injectionResult;
1001
1002    // If there is no currently focused window and no focused application
1003    // then drop the event.
1004    if (mFocusedWindowHandle == NULL) {
1005        if (mFocusedApplicationHandle != NULL) {
1006#if DEBUG_FOCUS
1007            ALOGD("Waiting because there is no focused window but there is a "
1008                    "focused application that may eventually add a window: %s.",
1009                    getApplicationWindowLabelLocked(mFocusedApplicationHandle, NULL).string());
1010#endif
1011            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1012                    mFocusedApplicationHandle, NULL, nextWakeupTime);
1013            goto Unresponsive;
1014        }
1015
1016        ALOGI("Dropping event because there is no focused window or focused application.");
1017        injectionResult = INPUT_EVENT_INJECTION_FAILED;
1018        goto Failed;
1019    }
1020
1021    // Check permissions.
1022    if (! checkInjectionPermission(mFocusedWindowHandle, entry->injectionState)) {
1023        injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1024        goto Failed;
1025    }
1026
1027    // If the currently focused window is paused then keep waiting.
1028    if (mFocusedWindowHandle->getInfo()->paused) {
1029#if DEBUG_FOCUS
1030        ALOGD("Waiting because focused window is paused.");
1031#endif
1032        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1033                mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime);
1034        goto Unresponsive;
1035    }
1036
1037    // If the currently focused window is still working on previous events then keep waiting.
1038    if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindowHandle)) {
1039#if DEBUG_FOCUS
1040        ALOGD("Waiting because focused window still processing previous input.");
1041#endif
1042        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1043                mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime);
1044        goto Unresponsive;
1045    }
1046
1047    // Success!  Output targets.
1048    injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1049    addWindowTargetLocked(mFocusedWindowHandle,
1050            InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
1051            inputTargets);
1052
1053    // Done.
1054Failed:
1055Unresponsive:
1056    nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1057    updateDispatchStatisticsLocked(currentTime, entry,
1058            injectionResult, timeSpentWaitingForApplication);
1059#if DEBUG_FOCUS
1060    ALOGD("findFocusedWindow finished: injectionResult=%d, "
1061            "timeSpendWaitingForApplication=%0.1fms",
1062            injectionResult, timeSpentWaitingForApplication / 1000000.0);
1063#endif
1064    return injectionResult;
1065}
1066
1067int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1068        const MotionEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
1069        bool* outConflictingPointerActions) {
1070    enum InjectionPermission {
1071        INJECTION_PERMISSION_UNKNOWN,
1072        INJECTION_PERMISSION_GRANTED,
1073        INJECTION_PERMISSION_DENIED
1074    };
1075
1076    nsecs_t startTime = now();
1077
1078    // For security reasons, we defer updating the touch state until we are sure that
1079    // event injection will be allowed.
1080    //
1081    // FIXME In the original code, screenWasOff could never be set to true.
1082    //       The reason is that the POLICY_FLAG_WOKE_HERE
1083    //       and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1084    //       EV_KEY, EV_REL and EV_ABS events.  As it happens, the touch event was
1085    //       actually enqueued using the policyFlags that appeared in the final EV_SYN
1086    //       events upon which no preprocessing took place.  So policyFlags was always 0.
1087    //       In the new native input dispatcher we're a bit more careful about event
1088    //       preprocessing so the touches we receive can actually have non-zero policyFlags.
1089    //       Unfortunately we obtain undesirable behavior.
1090    //
1091    //       Here's what happens:
1092    //
1093    //       When the device dims in anticipation of going to sleep, touches
1094    //       in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1095    //       the device to brighten and reset the user activity timer.
1096    //       Touches on other windows (such as the launcher window)
1097    //       are dropped.  Then after a moment, the device goes to sleep.  Oops.
1098    //
1099    //       Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1100    //       instead of POLICY_FLAG_WOKE_HERE...
1101    //
1102    bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1103
1104    int32_t action = entry->action;
1105    int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1106
1107    // Update the touch state as needed based on the properties of the touch event.
1108    int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1109    InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1110    sp<InputWindowHandle> newHoverWindowHandle;
1111
1112    bool isSplit = mTouchState.split;
1113    bool switchedDevice = mTouchState.deviceId >= 0
1114            && (mTouchState.deviceId != entry->deviceId
1115                    || mTouchState.source != entry->source);
1116    bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1117            || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1118            || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1119    bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
1120            || maskedAction == AMOTION_EVENT_ACTION_SCROLL
1121            || isHoverAction);
1122    bool wrongDevice = false;
1123    if (newGesture) {
1124        bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
1125        if (switchedDevice && mTouchState.down && !down) {
1126#if DEBUG_FOCUS
1127            ALOGD("Dropping event because a pointer for a different device is already down.");
1128#endif
1129            mTempTouchState.copyFrom(mTouchState);
1130            injectionResult = INPUT_EVENT_INJECTION_FAILED;
1131            switchedDevice = false;
1132            wrongDevice = true;
1133            goto Failed;
1134        }
1135        mTempTouchState.reset();
1136        mTempTouchState.down = down;
1137        mTempTouchState.deviceId = entry->deviceId;
1138        mTempTouchState.source = entry->source;
1139        isSplit = false;
1140    } else {
1141        mTempTouchState.copyFrom(mTouchState);
1142    }
1143
1144    if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1145        /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1146
1147        int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1148        int32_t x = int32_t(entry->pointerCoords[pointerIndex].
1149                getAxisValue(AMOTION_EVENT_AXIS_X));
1150        int32_t y = int32_t(entry->pointerCoords[pointerIndex].
1151                getAxisValue(AMOTION_EVENT_AXIS_Y));
1152        sp<InputWindowHandle> newTouchedWindowHandle;
1153        sp<InputWindowHandle> topErrorWindowHandle;
1154        bool isTouchModal = false;
1155
1156        // Traverse windows from front to back to find touched window and outside targets.
1157        size_t numWindows = mWindowHandles.size();
1158        for (size_t i = 0; i < numWindows; i++) {
1159            sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
1160            const InputWindowInfo* windowInfo = windowHandle->getInfo();
1161            int32_t flags = windowInfo->layoutParamsFlags;
1162
1163            if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
1164                if (topErrorWindowHandle == NULL) {
1165                    topErrorWindowHandle = windowHandle;
1166                }
1167            }
1168
1169            if (windowInfo->visible) {
1170                if (! (flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
1171                    isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
1172                            | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
1173                    if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
1174                        if (! screenWasOff
1175                                || (flags & InputWindowInfo::FLAG_TOUCHABLE_WHEN_WAKING)) {
1176                            newTouchedWindowHandle = windowHandle;
1177                        }
1178                        break; // found touched window, exit window loop
1179                    }
1180                }
1181
1182                if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1183                        && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
1184                    int32_t outsideTargetFlags = InputTarget::FLAG_DISPATCH_AS_OUTSIDE;
1185                    if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
1186                        outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1187                    }
1188
1189                    mTempTouchState.addOrUpdateWindow(
1190                            windowHandle, outsideTargetFlags, BitSet32(0));
1191                }
1192            }
1193        }
1194
1195        // If there is an error window but it is not taking focus (typically because
1196        // it is invisible) then wait for it.  Any other focused window may in
1197        // fact be in ANR state.
1198        if (topErrorWindowHandle != NULL && newTouchedWindowHandle != topErrorWindowHandle) {
1199#if DEBUG_FOCUS
1200            ALOGD("Waiting because system error window is pending.");
1201#endif
1202            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1203                    NULL, NULL, nextWakeupTime);
1204            injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1205            goto Unresponsive;
1206        }
1207
1208        // Figure out whether splitting will be allowed for this window.
1209        if (newTouchedWindowHandle != NULL
1210                && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1211            // New window supports splitting.
1212            isSplit = true;
1213        } else if (isSplit) {
1214            // New window does not support splitting but we have already split events.
1215            // Assign the pointer to the first foreground window we find.
1216            // (May be NULL which is why we put this code block before the next check.)
1217            newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
1218        }
1219
1220        // If we did not find a touched window then fail.
1221        if (newTouchedWindowHandle == NULL) {
1222            if (mFocusedApplicationHandle != NULL) {
1223#if DEBUG_FOCUS
1224                ALOGD("Waiting because there is no touched window but there is a "
1225                        "focused application that may eventually add a new window: %s.",
1226                        getApplicationWindowLabelLocked(mFocusedApplicationHandle, NULL).string());
1227#endif
1228                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1229                        mFocusedApplicationHandle, NULL, nextWakeupTime);
1230                goto Unresponsive;
1231            }
1232
1233            ALOGI("Dropping event because there is no touched window or focused application.");
1234            injectionResult = INPUT_EVENT_INJECTION_FAILED;
1235            goto Failed;
1236        }
1237
1238        // Set target flags.
1239        int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1240        if (isSplit) {
1241            targetFlags |= InputTarget::FLAG_SPLIT;
1242        }
1243        if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1244            targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1245        }
1246
1247        // Update hover state.
1248        if (isHoverAction) {
1249            newHoverWindowHandle = newTouchedWindowHandle;
1250        } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1251            newHoverWindowHandle = mLastHoverWindowHandle;
1252        }
1253
1254        // Update the temporary touch state.
1255        BitSet32 pointerIds;
1256        if (isSplit) {
1257            uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1258            pointerIds.markBit(pointerId);
1259        }
1260        mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1261    } else {
1262        /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1263
1264        // If the pointer is not currently down, then ignore the event.
1265        if (! mTempTouchState.down) {
1266#if DEBUG_FOCUS
1267            ALOGD("Dropping event because the pointer is not down or we previously "
1268                    "dropped the pointer down event.");
1269#endif
1270            injectionResult = INPUT_EVENT_INJECTION_FAILED;
1271            goto Failed;
1272        }
1273
1274        // Check whether touches should slip outside of the current foreground window.
1275        if (maskedAction == AMOTION_EVENT_ACTION_MOVE
1276                && entry->pointerCount == 1
1277                && mTempTouchState.isSlippery()) {
1278            int32_t x = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1279            int32_t y = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
1280
1281            sp<InputWindowHandle> oldTouchedWindowHandle =
1282                    mTempTouchState.getFirstForegroundWindowHandle();
1283            sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(x, y);
1284            if (oldTouchedWindowHandle != newTouchedWindowHandle
1285                    && newTouchedWindowHandle != NULL) {
1286#if DEBUG_FOCUS
1287                ALOGD("Touch is slipping out of window %s into window %s.",
1288                        oldTouchedWindowHandle->getName().string(),
1289                        newTouchedWindowHandle->getName().string());
1290#endif
1291                // Make a slippery exit from the old window.
1292                mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
1293                        InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
1294
1295                // Make a slippery entrance into the new window.
1296                if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
1297                    isSplit = true;
1298                }
1299
1300                int32_t targetFlags = InputTarget::FLAG_FOREGROUND
1301                        | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
1302                if (isSplit) {
1303                    targetFlags |= InputTarget::FLAG_SPLIT;
1304                }
1305                if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1306                    targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1307                }
1308
1309                BitSet32 pointerIds;
1310                if (isSplit) {
1311                    pointerIds.markBit(entry->pointerProperties[0].id);
1312                }
1313                mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1314            }
1315        }
1316    }
1317
1318    if (newHoverWindowHandle != mLastHoverWindowHandle) {
1319        // Let the previous window know that the hover sequence is over.
1320        if (mLastHoverWindowHandle != NULL) {
1321#if DEBUG_HOVER
1322            ALOGD("Sending hover exit event to window %s.",
1323                    mLastHoverWindowHandle->getName().string());
1324#endif
1325            mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1326                    InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
1327        }
1328
1329        // Let the new window know that the hover sequence is starting.
1330        if (newHoverWindowHandle != NULL) {
1331#if DEBUG_HOVER
1332            ALOGD("Sending hover enter event to window %s.",
1333                    newHoverWindowHandle->getName().string());
1334#endif
1335            mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1336                    InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
1337        }
1338    }
1339
1340    // Check permission to inject into all touched foreground windows and ensure there
1341    // is at least one touched foreground window.
1342    {
1343        bool haveForegroundWindow = false;
1344        for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1345            const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1346            if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1347                haveForegroundWindow = true;
1348                if (! checkInjectionPermission(touchedWindow.windowHandle,
1349                        entry->injectionState)) {
1350                    injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1351                    injectionPermission = INJECTION_PERMISSION_DENIED;
1352                    goto Failed;
1353                }
1354            }
1355        }
1356        if (! haveForegroundWindow) {
1357#if DEBUG_FOCUS
1358            ALOGD("Dropping event because there is no touched foreground window to receive it.");
1359#endif
1360            injectionResult = INPUT_EVENT_INJECTION_FAILED;
1361            goto Failed;
1362        }
1363
1364        // Permission granted to injection into all touched foreground windows.
1365        injectionPermission = INJECTION_PERMISSION_GRANTED;
1366    }
1367
1368    // Check whether windows listening for outside touches are owned by the same UID. If it is
1369    // set the policy flag that we will not reveal coordinate information to this window.
1370    if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1371        sp<InputWindowHandle> foregroundWindowHandle =
1372                mTempTouchState.getFirstForegroundWindowHandle();
1373        const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
1374        for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1375            const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1376            if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1377                sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1378                if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
1379                    mTempTouchState.addOrUpdateWindow(inputWindowHandle,
1380                            InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
1381                }
1382            }
1383        }
1384    }
1385
1386    // Ensure all touched foreground windows are ready for new input.
1387    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1388        const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1389        if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1390            // If the touched window is paused then keep waiting.
1391            if (touchedWindow.windowHandle->getInfo()->paused) {
1392#if DEBUG_FOCUS
1393                ALOGD("Waiting because touched window is paused.");
1394#endif
1395                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1396                        NULL, touchedWindow.windowHandle, nextWakeupTime);
1397                goto Unresponsive;
1398            }
1399
1400            // If the touched window is still working on previous events then keep waiting.
1401            if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.windowHandle)) {
1402#if DEBUG_FOCUS
1403                ALOGD("Waiting because touched window still processing previous input.");
1404#endif
1405                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1406                        NULL, touchedWindow.windowHandle, nextWakeupTime);
1407                goto Unresponsive;
1408            }
1409        }
1410    }
1411
1412    // If this is the first pointer going down and the touched window has a wallpaper
1413    // then also add the touched wallpaper windows so they are locked in for the duration
1414    // of the touch gesture.
1415    // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
1416    // engine only supports touch events.  We would need to add a mechanism similar
1417    // to View.onGenericMotionEvent to enable wallpapers to handle these events.
1418    if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1419        sp<InputWindowHandle> foregroundWindowHandle =
1420                mTempTouchState.getFirstForegroundWindowHandle();
1421        if (foregroundWindowHandle->getInfo()->hasWallpaper) {
1422            for (size_t i = 0; i < mWindowHandles.size(); i++) {
1423                sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
1424                if (windowHandle->getInfo()->layoutParamsType
1425                        == InputWindowInfo::TYPE_WALLPAPER) {
1426                    mTempTouchState.addOrUpdateWindow(windowHandle,
1427                            InputTarget::FLAG_WINDOW_IS_OBSCURED
1428                                    | InputTarget::FLAG_DISPATCH_AS_IS,
1429                            BitSet32(0));
1430                }
1431            }
1432        }
1433    }
1434
1435    // Success!  Output targets.
1436    injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
1437
1438    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1439        const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1440        addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
1441                touchedWindow.pointerIds, inputTargets);
1442    }
1443
1444    // Drop the outside or hover touch windows since we will not care about them
1445    // in the next iteration.
1446    mTempTouchState.filterNonAsIsTouchWindows();
1447
1448Failed:
1449    // Check injection permission once and for all.
1450    if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
1451        if (checkInjectionPermission(NULL, entry->injectionState)) {
1452            injectionPermission = INJECTION_PERMISSION_GRANTED;
1453        } else {
1454            injectionPermission = INJECTION_PERMISSION_DENIED;
1455        }
1456    }
1457
1458    // Update final pieces of touch state if the injector had permission.
1459    if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
1460        if (!wrongDevice) {
1461            if (switchedDevice) {
1462#if DEBUG_FOCUS
1463                ALOGD("Conflicting pointer actions: Switched to a different device.");
1464#endif
1465                *outConflictingPointerActions = true;
1466            }
1467
1468            if (isHoverAction) {
1469                // Started hovering, therefore no longer down.
1470                if (mTouchState.down) {
1471#if DEBUG_FOCUS
1472                    ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
1473#endif
1474                    *outConflictingPointerActions = true;
1475                }
1476                mTouchState.reset();
1477                if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1478                        || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
1479                    mTouchState.deviceId = entry->deviceId;
1480                    mTouchState.source = entry->source;
1481                }
1482            } else if (maskedAction == AMOTION_EVENT_ACTION_UP
1483                    || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1484                // All pointers up or canceled.
1485                mTouchState.reset();
1486            } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1487                // First pointer went down.
1488                if (mTouchState.down) {
1489#if DEBUG_FOCUS
1490                    ALOGD("Conflicting pointer actions: Down received while already down.");
1491#endif
1492                    *outConflictingPointerActions = true;
1493                }
1494                mTouchState.copyFrom(mTempTouchState);
1495            } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1496                // One pointer went up.
1497                if (isSplit) {
1498                    int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1499                    uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
1500
1501                    for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1502                        TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1503                        if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1504                            touchedWindow.pointerIds.clearBit(pointerId);
1505                            if (touchedWindow.pointerIds.isEmpty()) {
1506                                mTempTouchState.windows.removeAt(i);
1507                                continue;
1508                            }
1509                        }
1510                        i += 1;
1511                    }
1512                }
1513                mTouchState.copyFrom(mTempTouchState);
1514            } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
1515                // Discard temporary touch state since it was only valid for this action.
1516            } else {
1517                // Save changes to touch state as-is for all other actions.
1518                mTouchState.copyFrom(mTempTouchState);
1519            }
1520
1521            // Update hover state.
1522            mLastHoverWindowHandle = newHoverWindowHandle;
1523        }
1524    } else {
1525#if DEBUG_FOCUS
1526        ALOGD("Not updating touch focus because injection was denied.");
1527#endif
1528    }
1529
1530Unresponsive:
1531    // Reset temporary touch state to ensure we release unnecessary references to input channels.
1532    mTempTouchState.reset();
1533
1534    nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1535    updateDispatchStatisticsLocked(currentTime, entry,
1536            injectionResult, timeSpentWaitingForApplication);
1537#if DEBUG_FOCUS
1538    ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1539            "timeSpentWaitingForApplication=%0.1fms",
1540            injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1541#endif
1542    return injectionResult;
1543}
1544
1545void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
1546        int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) {
1547    inputTargets.push();
1548
1549    const InputWindowInfo* windowInfo = windowHandle->getInfo();
1550    InputTarget& target = inputTargets.editTop();
1551    target.inputChannel = windowInfo->inputChannel;
1552    target.flags = targetFlags;
1553    target.xOffset = - windowInfo->frameLeft;
1554    target.yOffset = - windowInfo->frameTop;
1555    target.scaleFactor = windowInfo->scaleFactor;
1556    target.pointerIds = pointerIds;
1557}
1558
1559void InputDispatcher::addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets) {
1560    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1561        inputTargets.push();
1562
1563        InputTarget& target = inputTargets.editTop();
1564        target.inputChannel = mMonitoringChannels[i];
1565        target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1566        target.xOffset = 0;
1567        target.yOffset = 0;
1568        target.pointerIds.clear();
1569        target.scaleFactor = 1.0f;
1570    }
1571}
1572
1573bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
1574        const InjectionState* injectionState) {
1575    if (injectionState
1576            && (windowHandle == NULL
1577                    || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
1578            && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
1579        if (windowHandle != NULL) {
1580            ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
1581                    "owned by uid %d",
1582                    injectionState->injectorPid, injectionState->injectorUid,
1583                    windowHandle->getName().string(),
1584                    windowHandle->getInfo()->ownerUid);
1585        } else {
1586            ALOGW("Permission denied: injecting event from pid %d uid %d",
1587                    injectionState->injectorPid, injectionState->injectorUid);
1588        }
1589        return false;
1590    }
1591    return true;
1592}
1593
1594bool InputDispatcher::isWindowObscuredAtPointLocked(
1595        const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
1596    size_t numWindows = mWindowHandles.size();
1597    for (size_t i = 0; i < numWindows; i++) {
1598        sp<InputWindowHandle> otherHandle = mWindowHandles.itemAt(i);
1599        if (otherHandle == windowHandle) {
1600            break;
1601        }
1602
1603        const InputWindowInfo* otherInfo = otherHandle->getInfo();
1604        if (otherInfo->visible && ! otherInfo->isTrustedOverlay()
1605                && otherInfo->frameContainsPoint(x, y)) {
1606            return true;
1607        }
1608    }
1609    return false;
1610}
1611
1612bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(
1613        const sp<InputWindowHandle>& windowHandle) {
1614    ssize_t connectionIndex = getConnectionIndexLocked(windowHandle->getInputChannel());
1615    if (connectionIndex >= 0) {
1616        sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
1617        return connection->outboundQueue.isEmpty();
1618    } else {
1619        return true;
1620    }
1621}
1622
1623String8 InputDispatcher::getApplicationWindowLabelLocked(
1624        const sp<InputApplicationHandle>& applicationHandle,
1625        const sp<InputWindowHandle>& windowHandle) {
1626    if (applicationHandle != NULL) {
1627        if (windowHandle != NULL) {
1628            String8 label(applicationHandle->getName());
1629            label.append(" - ");
1630            label.append(windowHandle->getName());
1631            return label;
1632        } else {
1633            return applicationHandle->getName();
1634        }
1635    } else if (windowHandle != NULL) {
1636        return windowHandle->getName();
1637    } else {
1638        return String8("<unknown application or window>");
1639    }
1640}
1641
1642void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
1643    int32_t eventType = POWER_MANAGER_OTHER_EVENT;
1644    switch (eventEntry->type) {
1645    case EventEntry::TYPE_MOTION: {
1646        const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
1647        if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
1648            return;
1649        }
1650
1651        if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
1652            eventType = POWER_MANAGER_TOUCH_EVENT;
1653        }
1654        break;
1655    }
1656    case EventEntry::TYPE_KEY: {
1657        const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
1658        if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
1659            return;
1660        }
1661        eventType = POWER_MANAGER_BUTTON_EVENT;
1662        break;
1663    }
1664    }
1665
1666    CommandEntry* commandEntry = postCommandLocked(
1667            & InputDispatcher::doPokeUserActivityLockedInterruptible);
1668    commandEntry->eventTime = eventEntry->eventTime;
1669    commandEntry->userActivityEventType = eventType;
1670}
1671
1672void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1673        const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
1674#if DEBUG_DISPATCH_CYCLE
1675    ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
1676            "xOffset=%f, yOffset=%f, scaleFactor=%f, "
1677            "pointerIds=0x%x",
1678            connection->getInputChannelName(), inputTarget->flags,
1679            inputTarget->xOffset, inputTarget->yOffset,
1680            inputTarget->scaleFactor, inputTarget->pointerIds.value);
1681#endif
1682
1683    // Skip this event if the connection status is not normal.
1684    // We don't want to enqueue additional outbound events if the connection is broken.
1685    if (connection->status != Connection::STATUS_NORMAL) {
1686#if DEBUG_DISPATCH_CYCLE
1687        ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
1688                connection->getInputChannelName(), connection->getStatusLabel());
1689#endif
1690        return;
1691    }
1692
1693    // Split a motion event if needed.
1694    if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
1695        ALOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
1696
1697        MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1698        if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1699            MotionEntry* splitMotionEntry = splitMotionEvent(
1700                    originalMotionEntry, inputTarget->pointerIds);
1701            if (!splitMotionEntry) {
1702                return; // split event was dropped
1703            }
1704#if DEBUG_FOCUS
1705            ALOGD("channel '%s' ~ Split motion event.",
1706                    connection->getInputChannelName());
1707            logOutboundMotionDetailsLocked("  ", splitMotionEntry);
1708#endif
1709            enqueueDispatchEntriesLocked(currentTime, connection,
1710                    splitMotionEntry, inputTarget);
1711            splitMotionEntry->release();
1712            return;
1713        }
1714    }
1715
1716    // Not splitting.  Enqueue dispatch entries for the event as is.
1717    enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
1718}
1719
1720void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
1721        const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
1722    bool wasEmpty = connection->outboundQueue.isEmpty();
1723
1724    // Enqueue dispatch entries for the requested modes.
1725    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1726            InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
1727    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1728            InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
1729    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1730            InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
1731    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1732            InputTarget::FLAG_DISPATCH_AS_IS);
1733    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1734            InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
1735    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
1736            InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
1737
1738    // If the outbound queue was previously empty, start the dispatch cycle going.
1739    if (wasEmpty && !connection->outboundQueue.isEmpty()) {
1740        startDispatchCycleLocked(currentTime, connection);
1741    }
1742}
1743
1744void InputDispatcher::enqueueDispatchEntryLocked(
1745        const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
1746        int32_t dispatchMode) {
1747    int32_t inputTargetFlags = inputTarget->flags;
1748    if (!(inputTargetFlags & dispatchMode)) {
1749        return;
1750    }
1751    inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
1752
1753    // This is a new event.
1754    // Enqueue a new dispatch entry onto the outbound queue for this connection.
1755    DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
1756            inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
1757            inputTarget->scaleFactor);
1758
1759    // Apply target flags and update the connection's input state.
1760    switch (eventEntry->type) {
1761    case EventEntry::TYPE_KEY: {
1762        KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
1763        dispatchEntry->resolvedAction = keyEntry->action;
1764        dispatchEntry->resolvedFlags = keyEntry->flags;
1765
1766        if (!connection->inputState.trackKey(keyEntry,
1767                dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
1768#if DEBUG_DISPATCH_CYCLE
1769            ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
1770                    connection->getInputChannelName());
1771#endif
1772            delete dispatchEntry;
1773            return; // skip the inconsistent event
1774        }
1775        break;
1776    }
1777
1778    case EventEntry::TYPE_MOTION: {
1779        MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1780        if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
1781            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
1782        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
1783            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
1784        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
1785            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
1786        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
1787            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
1788        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
1789            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
1790        } else {
1791            dispatchEntry->resolvedAction = motionEntry->action;
1792        }
1793        if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1794                && !connection->inputState.isHovering(
1795                        motionEntry->deviceId, motionEntry->source)) {
1796#if DEBUG_DISPATCH_CYCLE
1797        ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
1798                connection->getInputChannelName());
1799#endif
1800            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
1801        }
1802
1803        dispatchEntry->resolvedFlags = motionEntry->flags;
1804        if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1805            dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1806        }
1807
1808        if (!connection->inputState.trackMotion(motionEntry,
1809                dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
1810#if DEBUG_DISPATCH_CYCLE
1811            ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
1812                    connection->getInputChannelName());
1813#endif
1814            delete dispatchEntry;
1815            return; // skip the inconsistent event
1816        }
1817        break;
1818    }
1819    }
1820
1821    // Remember that we are waiting for this dispatch to complete.
1822    if (dispatchEntry->hasForegroundTarget()) {
1823        incrementPendingForegroundDispatchesLocked(eventEntry);
1824    }
1825
1826    // Enqueue the dispatch entry.
1827    connection->outboundQueue.enqueueAtTail(dispatchEntry);
1828}
1829
1830void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
1831        const sp<Connection>& connection) {
1832#if DEBUG_DISPATCH_CYCLE
1833    ALOGD("channel '%s' ~ startDispatchCycle",
1834            connection->getInputChannelName());
1835#endif
1836
1837    ALOG_ASSERT(connection->status == Connection::STATUS_NORMAL);
1838    ALOG_ASSERT(! connection->outboundQueue.isEmpty());
1839
1840    DispatchEntry* dispatchEntry = connection->outboundQueue.head;
1841    ALOG_ASSERT(! dispatchEntry->inProgress);
1842
1843    // Mark the dispatch entry as in progress.
1844    dispatchEntry->inProgress = true;
1845
1846    // Publish the event.
1847    status_t status;
1848    EventEntry* eventEntry = dispatchEntry->eventEntry;
1849    switch (eventEntry->type) {
1850    case EventEntry::TYPE_KEY: {
1851        KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
1852
1853        // Publish the key event.
1854        status = connection->inputPublisher.publishKeyEvent(
1855                keyEntry->deviceId, keyEntry->source,
1856                dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
1857                keyEntry->keyCode, keyEntry->scanCode,
1858                keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1859                keyEntry->eventTime);
1860
1861        if (status) {
1862            ALOGE("channel '%s' ~ Could not publish key event, "
1863                    "status=%d", connection->getInputChannelName(), status);
1864            abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
1865            return;
1866        }
1867        break;
1868    }
1869
1870    case EventEntry::TYPE_MOTION: {
1871        MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1872
1873        PointerCoords scaledCoords[MAX_POINTERS];
1874        const PointerCoords* usingCoords = motionEntry->pointerCoords;
1875
1876        // Set the X and Y offset depending on the input source.
1877        float xOffset, yOffset, scaleFactor;
1878        if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER
1879                && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
1880            scaleFactor = dispatchEntry->scaleFactor;
1881            xOffset = dispatchEntry->xOffset * scaleFactor;
1882            yOffset = dispatchEntry->yOffset * scaleFactor;
1883            if (scaleFactor != 1.0f) {
1884                for (size_t i = 0; i < motionEntry->pointerCount; i++) {
1885                    scaledCoords[i] = motionEntry->pointerCoords[i];
1886                    scaledCoords[i].scale(scaleFactor);
1887                }
1888                usingCoords = scaledCoords;
1889            }
1890        } else {
1891            xOffset = 0.0f;
1892            yOffset = 0.0f;
1893            scaleFactor = 1.0f;
1894
1895            // We don't want the dispatch target to know.
1896            if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
1897                for (size_t i = 0; i < motionEntry->pointerCount; i++) {
1898                    scaledCoords[i].clear();
1899                }
1900                usingCoords = scaledCoords;
1901            }
1902        }
1903
1904        // Publish the motion event.
1905        status = connection->inputPublisher.publishMotionEvent(
1906                motionEntry->deviceId, motionEntry->source,
1907                dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
1908                motionEntry->edgeFlags, motionEntry->metaState, motionEntry->buttonState,
1909                xOffset, yOffset,
1910                motionEntry->xPrecision, motionEntry->yPrecision,
1911                motionEntry->downTime, motionEntry->eventTime,
1912                motionEntry->pointerCount, motionEntry->pointerProperties,
1913                usingCoords);
1914
1915        if (status) {
1916            ALOGE("channel '%s' ~ Could not publish motion event, "
1917                    "status=%d", connection->getInputChannelName(), status);
1918            abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
1919            return;
1920        }
1921        break;
1922    }
1923
1924    default: {
1925        ALOG_ASSERT(false);
1926    }
1927    }
1928
1929    // Notify other system components.
1930    onDispatchCycleStartedLocked(currentTime, connection);
1931}
1932
1933void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1934        const sp<Connection>& connection, bool handled) {
1935#if DEBUG_DISPATCH_CYCLE
1936    ALOGD("channel '%s' ~ finishDispatchCycle - handled=%s",
1937            connection->getInputChannelName(), toString(handled));
1938#endif
1939
1940    if (connection->status == Connection::STATUS_BROKEN
1941            || connection->status == Connection::STATUS_ZOMBIE) {
1942        return;
1943    }
1944
1945    // Notify other system components and prepare to start the next dispatch cycle.
1946    onDispatchCycleFinishedLocked(currentTime, connection, handled);
1947}
1948
1949void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1950        const sp<Connection>& connection) {
1951    // Start the next dispatch cycle for this connection.
1952    while (! connection->outboundQueue.isEmpty()) {
1953        DispatchEntry* dispatchEntry = connection->outboundQueue.head;
1954        if (dispatchEntry->inProgress) {
1955            // Finished.
1956            connection->outboundQueue.dequeueAtHead();
1957            if (dispatchEntry->hasForegroundTarget()) {
1958                decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
1959            }
1960            delete dispatchEntry;
1961        } else {
1962            // If the head is not in progress, then we must have already dequeued the in
1963            // progress event, which means we actually aborted it.
1964            // So just start the next event for this connection.
1965            startDispatchCycleLocked(currentTime, connection);
1966            return;
1967        }
1968    }
1969}
1970
1971void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1972        const sp<Connection>& connection, bool notify) {
1973#if DEBUG_DISPATCH_CYCLE
1974    ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
1975            connection->getInputChannelName(), toString(notify));
1976#endif
1977
1978    // Clear the outbound queue.
1979    drainOutboundQueueLocked(connection.get());
1980
1981    // The connection appears to be unrecoverably broken.
1982    // Ignore already broken or zombie connections.
1983    if (connection->status == Connection::STATUS_NORMAL) {
1984        connection->status = Connection::STATUS_BROKEN;
1985
1986        if (notify) {
1987            // Notify other system components.
1988            onDispatchCycleBrokenLocked(currentTime, connection);
1989        }
1990    }
1991}
1992
1993void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1994    while (! connection->outboundQueue.isEmpty()) {
1995        DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1996        if (dispatchEntry->hasForegroundTarget()) {
1997            decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
1998        }
1999        delete dispatchEntry;
2000    }
2001}
2002
2003int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2004    InputDispatcher* d = static_cast<InputDispatcher*>(data);
2005
2006    { // acquire lock
2007        AutoMutex _l(d->mLock);
2008
2009        ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
2010        if (connectionIndex < 0) {
2011            ALOGE("Received spurious receive callback for unknown input channel.  "
2012                    "fd=%d, events=0x%x", fd, events);
2013            return 0; // remove the callback
2014        }
2015
2016        bool notify;
2017        sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
2018        if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2019            if (!(events & ALOOPER_EVENT_INPUT)) {
2020                ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
2021                        "events=0x%x", connection->getInputChannelName(), events);
2022                return 1;
2023            }
2024
2025            bool handled = false;
2026            status_t status = connection->inputPublisher.receiveFinishedSignal(&handled);
2027            if (!status) {
2028                nsecs_t currentTime = now();
2029                d->finishDispatchCycleLocked(currentTime, connection, handled);
2030                d->runCommandsLockedInterruptible();
2031                return 1;
2032            }
2033
2034            ALOGE("channel '%s' ~ Failed to receive finished signal.  status=%d",
2035                    connection->getInputChannelName(), status);
2036            notify = true;
2037        } else {
2038            // Monitor channels are never explicitly unregistered.
2039            // We do it automatically when the remote endpoint is closed so don't warn
2040            // about them.
2041            notify = !connection->monitor;
2042            if (notify) {
2043                ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred.  "
2044                        "events=0x%x", connection->getInputChannelName(), events);
2045            }
2046        }
2047
2048        // Unregister the channel.
2049        d->unregisterInputChannelLocked(connection->inputChannel, notify);
2050        return 0; // remove the callback
2051    } // release lock
2052}
2053
2054void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
2055        const CancelationOptions& options) {
2056    for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
2057        synthesizeCancelationEventsForConnectionLocked(
2058                mConnectionsByFd.valueAt(i), options);
2059    }
2060}
2061
2062void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2063        const sp<InputChannel>& channel, const CancelationOptions& options) {
2064    ssize_t index = getConnectionIndexLocked(channel);
2065    if (index >= 0) {
2066        synthesizeCancelationEventsForConnectionLocked(
2067                mConnectionsByFd.valueAt(index), options);
2068    }
2069}
2070
2071void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2072        const sp<Connection>& connection, const CancelationOptions& options) {
2073    if (connection->status == Connection::STATUS_BROKEN) {
2074        return;
2075    }
2076
2077    nsecs_t currentTime = now();
2078
2079    Vector<EventEntry*> cancelationEvents;
2080    connection->inputState.synthesizeCancelationEvents(currentTime,
2081            cancelationEvents, options);
2082
2083    if (!cancelationEvents.isEmpty()) {
2084#if DEBUG_OUTBOUND_EVENT_DETAILS
2085        ALOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
2086                "with reality: %s, mode=%d.",
2087                connection->getInputChannelName(), cancelationEvents.size(),
2088                options.reason, options.mode);
2089#endif
2090        for (size_t i = 0; i < cancelationEvents.size(); i++) {
2091            EventEntry* cancelationEventEntry = cancelationEvents.itemAt(i);
2092            switch (cancelationEventEntry->type) {
2093            case EventEntry::TYPE_KEY:
2094                logOutboundKeyDetailsLocked("cancel - ",
2095                        static_cast<KeyEntry*>(cancelationEventEntry));
2096                break;
2097            case EventEntry::TYPE_MOTION:
2098                logOutboundMotionDetailsLocked("cancel - ",
2099                        static_cast<MotionEntry*>(cancelationEventEntry));
2100                break;
2101            }
2102
2103            InputTarget target;
2104            sp<InputWindowHandle> windowHandle = getWindowHandleLocked(connection->inputChannel);
2105            if (windowHandle != NULL) {
2106                const InputWindowInfo* windowInfo = windowHandle->getInfo();
2107                target.xOffset = -windowInfo->frameLeft;
2108                target.yOffset = -windowInfo->frameTop;
2109                target.scaleFactor = windowInfo->scaleFactor;
2110            } else {
2111                target.xOffset = 0;
2112                target.yOffset = 0;
2113                target.scaleFactor = 1.0f;
2114            }
2115            target.inputChannel = connection->inputChannel;
2116            target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2117
2118            enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
2119                    &target, InputTarget::FLAG_DISPATCH_AS_IS);
2120
2121            cancelationEventEntry->release();
2122        }
2123
2124        if (!connection->outboundQueue.head->inProgress) {
2125            startDispatchCycleLocked(currentTime, connection);
2126        }
2127    }
2128}
2129
2130InputDispatcher::MotionEntry*
2131InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2132    ALOG_ASSERT(pointerIds.value != 0);
2133
2134    uint32_t splitPointerIndexMap[MAX_POINTERS];
2135    PointerProperties splitPointerProperties[MAX_POINTERS];
2136    PointerCoords splitPointerCoords[MAX_POINTERS];
2137
2138    uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2139    uint32_t splitPointerCount = 0;
2140
2141    for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2142            originalPointerIndex++) {
2143        const PointerProperties& pointerProperties =
2144                originalMotionEntry->pointerProperties[originalPointerIndex];
2145        uint32_t pointerId = uint32_t(pointerProperties.id);
2146        if (pointerIds.hasBit(pointerId)) {
2147            splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2148            splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2149            splitPointerCoords[splitPointerCount].copyFrom(
2150                    originalMotionEntry->pointerCoords[originalPointerIndex]);
2151            splitPointerCount += 1;
2152        }
2153    }
2154
2155    if (splitPointerCount != pointerIds.count()) {
2156        // This is bad.  We are missing some of the pointers that we expected to deliver.
2157        // Most likely this indicates that we received an ACTION_MOVE events that has
2158        // different pointer ids than we expected based on the previous ACTION_DOWN
2159        // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2160        // in this way.
2161        ALOGW("Dropping split motion event because the pointer count is %d but "
2162                "we expected there to be %d pointers.  This probably means we received "
2163                "a broken sequence of pointer ids from the input device.",
2164                splitPointerCount, pointerIds.count());
2165        return NULL;
2166    }
2167
2168    int32_t action = originalMotionEntry->action;
2169    int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2170    if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2171            || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2172        int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2173        const PointerProperties& pointerProperties =
2174                originalMotionEntry->pointerProperties[originalPointerIndex];
2175        uint32_t pointerId = uint32_t(pointerProperties.id);
2176        if (pointerIds.hasBit(pointerId)) {
2177            if (pointerIds.count() == 1) {
2178                // The first/last pointer went down/up.
2179                action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2180                        ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
2181            } else {
2182                // A secondary pointer went down/up.
2183                uint32_t splitPointerIndex = 0;
2184                while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2185                    splitPointerIndex += 1;
2186                }
2187                action = maskedAction | (splitPointerIndex
2188                        << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2189            }
2190        } else {
2191            // An unrelated pointer changed.
2192            action = AMOTION_EVENT_ACTION_MOVE;
2193        }
2194    }
2195
2196    MotionEntry* splitMotionEntry = new MotionEntry(
2197            originalMotionEntry->eventTime,
2198            originalMotionEntry->deviceId,
2199            originalMotionEntry->source,
2200            originalMotionEntry->policyFlags,
2201            action,
2202            originalMotionEntry->flags,
2203            originalMotionEntry->metaState,
2204            originalMotionEntry->buttonState,
2205            originalMotionEntry->edgeFlags,
2206            originalMotionEntry->xPrecision,
2207            originalMotionEntry->yPrecision,
2208            originalMotionEntry->downTime,
2209            splitPointerCount, splitPointerProperties, splitPointerCoords);
2210
2211    if (originalMotionEntry->injectionState) {
2212        splitMotionEntry->injectionState = originalMotionEntry->injectionState;
2213        splitMotionEntry->injectionState->refCount += 1;
2214    }
2215
2216    return splitMotionEntry;
2217}
2218
2219void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2220#if DEBUG_INBOUND_EVENT_DETAILS
2221    ALOGD("notifyConfigurationChanged - eventTime=%lld", args->eventTime);
2222#endif
2223
2224    bool needWake;
2225    { // acquire lock
2226        AutoMutex _l(mLock);
2227
2228        ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(args->eventTime);
2229        needWake = enqueueInboundEventLocked(newEntry);
2230    } // release lock
2231
2232    if (needWake) {
2233        mLooper->wake();
2234    }
2235}
2236
2237void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2238#if DEBUG_INBOUND_EVENT_DETAILS
2239    ALOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
2240            "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
2241            args->eventTime, args->deviceId, args->source, args->policyFlags,
2242            args->action, args->flags, args->keyCode, args->scanCode,
2243            args->metaState, args->downTime);
2244#endif
2245    if (!validateKeyEvent(args->action)) {
2246        return;
2247    }
2248
2249    uint32_t policyFlags = args->policyFlags;
2250    int32_t flags = args->flags;
2251    int32_t metaState = args->metaState;
2252    if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2253        policyFlags |= POLICY_FLAG_VIRTUAL;
2254        flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2255    }
2256    if (policyFlags & POLICY_FLAG_ALT) {
2257        metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON;
2258    }
2259    if (policyFlags & POLICY_FLAG_ALT_GR) {
2260        metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON;
2261    }
2262    if (policyFlags & POLICY_FLAG_SHIFT) {
2263        metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON;
2264    }
2265    if (policyFlags & POLICY_FLAG_CAPS_LOCK) {
2266        metaState |= AMETA_CAPS_LOCK_ON;
2267    }
2268    if (policyFlags & POLICY_FLAG_FUNCTION) {
2269        metaState |= AMETA_FUNCTION_ON;
2270    }
2271
2272    policyFlags |= POLICY_FLAG_TRUSTED;
2273
2274    KeyEvent event;
2275    event.initialize(args->deviceId, args->source, args->action,
2276            flags, args->keyCode, args->scanCode, metaState, 0,
2277            args->downTime, args->eventTime);
2278
2279    mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
2280
2281    if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2282        flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2283    }
2284
2285    bool needWake;
2286    { // acquire lock
2287        mLock.lock();
2288
2289        if (mInputFilterEnabled) {
2290            mLock.unlock();
2291
2292            policyFlags |= POLICY_FLAG_FILTERED;
2293            if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2294                return; // event was consumed by the filter
2295            }
2296
2297            mLock.lock();
2298        }
2299
2300        int32_t repeatCount = 0;
2301        KeyEntry* newEntry = new KeyEntry(args->eventTime,
2302                args->deviceId, args->source, policyFlags,
2303                args->action, flags, args->keyCode, args->scanCode,
2304                metaState, repeatCount, args->downTime);
2305
2306        needWake = enqueueInboundEventLocked(newEntry);
2307        mLock.unlock();
2308    } // release lock
2309
2310    if (needWake) {
2311        mLooper->wake();
2312    }
2313}
2314
2315void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2316#if DEBUG_INBOUND_EVENT_DETAILS
2317    ALOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
2318            "action=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, edgeFlags=0x%x, "
2319            "xPrecision=%f, yPrecision=%f, downTime=%lld",
2320            args->eventTime, args->deviceId, args->source, args->policyFlags,
2321            args->action, args->flags, args->metaState, args->buttonState,
2322            args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
2323    for (uint32_t i = 0; i < args->pointerCount; i++) {
2324        ALOGD("  Pointer %d: id=%d, toolType=%d, "
2325                "x=%f, y=%f, pressure=%f, size=%f, "
2326                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2327                "orientation=%f",
2328                i, args->pointerProperties[i].id,
2329                args->pointerProperties[i].toolType,
2330                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2331                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2332                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2333                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2334                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2335                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2336                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2337                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2338                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2339    }
2340#endif
2341    if (!validateMotionEvent(args->action, args->pointerCount, args->pointerProperties)) {
2342        return;
2343    }
2344
2345    uint32_t policyFlags = args->policyFlags;
2346    policyFlags |= POLICY_FLAG_TRUSTED;
2347    mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
2348
2349    bool needWake;
2350    { // acquire lock
2351        mLock.lock();
2352
2353        if (mInputFilterEnabled) {
2354            mLock.unlock();
2355
2356            MotionEvent event;
2357            event.initialize(args->deviceId, args->source, args->action, args->flags,
2358                    args->edgeFlags, args->metaState, args->buttonState, 0, 0,
2359                    args->xPrecision, args->yPrecision,
2360                    args->downTime, args->eventTime,
2361                    args->pointerCount, args->pointerProperties, args->pointerCoords);
2362
2363            policyFlags |= POLICY_FLAG_FILTERED;
2364            if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2365                return; // event was consumed by the filter
2366            }
2367
2368            mLock.lock();
2369        }
2370
2371        // Just enqueue a new motion event.
2372        MotionEntry* newEntry = new MotionEntry(args->eventTime,
2373                args->deviceId, args->source, policyFlags,
2374                args->action, args->flags, args->metaState, args->buttonState,
2375                args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
2376                args->pointerCount, args->pointerProperties, args->pointerCoords);
2377
2378        needWake = enqueueInboundEventLocked(newEntry);
2379        mLock.unlock();
2380    } // release lock
2381
2382    if (needWake) {
2383        mLooper->wake();
2384    }
2385}
2386
2387void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
2388#if DEBUG_INBOUND_EVENT_DETAILS
2389    ALOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchCode=%d, switchValue=%d",
2390            args->eventTime, args->policyFlags,
2391            args->switchCode, args->switchValue);
2392#endif
2393
2394    uint32_t policyFlags = args->policyFlags;
2395    policyFlags |= POLICY_FLAG_TRUSTED;
2396    mPolicy->notifySwitch(args->eventTime,
2397            args->switchCode, args->switchValue, policyFlags);
2398}
2399
2400void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
2401#if DEBUG_INBOUND_EVENT_DETAILS
2402    ALOGD("notifyDeviceReset - eventTime=%lld, deviceId=%d",
2403            args->eventTime, args->deviceId);
2404#endif
2405
2406    bool needWake;
2407    { // acquire lock
2408        AutoMutex _l(mLock);
2409
2410        DeviceResetEntry* newEntry = new DeviceResetEntry(args->eventTime, args->deviceId);
2411        needWake = enqueueInboundEventLocked(newEntry);
2412    } // release lock
2413
2414    if (needWake) {
2415        mLooper->wake();
2416    }
2417}
2418
2419int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
2420        int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
2421        uint32_t policyFlags) {
2422#if DEBUG_INBOUND_EVENT_DETAILS
2423    ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
2424            "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
2425            event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
2426#endif
2427
2428    nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2429
2430    policyFlags |= POLICY_FLAG_INJECTED;
2431    if (hasInjectionPermission(injectorPid, injectorUid)) {
2432        policyFlags |= POLICY_FLAG_TRUSTED;
2433    }
2434
2435    EventEntry* firstInjectedEntry;
2436    EventEntry* lastInjectedEntry;
2437    switch (event->getType()) {
2438    case AINPUT_EVENT_TYPE_KEY: {
2439        const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2440        int32_t action = keyEvent->getAction();
2441        if (! validateKeyEvent(action)) {
2442            return INPUT_EVENT_INJECTION_FAILED;
2443        }
2444
2445        int32_t flags = keyEvent->getFlags();
2446        if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2447            policyFlags |= POLICY_FLAG_VIRTUAL;
2448        }
2449
2450        if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2451            mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
2452        }
2453
2454        if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2455            flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2456        }
2457
2458        mLock.lock();
2459        firstInjectedEntry = new KeyEntry(keyEvent->getEventTime(),
2460                keyEvent->getDeviceId(), keyEvent->getSource(),
2461                policyFlags, action, flags,
2462                keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
2463                keyEvent->getRepeatCount(), keyEvent->getDownTime());
2464        lastInjectedEntry = firstInjectedEntry;
2465        break;
2466    }
2467
2468    case AINPUT_EVENT_TYPE_MOTION: {
2469        const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2470        int32_t action = motionEvent->getAction();
2471        size_t pointerCount = motionEvent->getPointerCount();
2472        const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
2473        if (! validateMotionEvent(action, pointerCount, pointerProperties)) {
2474            return INPUT_EVENT_INJECTION_FAILED;
2475        }
2476
2477        if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2478            nsecs_t eventTime = motionEvent->getEventTime();
2479            mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
2480        }
2481
2482        mLock.lock();
2483        const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2484        const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2485        firstInjectedEntry = new MotionEntry(*sampleEventTimes,
2486                motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2487                action, motionEvent->getFlags(),
2488                motionEvent->getMetaState(), motionEvent->getButtonState(),
2489                motionEvent->getEdgeFlags(),
2490                motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2491                motionEvent->getDownTime(), uint32_t(pointerCount),
2492                pointerProperties, samplePointerCoords);
2493        lastInjectedEntry = firstInjectedEntry;
2494        for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2495            sampleEventTimes += 1;
2496            samplePointerCoords += pointerCount;
2497            MotionEntry* nextInjectedEntry = new MotionEntry(*sampleEventTimes,
2498                    motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2499                    action, motionEvent->getFlags(),
2500                    motionEvent->getMetaState(), motionEvent->getButtonState(),
2501                    motionEvent->getEdgeFlags(),
2502                    motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2503                    motionEvent->getDownTime(), uint32_t(pointerCount),
2504                    pointerProperties, samplePointerCoords);
2505            lastInjectedEntry->next = nextInjectedEntry;
2506            lastInjectedEntry = nextInjectedEntry;
2507        }
2508        break;
2509    }
2510
2511    default:
2512        ALOGW("Cannot inject event of type %d", event->getType());
2513        return INPUT_EVENT_INJECTION_FAILED;
2514    }
2515
2516    InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
2517    if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2518        injectionState->injectionIsAsync = true;
2519    }
2520
2521    injectionState->refCount += 1;
2522    lastInjectedEntry->injectionState = injectionState;
2523
2524    bool needWake = false;
2525    for (EventEntry* entry = firstInjectedEntry; entry != NULL; ) {
2526        EventEntry* nextEntry = entry->next;
2527        needWake |= enqueueInboundEventLocked(entry);
2528        entry = nextEntry;
2529    }
2530
2531    mLock.unlock();
2532
2533    if (needWake) {
2534        mLooper->wake();
2535    }
2536
2537    int32_t injectionResult;
2538    { // acquire lock
2539        AutoMutex _l(mLock);
2540
2541        if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2542            injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2543        } else {
2544            for (;;) {
2545                injectionResult = injectionState->injectionResult;
2546                if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2547                    break;
2548                }
2549
2550                nsecs_t remainingTimeout = endTime - now();
2551                if (remainingTimeout <= 0) {
2552#if DEBUG_INJECTION
2553                    ALOGD("injectInputEvent - Timed out waiting for injection result "
2554                            "to become available.");
2555#endif
2556                    injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2557                    break;
2558                }
2559
2560                mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2561            }
2562
2563            if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2564                    && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
2565                while (injectionState->pendingForegroundDispatches != 0) {
2566#if DEBUG_INJECTION
2567                    ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
2568                            injectionState->pendingForegroundDispatches);
2569#endif
2570                    nsecs_t remainingTimeout = endTime - now();
2571                    if (remainingTimeout <= 0) {
2572#if DEBUG_INJECTION
2573                    ALOGD("injectInputEvent - Timed out waiting for pending foreground "
2574                            "dispatches to finish.");
2575#endif
2576                        injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2577                        break;
2578                    }
2579
2580                    mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2581                }
2582            }
2583        }
2584
2585        injectionState->release();
2586    } // release lock
2587
2588#if DEBUG_INJECTION
2589    ALOGD("injectInputEvent - Finished with result %d.  "
2590            "injectorPid=%d, injectorUid=%d",
2591            injectionResult, injectorPid, injectorUid);
2592#endif
2593
2594    return injectionResult;
2595}
2596
2597bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2598    return injectorUid == 0
2599            || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2600}
2601
2602void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
2603    InjectionState* injectionState = entry->injectionState;
2604    if (injectionState) {
2605#if DEBUG_INJECTION
2606        ALOGD("Setting input event injection result to %d.  "
2607                "injectorPid=%d, injectorUid=%d",
2608                 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
2609#endif
2610
2611        if (injectionState->injectionIsAsync
2612                && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
2613            // Log the outcome since the injector did not wait for the injection result.
2614            switch (injectionResult) {
2615            case INPUT_EVENT_INJECTION_SUCCEEDED:
2616                ALOGV("Asynchronous input event injection succeeded.");
2617                break;
2618            case INPUT_EVENT_INJECTION_FAILED:
2619                ALOGW("Asynchronous input event injection failed.");
2620                break;
2621            case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2622                ALOGW("Asynchronous input event injection permission denied.");
2623                break;
2624            case INPUT_EVENT_INJECTION_TIMED_OUT:
2625                ALOGW("Asynchronous input event injection timed out.");
2626                break;
2627            }
2628        }
2629
2630        injectionState->injectionResult = injectionResult;
2631        mInjectionResultAvailableCondition.broadcast();
2632    }
2633}
2634
2635void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2636    InjectionState* injectionState = entry->injectionState;
2637    if (injectionState) {
2638        injectionState->pendingForegroundDispatches += 1;
2639    }
2640}
2641
2642void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2643    InjectionState* injectionState = entry->injectionState;
2644    if (injectionState) {
2645        injectionState->pendingForegroundDispatches -= 1;
2646
2647        if (injectionState->pendingForegroundDispatches == 0) {
2648            mInjectionSyncFinishedCondition.broadcast();
2649        }
2650    }
2651}
2652
2653sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
2654        const sp<InputChannel>& inputChannel) const {
2655    size_t numWindows = mWindowHandles.size();
2656    for (size_t i = 0; i < numWindows; i++) {
2657        const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
2658        if (windowHandle->getInputChannel() == inputChannel) {
2659            return windowHandle;
2660        }
2661    }
2662    return NULL;
2663}
2664
2665bool InputDispatcher::hasWindowHandleLocked(
2666        const sp<InputWindowHandle>& windowHandle) const {
2667    size_t numWindows = mWindowHandles.size();
2668    for (size_t i = 0; i < numWindows; i++) {
2669        if (mWindowHandles.itemAt(i) == windowHandle) {
2670            return true;
2671        }
2672    }
2673    return false;
2674}
2675
2676void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) {
2677#if DEBUG_FOCUS
2678    ALOGD("setInputWindows");
2679#endif
2680    { // acquire lock
2681        AutoMutex _l(mLock);
2682
2683        Vector<sp<InputWindowHandle> > oldWindowHandles = mWindowHandles;
2684        mWindowHandles = inputWindowHandles;
2685
2686        sp<InputWindowHandle> newFocusedWindowHandle;
2687        bool foundHoveredWindow = false;
2688        for (size_t i = 0; i < mWindowHandles.size(); i++) {
2689            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
2690            if (!windowHandle->updateInfo() || windowHandle->getInputChannel() == NULL) {
2691                mWindowHandles.removeAt(i--);
2692                continue;
2693            }
2694            if (windowHandle->getInfo()->hasFocus) {
2695                newFocusedWindowHandle = windowHandle;
2696            }
2697            if (windowHandle == mLastHoverWindowHandle) {
2698                foundHoveredWindow = true;
2699            }
2700        }
2701
2702        if (!foundHoveredWindow) {
2703            mLastHoverWindowHandle = NULL;
2704        }
2705
2706        if (mFocusedWindowHandle != newFocusedWindowHandle) {
2707            if (mFocusedWindowHandle != NULL) {
2708#if DEBUG_FOCUS
2709                ALOGD("Focus left window: %s",
2710                        mFocusedWindowHandle->getName().string());
2711#endif
2712                sp<InputChannel> focusedInputChannel = mFocusedWindowHandle->getInputChannel();
2713                if (focusedInputChannel != NULL) {
2714                    CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
2715                            "focus left window");
2716                    synthesizeCancelationEventsForInputChannelLocked(
2717                            focusedInputChannel, options);
2718                }
2719            }
2720            if (newFocusedWindowHandle != NULL) {
2721#if DEBUG_FOCUS
2722                ALOGD("Focus entered window: %s",
2723                        newFocusedWindowHandle->getName().string());
2724#endif
2725            }
2726            mFocusedWindowHandle = newFocusedWindowHandle;
2727        }
2728
2729        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2730            TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2731            if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
2732#if DEBUG_FOCUS
2733                ALOGD("Touched window was removed: %s",
2734                        touchedWindow.windowHandle->getName().string());
2735#endif
2736                sp<InputChannel> touchedInputChannel =
2737                        touchedWindow.windowHandle->getInputChannel();
2738                if (touchedInputChannel != NULL) {
2739                    CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
2740                            "touched window was removed");
2741                    synthesizeCancelationEventsForInputChannelLocked(
2742                            touchedInputChannel, options);
2743                }
2744                mTouchState.windows.removeAt(i--);
2745            }
2746        }
2747
2748        // Release information for windows that are no longer present.
2749        // This ensures that unused input channels are released promptly.
2750        // Otherwise, they might stick around until the window handle is destroyed
2751        // which might not happen until the next GC.
2752        for (size_t i = 0; i < oldWindowHandles.size(); i++) {
2753            const sp<InputWindowHandle>& oldWindowHandle = oldWindowHandles.itemAt(i);
2754            if (!hasWindowHandleLocked(oldWindowHandle)) {
2755#if DEBUG_FOCUS
2756                ALOGD("Window went away: %s", oldWindowHandle->getName().string());
2757#endif
2758                oldWindowHandle->releaseInfo();
2759            }
2760        }
2761    } // release lock
2762
2763    // Wake up poll loop since it may need to make new input dispatching choices.
2764    mLooper->wake();
2765}
2766
2767void InputDispatcher::setFocusedApplication(
2768        const sp<InputApplicationHandle>& inputApplicationHandle) {
2769#if DEBUG_FOCUS
2770    ALOGD("setFocusedApplication");
2771#endif
2772    { // acquire lock
2773        AutoMutex _l(mLock);
2774
2775        if (inputApplicationHandle != NULL && inputApplicationHandle->updateInfo()) {
2776            if (mFocusedApplicationHandle != inputApplicationHandle) {
2777                if (mFocusedApplicationHandle != NULL) {
2778                    resetANRTimeoutsLocked();
2779                    mFocusedApplicationHandle->releaseInfo();
2780                }
2781                mFocusedApplicationHandle = inputApplicationHandle;
2782            }
2783        } else if (mFocusedApplicationHandle != NULL) {
2784            resetANRTimeoutsLocked();
2785            mFocusedApplicationHandle->releaseInfo();
2786            mFocusedApplicationHandle.clear();
2787        }
2788
2789#if DEBUG_FOCUS
2790        //logDispatchStateLocked();
2791#endif
2792    } // release lock
2793
2794    // Wake up poll loop since it may need to make new input dispatching choices.
2795    mLooper->wake();
2796}
2797
2798void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2799#if DEBUG_FOCUS
2800    ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2801#endif
2802
2803    bool changed;
2804    { // acquire lock
2805        AutoMutex _l(mLock);
2806
2807        if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2808            if (mDispatchFrozen && !frozen) {
2809                resetANRTimeoutsLocked();
2810            }
2811
2812            if (mDispatchEnabled && !enabled) {
2813                resetAndDropEverythingLocked("dispatcher is being disabled");
2814            }
2815
2816            mDispatchEnabled = enabled;
2817            mDispatchFrozen = frozen;
2818            changed = true;
2819        } else {
2820            changed = false;
2821        }
2822
2823#if DEBUG_FOCUS
2824        //logDispatchStateLocked();
2825#endif
2826    } // release lock
2827
2828    if (changed) {
2829        // Wake up poll loop since it may need to make new input dispatching choices.
2830        mLooper->wake();
2831    }
2832}
2833
2834void InputDispatcher::setInputFilterEnabled(bool enabled) {
2835#if DEBUG_FOCUS
2836    ALOGD("setInputFilterEnabled: enabled=%d", enabled);
2837#endif
2838
2839    { // acquire lock
2840        AutoMutex _l(mLock);
2841
2842        if (mInputFilterEnabled == enabled) {
2843            return;
2844        }
2845
2846        mInputFilterEnabled = enabled;
2847        resetAndDropEverythingLocked("input filter is being enabled or disabled");
2848    } // release lock
2849
2850    // Wake up poll loop since there might be work to do to drop everything.
2851    mLooper->wake();
2852}
2853
2854bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2855        const sp<InputChannel>& toChannel) {
2856#if DEBUG_FOCUS
2857    ALOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2858            fromChannel->getName().string(), toChannel->getName().string());
2859#endif
2860    { // acquire lock
2861        AutoMutex _l(mLock);
2862
2863        sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromChannel);
2864        sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toChannel);
2865        if (fromWindowHandle == NULL || toWindowHandle == NULL) {
2866#if DEBUG_FOCUS
2867            ALOGD("Cannot transfer focus because from or to window not found.");
2868#endif
2869            return false;
2870        }
2871        if (fromWindowHandle == toWindowHandle) {
2872#if DEBUG_FOCUS
2873            ALOGD("Trivial transfer to same window.");
2874#endif
2875            return true;
2876        }
2877
2878        bool found = false;
2879        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2880            const TouchedWindow& touchedWindow = mTouchState.windows[i];
2881            if (touchedWindow.windowHandle == fromWindowHandle) {
2882                int32_t oldTargetFlags = touchedWindow.targetFlags;
2883                BitSet32 pointerIds = touchedWindow.pointerIds;
2884
2885                mTouchState.windows.removeAt(i);
2886
2887                int32_t newTargetFlags = oldTargetFlags
2888                        & (InputTarget::FLAG_FOREGROUND
2889                                | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
2890                mTouchState.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
2891
2892                found = true;
2893                break;
2894            }
2895        }
2896
2897        if (! found) {
2898#if DEBUG_FOCUS
2899            ALOGD("Focus transfer failed because from window did not have focus.");
2900#endif
2901            return false;
2902        }
2903
2904        ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2905        ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2906        if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2907            sp<Connection> fromConnection = mConnectionsByFd.valueAt(fromConnectionIndex);
2908            sp<Connection> toConnection = mConnectionsByFd.valueAt(toConnectionIndex);
2909
2910            fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2911            CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
2912                    "transferring touch focus from this window to another window");
2913            synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
2914        }
2915
2916#if DEBUG_FOCUS
2917        logDispatchStateLocked();
2918#endif
2919    } // release lock
2920
2921    // Wake up poll loop since it may need to make new input dispatching choices.
2922    mLooper->wake();
2923    return true;
2924}
2925
2926void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2927#if DEBUG_FOCUS
2928    ALOGD("Resetting and dropping all events (%s).", reason);
2929#endif
2930
2931    CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
2932    synthesizeCancelationEventsForAllConnectionsLocked(options);
2933
2934    resetKeyRepeatLocked();
2935    releasePendingEventLocked();
2936    drainInboundQueueLocked();
2937    resetANRTimeoutsLocked();
2938
2939    mTouchState.reset();
2940    mLastHoverWindowHandle.clear();
2941}
2942
2943void InputDispatcher::logDispatchStateLocked() {
2944    String8 dump;
2945    dumpDispatchStateLocked(dump);
2946
2947    char* text = dump.lockBuffer(dump.size());
2948    char* start = text;
2949    while (*start != '\0') {
2950        char* end = strchr(start, '\n');
2951        if (*end == '\n') {
2952            *(end++) = '\0';
2953        }
2954        ALOGD("%s", start);
2955        start = end;
2956    }
2957}
2958
2959void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
2960    dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2961    dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
2962
2963    if (mFocusedApplicationHandle != NULL) {
2964        dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
2965                mFocusedApplicationHandle->getName().string(),
2966                mFocusedApplicationHandle->getDispatchingTimeout(
2967                        DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
2968    } else {
2969        dump.append(INDENT "FocusedApplication: <null>\n");
2970    }
2971    dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
2972            mFocusedWindowHandle != NULL ? mFocusedWindowHandle->getName().string() : "<null>");
2973
2974    dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2975    dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2976    dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
2977    dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
2978    if (!mTouchState.windows.isEmpty()) {
2979        dump.append(INDENT "TouchedWindows:\n");
2980        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2981            const TouchedWindow& touchedWindow = mTouchState.windows[i];
2982            dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2983                    i, touchedWindow.windowHandle->getName().string(),
2984                    touchedWindow.pointerIds.value,
2985                    touchedWindow.targetFlags);
2986        }
2987    } else {
2988        dump.append(INDENT "TouchedWindows: <none>\n");
2989    }
2990
2991    if (!mWindowHandles.isEmpty()) {
2992        dump.append(INDENT "Windows:\n");
2993        for (size_t i = 0; i < mWindowHandles.size(); i++) {
2994            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
2995            const InputWindowInfo* windowInfo = windowHandle->getInfo();
2996
2997            dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2998                    "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
2999                    "frame=[%d,%d][%d,%d], scale=%f, "
3000                    "touchableRegion=",
3001                    i, windowInfo->name.string(),
3002                    toString(windowInfo->paused),
3003                    toString(windowInfo->hasFocus),
3004                    toString(windowInfo->hasWallpaper),
3005                    toString(windowInfo->visible),
3006                    toString(windowInfo->canReceiveKeys),
3007                    windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
3008                    windowInfo->layer,
3009                    windowInfo->frameLeft, windowInfo->frameTop,
3010                    windowInfo->frameRight, windowInfo->frameBottom,
3011                    windowInfo->scaleFactor);
3012            dumpRegion(dump, windowInfo->touchableRegion);
3013            dump.appendFormat(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3014            dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
3015                    windowInfo->ownerPid, windowInfo->ownerUid,
3016                    windowInfo->dispatchingTimeout / 1000000.0);
3017        }
3018    } else {
3019        dump.append(INDENT "Windows: <none>\n");
3020    }
3021
3022    if (!mMonitoringChannels.isEmpty()) {
3023        dump.append(INDENT "MonitoringChannels:\n");
3024        for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3025            const sp<InputChannel>& channel = mMonitoringChannels[i];
3026            dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
3027        }
3028    } else {
3029        dump.append(INDENT "MonitoringChannels: <none>\n");
3030    }
3031
3032    dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
3033
3034    if (isAppSwitchPendingLocked()) {
3035        dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
3036                (mAppSwitchDueTime - now()) / 1000000.0);
3037    } else {
3038        dump.append(INDENT "AppSwitch: not pending\n");
3039    }
3040}
3041
3042status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
3043        const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
3044#if DEBUG_REGISTRATION
3045    ALOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
3046            toString(monitor));
3047#endif
3048
3049    { // acquire lock
3050        AutoMutex _l(mLock);
3051
3052        if (getConnectionIndexLocked(inputChannel) >= 0) {
3053            ALOGW("Attempted to register already registered input channel '%s'",
3054                    inputChannel->getName().string());
3055            return BAD_VALUE;
3056        }
3057
3058        sp<Connection> connection = new Connection(inputChannel, inputWindowHandle, monitor);
3059
3060        int32_t fd = inputChannel->getFd();
3061        mConnectionsByFd.add(fd, connection);
3062
3063        if (monitor) {
3064            mMonitoringChannels.push(inputChannel);
3065        }
3066
3067        mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3068
3069        runCommandsLockedInterruptible();
3070    } // release lock
3071    return OK;
3072}
3073
3074status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
3075#if DEBUG_REGISTRATION
3076    ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
3077#endif
3078
3079    { // acquire lock
3080        AutoMutex _l(mLock);
3081
3082        status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
3083        if (status) {
3084            return status;
3085        }
3086    } // release lock
3087
3088    // Wake the poll loop because removing the connection may have changed the current
3089    // synchronization state.
3090    mLooper->wake();
3091    return OK;
3092}
3093
3094status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
3095        bool notify) {
3096    ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
3097    if (connectionIndex < 0) {
3098        ALOGW("Attempted to unregister already unregistered input channel '%s'",
3099                inputChannel->getName().string());
3100        return BAD_VALUE;
3101    }
3102
3103    sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
3104    mConnectionsByFd.removeItemsAt(connectionIndex);
3105
3106    if (connection->monitor) {
3107        removeMonitorChannelLocked(inputChannel);
3108    }
3109
3110    mLooper->removeFd(inputChannel->getFd());
3111
3112    nsecs_t currentTime = now();
3113    abortBrokenDispatchCycleLocked(currentTime, connection, notify);
3114
3115    runCommandsLockedInterruptible();
3116
3117    connection->status = Connection::STATUS_ZOMBIE;
3118    return OK;
3119}
3120
3121void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
3122    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3123         if (mMonitoringChannels[i] == inputChannel) {
3124             mMonitoringChannels.removeAt(i);
3125             break;
3126         }
3127    }
3128}
3129
3130ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
3131    ssize_t connectionIndex = mConnectionsByFd.indexOfKey(inputChannel->getFd());
3132    if (connectionIndex >= 0) {
3133        sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
3134        if (connection->inputChannel.get() == inputChannel.get()) {
3135            return connectionIndex;
3136        }
3137    }
3138
3139    return -1;
3140}
3141
3142void InputDispatcher::onDispatchCycleStartedLocked(
3143        nsecs_t currentTime, const sp<Connection>& connection) {
3144}
3145
3146void InputDispatcher::onDispatchCycleFinishedLocked(
3147        nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
3148    CommandEntry* commandEntry = postCommandLocked(
3149            & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
3150    commandEntry->connection = connection;
3151    commandEntry->handled = handled;
3152}
3153
3154void InputDispatcher::onDispatchCycleBrokenLocked(
3155        nsecs_t currentTime, const sp<Connection>& connection) {
3156    ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3157            connection->getInputChannelName());
3158
3159    CommandEntry* commandEntry = postCommandLocked(
3160            & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
3161    commandEntry->connection = connection;
3162}
3163
3164void InputDispatcher::onANRLocked(
3165        nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
3166        const sp<InputWindowHandle>& windowHandle,
3167        nsecs_t eventTime, nsecs_t waitStartTime) {
3168    ALOGI("Application is not responding: %s.  "
3169            "%01.1fms since event, %01.1fms since wait started",
3170            getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
3171            (currentTime - eventTime) / 1000000.0,
3172            (currentTime - waitStartTime) / 1000000.0);
3173
3174    CommandEntry* commandEntry = postCommandLocked(
3175            & InputDispatcher::doNotifyANRLockedInterruptible);
3176    commandEntry->inputApplicationHandle = applicationHandle;
3177    commandEntry->inputWindowHandle = windowHandle;
3178}
3179
3180void InputDispatcher::doNotifyConfigurationChangedInterruptible(
3181        CommandEntry* commandEntry) {
3182    mLock.unlock();
3183
3184    mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
3185
3186    mLock.lock();
3187}
3188
3189void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
3190        CommandEntry* commandEntry) {
3191    sp<Connection> connection = commandEntry->connection;
3192
3193    if (connection->status != Connection::STATUS_ZOMBIE) {
3194        mLock.unlock();
3195
3196        mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
3197
3198        mLock.lock();
3199    }
3200}
3201
3202void InputDispatcher::doNotifyANRLockedInterruptible(
3203        CommandEntry* commandEntry) {
3204    mLock.unlock();
3205
3206    nsecs_t newTimeout = mPolicy->notifyANR(
3207            commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
3208
3209    mLock.lock();
3210
3211    resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
3212            commandEntry->inputWindowHandle != NULL
3213                    ? commandEntry->inputWindowHandle->getInputChannel() : NULL);
3214}
3215
3216void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3217        CommandEntry* commandEntry) {
3218    KeyEntry* entry = commandEntry->keyEntry;
3219
3220    KeyEvent event;
3221    initializeKeyEvent(&event, entry);
3222
3223    mLock.unlock();
3224
3225    nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
3226            &event, entry->policyFlags);
3227
3228    mLock.lock();
3229
3230    if (delay < 0) {
3231        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
3232    } else if (!delay) {
3233        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3234    } else {
3235        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
3236        entry->interceptKeyWakeupTime = now() + delay;
3237    }
3238    entry->release();
3239}
3240
3241void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3242        CommandEntry* commandEntry) {
3243    sp<Connection> connection = commandEntry->connection;
3244    bool handled = commandEntry->handled;
3245
3246    bool skipNext = false;
3247    if (!connection->outboundQueue.isEmpty()) {
3248        DispatchEntry* dispatchEntry = connection->outboundQueue.head;
3249        if (dispatchEntry->inProgress) {
3250            if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3251                KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
3252                skipNext = afterKeyEventLockedInterruptible(connection,
3253                        dispatchEntry, keyEntry, handled);
3254            } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
3255                MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
3256                skipNext = afterMotionEventLockedInterruptible(connection,
3257                        dispatchEntry, motionEntry, handled);
3258            }
3259        }
3260    }
3261
3262    if (!skipNext) {
3263        startNextDispatchCycleLocked(now(), connection);
3264    }
3265}
3266
3267bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
3268        DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
3269    if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
3270        // Get the fallback key state.
3271        // Clear it out after dispatching the UP.
3272        int32_t originalKeyCode = keyEntry->keyCode;
3273        int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
3274        if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
3275            connection->inputState.removeFallbackKey(originalKeyCode);
3276        }
3277
3278        if (handled || !dispatchEntry->hasForegroundTarget()) {
3279            // If the application handles the original key for which we previously
3280            // generated a fallback or if the window is not a foreground window,
3281            // then cancel the associated fallback key, if any.
3282            if (fallbackKeyCode != -1) {
3283                if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
3284                    CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
3285                            "application handled the original non-fallback key "
3286                            "or is no longer a foreground target, "
3287                            "canceling previously dispatched fallback key");
3288                    options.keyCode = fallbackKeyCode;
3289                    synthesizeCancelationEventsForConnectionLocked(connection, options);
3290                }
3291                connection->inputState.removeFallbackKey(originalKeyCode);
3292            }
3293        } else {
3294            // If the application did not handle a non-fallback key, first check
3295            // that we are in a good state to perform unhandled key event processing
3296            // Then ask the policy what to do with it.
3297            bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
3298                    && keyEntry->repeatCount == 0;
3299            if (fallbackKeyCode == -1 && !initialDown) {
3300#if DEBUG_OUTBOUND_EVENT_DETAILS
3301                ALOGD("Unhandled key event: Skipping unhandled key event processing "
3302                        "since this is not an initial down.  "
3303                        "keyCode=%d, action=%d, repeatCount=%d",
3304                        originalKeyCode, keyEntry->action, keyEntry->repeatCount);
3305#endif
3306                return false;
3307            }
3308
3309            // Dispatch the unhandled key to the policy.
3310#if DEBUG_OUTBOUND_EVENT_DETAILS
3311            ALOGD("Unhandled key event: Asking policy to perform fallback action.  "
3312                    "keyCode=%d, action=%d, repeatCount=%d",
3313                    keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount);
3314#endif
3315            KeyEvent event;
3316            initializeKeyEvent(&event, keyEntry);
3317
3318            mLock.unlock();
3319
3320            bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
3321                    &event, keyEntry->policyFlags, &event);
3322
3323            mLock.lock();
3324
3325            if (connection->status != Connection::STATUS_NORMAL) {
3326                connection->inputState.removeFallbackKey(originalKeyCode);
3327                return true; // skip next cycle
3328            }
3329
3330            ALOG_ASSERT(connection->outboundQueue.head == dispatchEntry);
3331
3332            // Latch the fallback keycode for this key on an initial down.
3333            // The fallback keycode cannot change at any other point in the lifecycle.
3334            if (initialDown) {
3335                if (fallback) {
3336                    fallbackKeyCode = event.getKeyCode();
3337                } else {
3338                    fallbackKeyCode = AKEYCODE_UNKNOWN;
3339                }
3340                connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
3341            }
3342
3343            ALOG_ASSERT(fallbackKeyCode != -1);
3344
3345            // Cancel the fallback key if the policy decides not to send it anymore.
3346            // We will continue to dispatch the key to the policy but we will no
3347            // longer dispatch a fallback key to the application.
3348            if (fallbackKeyCode != AKEYCODE_UNKNOWN
3349                    && (!fallback || fallbackKeyCode != event.getKeyCode())) {
3350#if DEBUG_OUTBOUND_EVENT_DETAILS
3351                if (fallback) {
3352                    ALOGD("Unhandled key event: Policy requested to send key %d"
3353                            "as a fallback for %d, but on the DOWN it had requested "
3354                            "to send %d instead.  Fallback canceled.",
3355                            event.getKeyCode(), originalKeyCode, fallbackKeyCode);
3356                } else {
3357                    ALOGD("Unhandled key event: Policy did not request fallback for %d,"
3358                            "but on the DOWN it had requested to send %d.  "
3359                            "Fallback canceled.",
3360                            originalKeyCode, fallbackKeyCode);
3361                }
3362#endif
3363
3364                CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
3365                        "canceling fallback, policy no longer desires it");
3366                options.keyCode = fallbackKeyCode;
3367                synthesizeCancelationEventsForConnectionLocked(connection, options);
3368
3369                fallback = false;
3370                fallbackKeyCode = AKEYCODE_UNKNOWN;
3371                if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
3372                    connection->inputState.setFallbackKey(originalKeyCode,
3373                            fallbackKeyCode);
3374                }
3375            }
3376
3377#if DEBUG_OUTBOUND_EVENT_DETAILS
3378            {
3379                String8 msg;
3380                const KeyedVector<int32_t, int32_t>& fallbackKeys =
3381                        connection->inputState.getFallbackKeys();
3382                for (size_t i = 0; i < fallbackKeys.size(); i++) {
3383                    msg.appendFormat(", %d->%d", fallbackKeys.keyAt(i),
3384                            fallbackKeys.valueAt(i));
3385                }
3386                ALOGD("Unhandled key event: %d currently tracked fallback keys%s.",
3387                        fallbackKeys.size(), msg.string());
3388            }
3389#endif
3390
3391            if (fallback) {
3392                // Restart the dispatch cycle using the fallback key.
3393                keyEntry->eventTime = event.getEventTime();
3394                keyEntry->deviceId = event.getDeviceId();
3395                keyEntry->source = event.getSource();
3396                keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
3397                keyEntry->keyCode = fallbackKeyCode;
3398                keyEntry->scanCode = event.getScanCode();
3399                keyEntry->metaState = event.getMetaState();
3400                keyEntry->repeatCount = event.getRepeatCount();
3401                keyEntry->downTime = event.getDownTime();
3402                keyEntry->syntheticRepeat = false;
3403
3404#if DEBUG_OUTBOUND_EVENT_DETAILS
3405                ALOGD("Unhandled key event: Dispatching fallback key.  "
3406                        "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
3407                        originalKeyCode, fallbackKeyCode, keyEntry->metaState);
3408#endif
3409
3410                dispatchEntry->inProgress = false;
3411                startDispatchCycleLocked(now(), connection);
3412                return true; // already started next cycle
3413            } else {
3414#if DEBUG_OUTBOUND_EVENT_DETAILS
3415                ALOGD("Unhandled key event: No fallback key.");
3416#endif
3417            }
3418        }
3419    }
3420    return false;
3421}
3422
3423bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
3424        DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
3425    return false;
3426}
3427
3428void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3429    mLock.unlock();
3430
3431    mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
3432
3433    mLock.lock();
3434}
3435
3436void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
3437    event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3438            entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3439            entry->downTime, entry->eventTime);
3440}
3441
3442void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3443        int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3444    // TODO Write some statistics about how long we spend waiting.
3445}
3446
3447void InputDispatcher::dump(String8& dump) {
3448    AutoMutex _l(mLock);
3449
3450    dump.append("Input Dispatcher State:\n");
3451    dumpDispatchStateLocked(dump);
3452
3453    dump.append(INDENT "Configuration:\n");
3454    dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
3455    dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n", mConfig.keyRepeatTimeout * 0.000001f);
3456}
3457
3458void InputDispatcher::monitor() {
3459    // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
3460    mLock.lock();
3461    mLooper->wake();
3462    mDispatcherIsAliveCondition.wait(mLock);
3463    mLock.unlock();
3464}
3465
3466
3467// --- InputDispatcher::Queue ---
3468
3469template <typename T>
3470uint32_t InputDispatcher::Queue<T>::count() const {
3471    uint32_t result = 0;
3472    for (const T* entry = head; entry; entry = entry->next) {
3473        result += 1;
3474    }
3475    return result;
3476}
3477
3478
3479// --- InputDispatcher::InjectionState ---
3480
3481InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
3482        refCount(1),
3483        injectorPid(injectorPid), injectorUid(injectorUid),
3484        injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
3485        pendingForegroundDispatches(0) {
3486}
3487
3488InputDispatcher::InjectionState::~InjectionState() {
3489}
3490
3491void InputDispatcher::InjectionState::release() {
3492    refCount -= 1;
3493    if (refCount == 0) {
3494        delete this;
3495    } else {
3496        ALOG_ASSERT(refCount > 0);
3497    }
3498}
3499
3500
3501// --- InputDispatcher::EventEntry ---
3502
3503InputDispatcher::EventEntry::EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags) :
3504        refCount(1), type(type), eventTime(eventTime), policyFlags(policyFlags),
3505        injectionState(NULL), dispatchInProgress(false) {
3506}
3507
3508InputDispatcher::EventEntry::~EventEntry() {
3509    releaseInjectionState();
3510}
3511
3512void InputDispatcher::EventEntry::release() {
3513    refCount -= 1;
3514    if (refCount == 0) {
3515        delete this;
3516    } else {
3517        ALOG_ASSERT(refCount > 0);
3518    }
3519}
3520
3521void InputDispatcher::EventEntry::releaseInjectionState() {
3522    if (injectionState) {
3523        injectionState->release();
3524        injectionState = NULL;
3525    }
3526}
3527
3528
3529// --- InputDispatcher::ConfigurationChangedEntry ---
3530
3531InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(nsecs_t eventTime) :
3532        EventEntry(TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
3533}
3534
3535InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
3536}
3537
3538
3539// --- InputDispatcher::DeviceResetEntry ---
3540
3541InputDispatcher::DeviceResetEntry::DeviceResetEntry(nsecs_t eventTime, int32_t deviceId) :
3542        EventEntry(TYPE_DEVICE_RESET, eventTime, 0),
3543        deviceId(deviceId) {
3544}
3545
3546InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
3547}
3548
3549
3550// --- InputDispatcher::KeyEntry ---
3551
3552InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
3553        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
3554        int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3555        int32_t repeatCount, nsecs_t downTime) :
3556        EventEntry(TYPE_KEY, eventTime, policyFlags),
3557        deviceId(deviceId), source(source), action(action), flags(flags),
3558        keyCode(keyCode), scanCode(scanCode), metaState(metaState),
3559        repeatCount(repeatCount), downTime(downTime),
3560        syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
3561        interceptKeyWakeupTime(0) {
3562}
3563
3564InputDispatcher::KeyEntry::~KeyEntry() {
3565}
3566
3567void InputDispatcher::KeyEntry::recycle() {
3568    releaseInjectionState();
3569
3570    dispatchInProgress = false;
3571    syntheticRepeat = false;
3572    interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
3573    interceptKeyWakeupTime = 0;
3574}
3575
3576
3577// --- InputDispatcher::MotionEntry ---
3578
3579InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,
3580        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
3581        int32_t metaState, int32_t buttonState,
3582        int32_t edgeFlags, float xPrecision, float yPrecision,
3583        nsecs_t downTime, uint32_t pointerCount,
3584        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) :
3585        EventEntry(TYPE_MOTION, eventTime, policyFlags),
3586        eventTime(eventTime),
3587        deviceId(deviceId), source(source), action(action), flags(flags),
3588        metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
3589        xPrecision(xPrecision), yPrecision(yPrecision),
3590        downTime(downTime), pointerCount(pointerCount) {
3591    for (uint32_t i = 0; i < pointerCount; i++) {
3592        this->pointerProperties[i].copyFrom(pointerProperties[i]);
3593        this->pointerCoords[i].copyFrom(pointerCoords[i]);
3594    }
3595}
3596
3597InputDispatcher::MotionEntry::~MotionEntry() {
3598}
3599
3600
3601// --- InputDispatcher::DispatchEntry ---
3602
3603InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
3604        int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) :
3605        eventEntry(eventEntry), targetFlags(targetFlags),
3606        xOffset(xOffset), yOffset(yOffset), scaleFactor(scaleFactor),
3607        inProgress(false),
3608        resolvedAction(0), resolvedFlags(0) {
3609    eventEntry->refCount += 1;
3610}
3611
3612InputDispatcher::DispatchEntry::~DispatchEntry() {
3613    eventEntry->release();
3614}
3615
3616
3617// --- InputDispatcher::InputState ---
3618
3619InputDispatcher::InputState::InputState() {
3620}
3621
3622InputDispatcher::InputState::~InputState() {
3623}
3624
3625bool InputDispatcher::InputState::isNeutral() const {
3626    return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3627}
3628
3629bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source) const {
3630    for (size_t i = 0; i < mMotionMementos.size(); i++) {
3631        const MotionMemento& memento = mMotionMementos.itemAt(i);
3632        if (memento.deviceId == deviceId
3633                && memento.source == source
3634                && memento.hovering) {
3635            return true;
3636        }
3637    }
3638    return false;
3639}
3640
3641bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
3642        int32_t action, int32_t flags) {
3643    switch (action) {
3644    case AKEY_EVENT_ACTION_UP: {
3645        if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
3646            for (size_t i = 0; i < mFallbackKeys.size(); ) {
3647                if (mFallbackKeys.valueAt(i) == entry->keyCode) {
3648                    mFallbackKeys.removeItemsAt(i);
3649                } else {
3650                    i += 1;
3651                }
3652            }
3653        }
3654        ssize_t index = findKeyMemento(entry);
3655        if (index >= 0) {
3656            mKeyMementos.removeAt(index);
3657            return true;
3658        }
3659        /* FIXME: We can't just drop the key up event because that prevents creating
3660         * popup windows that are automatically shown when a key is held and then
3661         * dismissed when the key is released.  The problem is that the popup will
3662         * not have received the original key down, so the key up will be considered
3663         * to be inconsistent with its observed state.  We could perhaps handle this
3664         * by synthesizing a key down but that will cause other problems.
3665         *
3666         * So for now, allow inconsistent key up events to be dispatched.
3667         *
3668#if DEBUG_OUTBOUND_EVENT_DETAILS
3669        ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
3670                "keyCode=%d, scanCode=%d",
3671                entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
3672#endif
3673        return false;
3674        */
3675        return true;
3676    }
3677
3678    case AKEY_EVENT_ACTION_DOWN: {
3679        ssize_t index = findKeyMemento(entry);
3680        if (index >= 0) {
3681            mKeyMementos.removeAt(index);
3682        }
3683        addKeyMemento(entry, flags);
3684        return true;
3685    }
3686
3687    default:
3688        return true;
3689    }
3690}
3691
3692bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
3693        int32_t action, int32_t flags) {
3694    int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
3695    switch (actionMasked) {
3696    case AMOTION_EVENT_ACTION_UP:
3697    case AMOTION_EVENT_ACTION_CANCEL: {
3698        ssize_t index = findMotionMemento(entry, false /*hovering*/);
3699        if (index >= 0) {
3700            mMotionMementos.removeAt(index);
3701            return true;
3702        }
3703#if DEBUG_OUTBOUND_EVENT_DETAILS
3704        ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
3705                "actionMasked=%d",
3706                entry->deviceId, entry->source, actionMasked);
3707#endif
3708        return false;
3709    }
3710
3711    case AMOTION_EVENT_ACTION_DOWN: {
3712        ssize_t index = findMotionMemento(entry, false /*hovering*/);
3713        if (index >= 0) {
3714            mMotionMementos.removeAt(index);
3715        }
3716        addMotionMemento(entry, flags, false /*hovering*/);
3717        return true;
3718    }
3719
3720    case AMOTION_EVENT_ACTION_POINTER_UP:
3721    case AMOTION_EVENT_ACTION_POINTER_DOWN:
3722    case AMOTION_EVENT_ACTION_MOVE: {
3723        ssize_t index = findMotionMemento(entry, false /*hovering*/);
3724        if (index >= 0) {
3725            MotionMemento& memento = mMotionMementos.editItemAt(index);
3726            memento.setPointers(entry);
3727            return true;
3728        }
3729        if (actionMasked == AMOTION_EVENT_ACTION_MOVE
3730                && (entry->source & (AINPUT_SOURCE_CLASS_JOYSTICK
3731                        | AINPUT_SOURCE_CLASS_NAVIGATION))) {
3732            // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
3733            return true;
3734        }
3735#if DEBUG_OUTBOUND_EVENT_DETAILS
3736        ALOGD("Dropping inconsistent motion pointer up/down or move event: "
3737                "deviceId=%d, source=%08x, actionMasked=%d",
3738                entry->deviceId, entry->source, actionMasked);
3739#endif
3740        return false;
3741    }
3742
3743    case AMOTION_EVENT_ACTION_HOVER_EXIT: {
3744        ssize_t index = findMotionMemento(entry, true /*hovering*/);
3745        if (index >= 0) {
3746            mMotionMementos.removeAt(index);
3747            return true;
3748        }
3749#if DEBUG_OUTBOUND_EVENT_DETAILS
3750        ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x",
3751                entry->deviceId, entry->source);
3752#endif
3753        return false;
3754    }
3755
3756    case AMOTION_EVENT_ACTION_HOVER_ENTER:
3757    case AMOTION_EVENT_ACTION_HOVER_MOVE: {
3758        ssize_t index = findMotionMemento(entry, true /*hovering*/);
3759        if (index >= 0) {
3760            mMotionMementos.removeAt(index);
3761        }
3762        addMotionMemento(entry, flags, true /*hovering*/);
3763        return true;
3764    }
3765
3766    default:
3767        return true;
3768    }
3769}
3770
3771ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
3772    for (size_t i = 0; i < mKeyMementos.size(); i++) {
3773        const KeyMemento& memento = mKeyMementos.itemAt(i);
3774        if (memento.deviceId == entry->deviceId
3775                && memento.source == entry->source
3776                && memento.keyCode == entry->keyCode
3777                && memento.scanCode == entry->scanCode) {
3778            return i;
3779        }
3780    }
3781    return -1;
3782}
3783
3784ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
3785        bool hovering) const {
3786    for (size_t i = 0; i < mMotionMementos.size(); i++) {
3787        const MotionMemento& memento = mMotionMementos.itemAt(i);
3788        if (memento.deviceId == entry->deviceId
3789                && memento.source == entry->source
3790                && memento.hovering == hovering) {
3791            return i;
3792        }
3793    }
3794    return -1;
3795}
3796
3797void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
3798    mKeyMementos.push();
3799    KeyMemento& memento = mKeyMementos.editTop();
3800    memento.deviceId = entry->deviceId;
3801    memento.source = entry->source;
3802    memento.keyCode = entry->keyCode;
3803    memento.scanCode = entry->scanCode;
3804    memento.flags = flags;
3805    memento.downTime = entry->downTime;
3806}
3807
3808void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
3809        int32_t flags, bool hovering) {
3810    mMotionMementos.push();
3811    MotionMemento& memento = mMotionMementos.editTop();
3812    memento.deviceId = entry->deviceId;
3813    memento.source = entry->source;
3814    memento.flags = flags;
3815    memento.xPrecision = entry->xPrecision;
3816    memento.yPrecision = entry->yPrecision;
3817    memento.downTime = entry->downTime;
3818    memento.setPointers(entry);
3819    memento.hovering = hovering;
3820}
3821
3822void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3823    pointerCount = entry->pointerCount;
3824    for (uint32_t i = 0; i < entry->pointerCount; i++) {
3825        pointerProperties[i].copyFrom(entry->pointerProperties[i]);
3826        pointerCoords[i].copyFrom(entry->pointerCoords[i]);
3827    }
3828}
3829
3830void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3831        Vector<EventEntry*>& outEvents, const CancelationOptions& options) {
3832    for (size_t i = 0; i < mKeyMementos.size(); i++) {
3833        const KeyMemento& memento = mKeyMementos.itemAt(i);
3834        if (shouldCancelKey(memento, options)) {
3835            outEvents.push(new KeyEntry(currentTime,
3836                    memento.deviceId, memento.source, 0,
3837                    AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
3838                    memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3839        }
3840    }
3841
3842    for (size_t i = 0; i < mMotionMementos.size(); i++) {
3843        const MotionMemento& memento = mMotionMementos.itemAt(i);
3844        if (shouldCancelMotion(memento, options)) {
3845            outEvents.push(new MotionEntry(currentTime,
3846                    memento.deviceId, memento.source, 0,
3847                    memento.hovering
3848                            ? AMOTION_EVENT_ACTION_HOVER_EXIT
3849                            : AMOTION_EVENT_ACTION_CANCEL,
3850                    memento.flags, 0, 0, 0,
3851                    memento.xPrecision, memento.yPrecision, memento.downTime,
3852                    memento.pointerCount, memento.pointerProperties, memento.pointerCoords));
3853        }
3854    }
3855}
3856
3857void InputDispatcher::InputState::clear() {
3858    mKeyMementos.clear();
3859    mMotionMementos.clear();
3860    mFallbackKeys.clear();
3861}
3862
3863void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3864    for (size_t i = 0; i < mMotionMementos.size(); i++) {
3865        const MotionMemento& memento = mMotionMementos.itemAt(i);
3866        if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3867            for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3868                const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3869                if (memento.deviceId == otherMemento.deviceId
3870                        && memento.source == otherMemento.source) {
3871                    other.mMotionMementos.removeAt(j);
3872                } else {
3873                    j += 1;
3874                }
3875            }
3876            other.mMotionMementos.push(memento);
3877        }
3878    }
3879}
3880
3881int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
3882    ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
3883    return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
3884}
3885
3886void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
3887        int32_t fallbackKeyCode) {
3888    ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
3889    if (index >= 0) {
3890        mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
3891    } else {
3892        mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
3893    }
3894}
3895
3896void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
3897    mFallbackKeys.removeItem(originalKeyCode);
3898}
3899
3900bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
3901        const CancelationOptions& options) {
3902    if (options.keyCode != -1 && memento.keyCode != options.keyCode) {
3903        return false;
3904    }
3905
3906    if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
3907        return false;
3908    }
3909
3910    switch (options.mode) {
3911    case CancelationOptions::CANCEL_ALL_EVENTS:
3912    case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
3913        return true;
3914    case CancelationOptions::CANCEL_FALLBACK_EVENTS:
3915        return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
3916    default:
3917        return false;
3918    }
3919}
3920
3921bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
3922        const CancelationOptions& options) {
3923    if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
3924        return false;
3925    }
3926
3927    switch (options.mode) {
3928    case CancelationOptions::CANCEL_ALL_EVENTS:
3929        return true;
3930    case CancelationOptions::CANCEL_POINTER_EVENTS:
3931        return memento.source & AINPUT_SOURCE_CLASS_POINTER;
3932    case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
3933        return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
3934    default:
3935        return false;
3936    }
3937}
3938
3939
3940// --- InputDispatcher::Connection ---
3941
3942InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
3943        const sp<InputWindowHandle>& inputWindowHandle, bool monitor) :
3944        status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
3945        monitor(monitor),
3946        inputPublisher(inputChannel) {
3947}
3948
3949InputDispatcher::Connection::~Connection() {
3950}
3951
3952const char* InputDispatcher::Connection::getStatusLabel() const {
3953    switch (status) {
3954    case STATUS_NORMAL:
3955        return "NORMAL";
3956
3957    case STATUS_BROKEN:
3958        return "BROKEN";
3959
3960    case STATUS_ZOMBIE:
3961        return "ZOMBIE";
3962
3963    default:
3964        return "UNKNOWN";
3965    }
3966}
3967
3968
3969// --- InputDispatcher::CommandEntry ---
3970
3971InputDispatcher::CommandEntry::CommandEntry(Command command) :
3972    command(command), eventTime(0), keyEntry(NULL), userActivityEventType(0), handled(false) {
3973}
3974
3975InputDispatcher::CommandEntry::~CommandEntry() {
3976}
3977
3978
3979// --- InputDispatcher::TouchState ---
3980
3981InputDispatcher::TouchState::TouchState() :
3982    down(false), split(false), deviceId(-1), source(0) {
3983}
3984
3985InputDispatcher::TouchState::~TouchState() {
3986}
3987
3988void InputDispatcher::TouchState::reset() {
3989    down = false;
3990    split = false;
3991    deviceId = -1;
3992    source = 0;
3993    windows.clear();
3994}
3995
3996void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3997    down = other.down;
3998    split = other.split;
3999    deviceId = other.deviceId;
4000    source = other.source;
4001    windows = other.windows;
4002}
4003
4004void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
4005        int32_t targetFlags, BitSet32 pointerIds) {
4006    if (targetFlags & InputTarget::FLAG_SPLIT) {
4007        split = true;
4008    }
4009
4010    for (size_t i = 0; i < windows.size(); i++) {
4011        TouchedWindow& touchedWindow = windows.editItemAt(i);
4012        if (touchedWindow.windowHandle == windowHandle) {
4013            touchedWindow.targetFlags |= targetFlags;
4014            if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
4015                touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
4016            }
4017            touchedWindow.pointerIds.value |= pointerIds.value;
4018            return;
4019        }
4020    }
4021
4022    windows.push();
4023
4024    TouchedWindow& touchedWindow = windows.editTop();
4025    touchedWindow.windowHandle = windowHandle;
4026    touchedWindow.targetFlags = targetFlags;
4027    touchedWindow.pointerIds = pointerIds;
4028}
4029
4030void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
4031    for (size_t i = 0 ; i < windows.size(); ) {
4032        TouchedWindow& window = windows.editItemAt(i);
4033        if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
4034                | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
4035            window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
4036            window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
4037            i += 1;
4038        } else {
4039            windows.removeAt(i);
4040        }
4041    }
4042}
4043
4044sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
4045    for (size_t i = 0; i < windows.size(); i++) {
4046        const TouchedWindow& window = windows.itemAt(i);
4047        if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
4048            return window.windowHandle;
4049        }
4050    }
4051    return NULL;
4052}
4053
4054bool InputDispatcher::TouchState::isSlippery() const {
4055    // Must have exactly one foreground window.
4056    bool haveSlipperyForegroundWindow = false;
4057    for (size_t i = 0; i < windows.size(); i++) {
4058        const TouchedWindow& window = windows.itemAt(i);
4059        if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
4060            if (haveSlipperyForegroundWindow
4061                    || !(window.windowHandle->getInfo()->layoutParamsFlags
4062                            & InputWindowInfo::FLAG_SLIPPERY)) {
4063                return false;
4064            }
4065            haveSlipperyForegroundWindow = true;
4066        }
4067    }
4068    return haveSlipperyForegroundWindow;
4069}
4070
4071
4072// --- InputDispatcherThread ---
4073
4074InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
4075        Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
4076}
4077
4078InputDispatcherThread::~InputDispatcherThread() {
4079}
4080
4081bool InputDispatcherThread::threadLoop() {
4082    mDispatcher->dispatchOnce();
4083    return true;
4084}
4085
4086} // namespace android
4087