InputDispatcher.cpp revision 9831d90db8fba7e967d22b1f86eea1d6ac831541
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    // Record information about the newly started dispatch cycle.
1930    connection->lastEventTime = eventEntry->eventTime;
1931    connection->lastDispatchTime = currentTime;
1932
1933    // Notify other system components.
1934    onDispatchCycleStartedLocked(currentTime, connection);
1935}
1936
1937void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1938        const sp<Connection>& connection, bool handled) {
1939#if DEBUG_DISPATCH_CYCLE
1940    ALOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
1941            "%01.1fms since dispatch, handled=%s",
1942            connection->getInputChannelName(),
1943            connection->getEventLatencyMillis(currentTime),
1944            connection->getDispatchLatencyMillis(currentTime),
1945            toString(handled));
1946#endif
1947
1948    if (connection->status == Connection::STATUS_BROKEN
1949            || connection->status == Connection::STATUS_ZOMBIE) {
1950        return;
1951    }
1952
1953    // Notify other system components and prepare to start the next dispatch cycle.
1954    onDispatchCycleFinishedLocked(currentTime, connection, handled);
1955}
1956
1957void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1958        const sp<Connection>& connection) {
1959    // Start the next dispatch cycle for this connection.
1960    while (! connection->outboundQueue.isEmpty()) {
1961        DispatchEntry* dispatchEntry = connection->outboundQueue.head;
1962        if (dispatchEntry->inProgress) {
1963            // Finished.
1964            connection->outboundQueue.dequeueAtHead();
1965            if (dispatchEntry->hasForegroundTarget()) {
1966                decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
1967            }
1968            delete dispatchEntry;
1969        } else {
1970            // If the head is not in progress, then we must have already dequeued the in
1971            // progress event, which means we actually aborted it.
1972            // So just start the next event for this connection.
1973            startDispatchCycleLocked(currentTime, connection);
1974            return;
1975        }
1976    }
1977}
1978
1979void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
1980        const sp<Connection>& connection, bool notify) {
1981#if DEBUG_DISPATCH_CYCLE
1982    ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
1983            connection->getInputChannelName(), toString(notify));
1984#endif
1985
1986    // Clear the outbound queue.
1987    drainOutboundQueueLocked(connection.get());
1988
1989    // The connection appears to be unrecoverably broken.
1990    // Ignore already broken or zombie connections.
1991    if (connection->status == Connection::STATUS_NORMAL) {
1992        connection->status = Connection::STATUS_BROKEN;
1993
1994        if (notify) {
1995            // Notify other system components.
1996            onDispatchCycleBrokenLocked(currentTime, connection);
1997        }
1998    }
1999}
2000
2001void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
2002    while (! connection->outboundQueue.isEmpty()) {
2003        DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
2004        if (dispatchEntry->hasForegroundTarget()) {
2005            decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
2006        }
2007        delete dispatchEntry;
2008    }
2009}
2010
2011int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
2012    InputDispatcher* d = static_cast<InputDispatcher*>(data);
2013
2014    { // acquire lock
2015        AutoMutex _l(d->mLock);
2016
2017        ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
2018        if (connectionIndex < 0) {
2019            ALOGE("Received spurious receive callback for unknown input channel.  "
2020                    "fd=%d, events=0x%x", fd, events);
2021            return 0; // remove the callback
2022        }
2023
2024        bool notify;
2025        sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
2026        if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2027            if (!(events & ALOOPER_EVENT_INPUT)) {
2028                ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
2029                        "events=0x%x", connection->getInputChannelName(), events);
2030                return 1;
2031            }
2032
2033            bool handled = false;
2034            status_t status = connection->inputPublisher.receiveFinishedSignal(&handled);
2035            if (!status) {
2036                nsecs_t currentTime = now();
2037                d->finishDispatchCycleLocked(currentTime, connection, handled);
2038                d->runCommandsLockedInterruptible();
2039                return 1;
2040            }
2041
2042            ALOGE("channel '%s' ~ Failed to receive finished signal.  status=%d",
2043                    connection->getInputChannelName(), status);
2044            notify = true;
2045        } else {
2046            // Monitor channels are never explicitly unregistered.
2047            // We do it automatically when the remote endpoint is closed so don't warn
2048            // about them.
2049            notify = !connection->monitor;
2050            if (notify) {
2051                ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred.  "
2052                        "events=0x%x", connection->getInputChannelName(), events);
2053            }
2054        }
2055
2056        // Unregister the channel.
2057        d->unregisterInputChannelLocked(connection->inputChannel, notify);
2058        return 0; // remove the callback
2059    } // release lock
2060}
2061
2062void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
2063        const CancelationOptions& options) {
2064    for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
2065        synthesizeCancelationEventsForConnectionLocked(
2066                mConnectionsByFd.valueAt(i), options);
2067    }
2068}
2069
2070void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2071        const sp<InputChannel>& channel, const CancelationOptions& options) {
2072    ssize_t index = getConnectionIndexLocked(channel);
2073    if (index >= 0) {
2074        synthesizeCancelationEventsForConnectionLocked(
2075                mConnectionsByFd.valueAt(index), options);
2076    }
2077}
2078
2079void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2080        const sp<Connection>& connection, const CancelationOptions& options) {
2081    if (connection->status == Connection::STATUS_BROKEN) {
2082        return;
2083    }
2084
2085    nsecs_t currentTime = now();
2086
2087    mTempCancelationEvents.clear();
2088    connection->inputState.synthesizeCancelationEvents(currentTime,
2089            mTempCancelationEvents, options);
2090
2091    if (!mTempCancelationEvents.isEmpty()) {
2092#if DEBUG_OUTBOUND_EVENT_DETAILS
2093        ALOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
2094                "with reality: %s, mode=%d.",
2095                connection->getInputChannelName(), mTempCancelationEvents.size(),
2096                options.reason, options.mode);
2097#endif
2098        for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
2099            EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
2100            switch (cancelationEventEntry->type) {
2101            case EventEntry::TYPE_KEY:
2102                logOutboundKeyDetailsLocked("cancel - ",
2103                        static_cast<KeyEntry*>(cancelationEventEntry));
2104                break;
2105            case EventEntry::TYPE_MOTION:
2106                logOutboundMotionDetailsLocked("cancel - ",
2107                        static_cast<MotionEntry*>(cancelationEventEntry));
2108                break;
2109            }
2110
2111            InputTarget target;
2112            sp<InputWindowHandle> windowHandle = getWindowHandleLocked(connection->inputChannel);
2113            if (windowHandle != NULL) {
2114                const InputWindowInfo* windowInfo = windowHandle->getInfo();
2115                target.xOffset = -windowInfo->frameLeft;
2116                target.yOffset = -windowInfo->frameTop;
2117                target.scaleFactor = windowInfo->scaleFactor;
2118            } else {
2119                target.xOffset = 0;
2120                target.yOffset = 0;
2121                target.scaleFactor = 1.0f;
2122            }
2123            target.inputChannel = connection->inputChannel;
2124            target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2125
2126            enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
2127                    &target, InputTarget::FLAG_DISPATCH_AS_IS);
2128
2129            cancelationEventEntry->release();
2130        }
2131
2132        if (!connection->outboundQueue.head->inProgress) {
2133            startDispatchCycleLocked(currentTime, connection);
2134        }
2135    }
2136}
2137
2138InputDispatcher::MotionEntry*
2139InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2140    ALOG_ASSERT(pointerIds.value != 0);
2141
2142    uint32_t splitPointerIndexMap[MAX_POINTERS];
2143    PointerProperties splitPointerProperties[MAX_POINTERS];
2144    PointerCoords splitPointerCoords[MAX_POINTERS];
2145
2146    uint32_t originalPointerCount = originalMotionEntry->pointerCount;
2147    uint32_t splitPointerCount = 0;
2148
2149    for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
2150            originalPointerIndex++) {
2151        const PointerProperties& pointerProperties =
2152                originalMotionEntry->pointerProperties[originalPointerIndex];
2153        uint32_t pointerId = uint32_t(pointerProperties.id);
2154        if (pointerIds.hasBit(pointerId)) {
2155            splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2156            splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2157            splitPointerCoords[splitPointerCount].copyFrom(
2158                    originalMotionEntry->pointerCoords[originalPointerIndex]);
2159            splitPointerCount += 1;
2160        }
2161    }
2162
2163    if (splitPointerCount != pointerIds.count()) {
2164        // This is bad.  We are missing some of the pointers that we expected to deliver.
2165        // Most likely this indicates that we received an ACTION_MOVE events that has
2166        // different pointer ids than we expected based on the previous ACTION_DOWN
2167        // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
2168        // in this way.
2169        ALOGW("Dropping split motion event because the pointer count is %d but "
2170                "we expected there to be %d pointers.  This probably means we received "
2171                "a broken sequence of pointer ids from the input device.",
2172                splitPointerCount, pointerIds.count());
2173        return NULL;
2174    }
2175
2176    int32_t action = originalMotionEntry->action;
2177    int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
2178    if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2179            || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2180        int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2181        const PointerProperties& pointerProperties =
2182                originalMotionEntry->pointerProperties[originalPointerIndex];
2183        uint32_t pointerId = uint32_t(pointerProperties.id);
2184        if (pointerIds.hasBit(pointerId)) {
2185            if (pointerIds.count() == 1) {
2186                // The first/last pointer went down/up.
2187                action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
2188                        ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
2189            } else {
2190                // A secondary pointer went down/up.
2191                uint32_t splitPointerIndex = 0;
2192                while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
2193                    splitPointerIndex += 1;
2194                }
2195                action = maskedAction | (splitPointerIndex
2196                        << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2197            }
2198        } else {
2199            // An unrelated pointer changed.
2200            action = AMOTION_EVENT_ACTION_MOVE;
2201        }
2202    }
2203
2204    MotionEntry* splitMotionEntry = new MotionEntry(
2205            originalMotionEntry->eventTime,
2206            originalMotionEntry->deviceId,
2207            originalMotionEntry->source,
2208            originalMotionEntry->policyFlags,
2209            action,
2210            originalMotionEntry->flags,
2211            originalMotionEntry->metaState,
2212            originalMotionEntry->buttonState,
2213            originalMotionEntry->edgeFlags,
2214            originalMotionEntry->xPrecision,
2215            originalMotionEntry->yPrecision,
2216            originalMotionEntry->downTime,
2217            splitPointerCount, splitPointerProperties, splitPointerCoords);
2218
2219    if (originalMotionEntry->injectionState) {
2220        splitMotionEntry->injectionState = originalMotionEntry->injectionState;
2221        splitMotionEntry->injectionState->refCount += 1;
2222    }
2223
2224    return splitMotionEntry;
2225}
2226
2227void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
2228#if DEBUG_INBOUND_EVENT_DETAILS
2229    ALOGD("notifyConfigurationChanged - eventTime=%lld", args->eventTime);
2230#endif
2231
2232    bool needWake;
2233    { // acquire lock
2234        AutoMutex _l(mLock);
2235
2236        ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(args->eventTime);
2237        needWake = enqueueInboundEventLocked(newEntry);
2238    } // release lock
2239
2240    if (needWake) {
2241        mLooper->wake();
2242    }
2243}
2244
2245void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
2246#if DEBUG_INBOUND_EVENT_DETAILS
2247    ALOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
2248            "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
2249            args->eventTime, args->deviceId, args->source, args->policyFlags,
2250            args->action, args->flags, args->keyCode, args->scanCode,
2251            args->metaState, args->downTime);
2252#endif
2253    if (!validateKeyEvent(args->action)) {
2254        return;
2255    }
2256
2257    uint32_t policyFlags = args->policyFlags;
2258    int32_t flags = args->flags;
2259    int32_t metaState = args->metaState;
2260    if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
2261        policyFlags |= POLICY_FLAG_VIRTUAL;
2262        flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2263    }
2264    if (policyFlags & POLICY_FLAG_ALT) {
2265        metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON;
2266    }
2267    if (policyFlags & POLICY_FLAG_ALT_GR) {
2268        metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON;
2269    }
2270    if (policyFlags & POLICY_FLAG_SHIFT) {
2271        metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON;
2272    }
2273    if (policyFlags & POLICY_FLAG_CAPS_LOCK) {
2274        metaState |= AMETA_CAPS_LOCK_ON;
2275    }
2276    if (policyFlags & POLICY_FLAG_FUNCTION) {
2277        metaState |= AMETA_FUNCTION_ON;
2278    }
2279
2280    policyFlags |= POLICY_FLAG_TRUSTED;
2281
2282    KeyEvent event;
2283    event.initialize(args->deviceId, args->source, args->action,
2284            flags, args->keyCode, args->scanCode, metaState, 0,
2285            args->downTime, args->eventTime);
2286
2287    mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
2288
2289    if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2290        flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2291    }
2292
2293    bool needWake;
2294    { // acquire lock
2295        mLock.lock();
2296
2297        if (mInputFilterEnabled) {
2298            mLock.unlock();
2299
2300            policyFlags |= POLICY_FLAG_FILTERED;
2301            if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2302                return; // event was consumed by the filter
2303            }
2304
2305            mLock.lock();
2306        }
2307
2308        int32_t repeatCount = 0;
2309        KeyEntry* newEntry = new KeyEntry(args->eventTime,
2310                args->deviceId, args->source, policyFlags,
2311                args->action, flags, args->keyCode, args->scanCode,
2312                metaState, repeatCount, args->downTime);
2313
2314        needWake = enqueueInboundEventLocked(newEntry);
2315        mLock.unlock();
2316    } // release lock
2317
2318    if (needWake) {
2319        mLooper->wake();
2320    }
2321}
2322
2323void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2324#if DEBUG_INBOUND_EVENT_DETAILS
2325    ALOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
2326            "action=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, edgeFlags=0x%x, "
2327            "xPrecision=%f, yPrecision=%f, downTime=%lld",
2328            args->eventTime, args->deviceId, args->source, args->policyFlags,
2329            args->action, args->flags, args->metaState, args->buttonState,
2330            args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
2331    for (uint32_t i = 0; i < args->pointerCount; i++) {
2332        ALOGD("  Pointer %d: id=%d, toolType=%d, "
2333                "x=%f, y=%f, pressure=%f, size=%f, "
2334                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
2335                "orientation=%f",
2336                i, args->pointerProperties[i].id,
2337                args->pointerProperties[i].toolType,
2338                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2339                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2340                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2341                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2342                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2343                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2344                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2345                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2346                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2347    }
2348#endif
2349    if (!validateMotionEvent(args->action, args->pointerCount, args->pointerProperties)) {
2350        return;
2351    }
2352
2353    uint32_t policyFlags = args->policyFlags;
2354    policyFlags |= POLICY_FLAG_TRUSTED;
2355    mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
2356
2357    bool needWake;
2358    { // acquire lock
2359        mLock.lock();
2360
2361        if (mInputFilterEnabled) {
2362            mLock.unlock();
2363
2364            MotionEvent event;
2365            event.initialize(args->deviceId, args->source, args->action, args->flags,
2366                    args->edgeFlags, args->metaState, args->buttonState, 0, 0,
2367                    args->xPrecision, args->yPrecision,
2368                    args->downTime, args->eventTime,
2369                    args->pointerCount, args->pointerProperties, args->pointerCoords);
2370
2371            policyFlags |= POLICY_FLAG_FILTERED;
2372            if (!mPolicy->filterInputEvent(&event, policyFlags)) {
2373                return; // event was consumed by the filter
2374            }
2375
2376            mLock.lock();
2377        }
2378
2379        // Just enqueue a new motion event.
2380        MotionEntry* newEntry = new MotionEntry(args->eventTime,
2381                args->deviceId, args->source, policyFlags,
2382                args->action, args->flags, args->metaState, args->buttonState,
2383                args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
2384                args->pointerCount, args->pointerProperties, args->pointerCoords);
2385
2386        needWake = enqueueInboundEventLocked(newEntry);
2387        mLock.unlock();
2388    } // release lock
2389
2390    if (needWake) {
2391        mLooper->wake();
2392    }
2393}
2394
2395void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
2396#if DEBUG_INBOUND_EVENT_DETAILS
2397    ALOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchCode=%d, switchValue=%d",
2398            args->eventTime, args->policyFlags,
2399            args->switchCode, args->switchValue);
2400#endif
2401
2402    uint32_t policyFlags = args->policyFlags;
2403    policyFlags |= POLICY_FLAG_TRUSTED;
2404    mPolicy->notifySwitch(args->eventTime,
2405            args->switchCode, args->switchValue, policyFlags);
2406}
2407
2408void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
2409#if DEBUG_INBOUND_EVENT_DETAILS
2410    ALOGD("notifyDeviceReset - eventTime=%lld, deviceId=%d",
2411            args->eventTime, args->deviceId);
2412#endif
2413
2414    bool needWake;
2415    { // acquire lock
2416        AutoMutex _l(mLock);
2417
2418        DeviceResetEntry* newEntry = new DeviceResetEntry(args->eventTime, args->deviceId);
2419        needWake = enqueueInboundEventLocked(newEntry);
2420    } // release lock
2421
2422    if (needWake) {
2423        mLooper->wake();
2424    }
2425}
2426
2427int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
2428        int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
2429        uint32_t policyFlags) {
2430#if DEBUG_INBOUND_EVENT_DETAILS
2431    ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
2432            "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
2433            event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
2434#endif
2435
2436    nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2437
2438    policyFlags |= POLICY_FLAG_INJECTED;
2439    if (hasInjectionPermission(injectorPid, injectorUid)) {
2440        policyFlags |= POLICY_FLAG_TRUSTED;
2441    }
2442
2443    EventEntry* firstInjectedEntry;
2444    EventEntry* lastInjectedEntry;
2445    switch (event->getType()) {
2446    case AINPUT_EVENT_TYPE_KEY: {
2447        const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
2448        int32_t action = keyEvent->getAction();
2449        if (! validateKeyEvent(action)) {
2450            return INPUT_EVENT_INJECTION_FAILED;
2451        }
2452
2453        int32_t flags = keyEvent->getFlags();
2454        if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
2455            policyFlags |= POLICY_FLAG_VIRTUAL;
2456        }
2457
2458        if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2459            mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
2460        }
2461
2462        if (policyFlags & POLICY_FLAG_WOKE_HERE) {
2463            flags |= AKEY_EVENT_FLAG_WOKE_HERE;
2464        }
2465
2466        mLock.lock();
2467        firstInjectedEntry = new KeyEntry(keyEvent->getEventTime(),
2468                keyEvent->getDeviceId(), keyEvent->getSource(),
2469                policyFlags, action, flags,
2470                keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
2471                keyEvent->getRepeatCount(), keyEvent->getDownTime());
2472        lastInjectedEntry = firstInjectedEntry;
2473        break;
2474    }
2475
2476    case AINPUT_EVENT_TYPE_MOTION: {
2477        const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
2478        int32_t action = motionEvent->getAction();
2479        size_t pointerCount = motionEvent->getPointerCount();
2480        const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
2481        if (! validateMotionEvent(action, pointerCount, pointerProperties)) {
2482            return INPUT_EVENT_INJECTION_FAILED;
2483        }
2484
2485        if (!(policyFlags & POLICY_FLAG_FILTERED)) {
2486            nsecs_t eventTime = motionEvent->getEventTime();
2487            mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
2488        }
2489
2490        mLock.lock();
2491        const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2492        const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2493        firstInjectedEntry = new MotionEntry(*sampleEventTimes,
2494                motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2495                action, motionEvent->getFlags(),
2496                motionEvent->getMetaState(), motionEvent->getButtonState(),
2497                motionEvent->getEdgeFlags(),
2498                motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2499                motionEvent->getDownTime(), uint32_t(pointerCount),
2500                pointerProperties, samplePointerCoords);
2501        lastInjectedEntry = firstInjectedEntry;
2502        for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2503            sampleEventTimes += 1;
2504            samplePointerCoords += pointerCount;
2505            MotionEntry* nextInjectedEntry = new MotionEntry(*sampleEventTimes,
2506                    motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
2507                    action, motionEvent->getFlags(),
2508                    motionEvent->getMetaState(), motionEvent->getButtonState(),
2509                    motionEvent->getEdgeFlags(),
2510                    motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2511                    motionEvent->getDownTime(), uint32_t(pointerCount),
2512                    pointerProperties, samplePointerCoords);
2513            lastInjectedEntry->next = nextInjectedEntry;
2514            lastInjectedEntry = nextInjectedEntry;
2515        }
2516        break;
2517    }
2518
2519    default:
2520        ALOGW("Cannot inject event of type %d", event->getType());
2521        return INPUT_EVENT_INJECTION_FAILED;
2522    }
2523
2524    InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
2525    if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2526        injectionState->injectionIsAsync = true;
2527    }
2528
2529    injectionState->refCount += 1;
2530    lastInjectedEntry->injectionState = injectionState;
2531
2532    bool needWake = false;
2533    for (EventEntry* entry = firstInjectedEntry; entry != NULL; ) {
2534        EventEntry* nextEntry = entry->next;
2535        needWake |= enqueueInboundEventLocked(entry);
2536        entry = nextEntry;
2537    }
2538
2539    mLock.unlock();
2540
2541    if (needWake) {
2542        mLooper->wake();
2543    }
2544
2545    int32_t injectionResult;
2546    { // acquire lock
2547        AutoMutex _l(mLock);
2548
2549        if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2550            injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2551        } else {
2552            for (;;) {
2553                injectionResult = injectionState->injectionResult;
2554                if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2555                    break;
2556                }
2557
2558                nsecs_t remainingTimeout = endTime - now();
2559                if (remainingTimeout <= 0) {
2560#if DEBUG_INJECTION
2561                    ALOGD("injectInputEvent - Timed out waiting for injection result "
2562                            "to become available.");
2563#endif
2564                    injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2565                    break;
2566                }
2567
2568                mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2569            }
2570
2571            if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2572                    && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
2573                while (injectionState->pendingForegroundDispatches != 0) {
2574#if DEBUG_INJECTION
2575                    ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
2576                            injectionState->pendingForegroundDispatches);
2577#endif
2578                    nsecs_t remainingTimeout = endTime - now();
2579                    if (remainingTimeout <= 0) {
2580#if DEBUG_INJECTION
2581                    ALOGD("injectInputEvent - Timed out waiting for pending foreground "
2582                            "dispatches to finish.");
2583#endif
2584                        injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2585                        break;
2586                    }
2587
2588                    mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2589                }
2590            }
2591        }
2592
2593        injectionState->release();
2594    } // release lock
2595
2596#if DEBUG_INJECTION
2597    ALOGD("injectInputEvent - Finished with result %d.  "
2598            "injectorPid=%d, injectorUid=%d",
2599            injectionResult, injectorPid, injectorUid);
2600#endif
2601
2602    return injectionResult;
2603}
2604
2605bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
2606    return injectorUid == 0
2607            || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
2608}
2609
2610void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
2611    InjectionState* injectionState = entry->injectionState;
2612    if (injectionState) {
2613#if DEBUG_INJECTION
2614        ALOGD("Setting input event injection result to %d.  "
2615                "injectorPid=%d, injectorUid=%d",
2616                 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
2617#endif
2618
2619        if (injectionState->injectionIsAsync
2620                && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
2621            // Log the outcome since the injector did not wait for the injection result.
2622            switch (injectionResult) {
2623            case INPUT_EVENT_INJECTION_SUCCEEDED:
2624                ALOGV("Asynchronous input event injection succeeded.");
2625                break;
2626            case INPUT_EVENT_INJECTION_FAILED:
2627                ALOGW("Asynchronous input event injection failed.");
2628                break;
2629            case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2630                ALOGW("Asynchronous input event injection permission denied.");
2631                break;
2632            case INPUT_EVENT_INJECTION_TIMED_OUT:
2633                ALOGW("Asynchronous input event injection timed out.");
2634                break;
2635            }
2636        }
2637
2638        injectionState->injectionResult = injectionResult;
2639        mInjectionResultAvailableCondition.broadcast();
2640    }
2641}
2642
2643void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2644    InjectionState* injectionState = entry->injectionState;
2645    if (injectionState) {
2646        injectionState->pendingForegroundDispatches += 1;
2647    }
2648}
2649
2650void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2651    InjectionState* injectionState = entry->injectionState;
2652    if (injectionState) {
2653        injectionState->pendingForegroundDispatches -= 1;
2654
2655        if (injectionState->pendingForegroundDispatches == 0) {
2656            mInjectionSyncFinishedCondition.broadcast();
2657        }
2658    }
2659}
2660
2661sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
2662        const sp<InputChannel>& inputChannel) const {
2663    size_t numWindows = mWindowHandles.size();
2664    for (size_t i = 0; i < numWindows; i++) {
2665        const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
2666        if (windowHandle->getInputChannel() == inputChannel) {
2667            return windowHandle;
2668        }
2669    }
2670    return NULL;
2671}
2672
2673bool InputDispatcher::hasWindowHandleLocked(
2674        const sp<InputWindowHandle>& windowHandle) const {
2675    size_t numWindows = mWindowHandles.size();
2676    for (size_t i = 0; i < numWindows; i++) {
2677        if (mWindowHandles.itemAt(i) == windowHandle) {
2678            return true;
2679        }
2680    }
2681    return false;
2682}
2683
2684void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) {
2685#if DEBUG_FOCUS
2686    ALOGD("setInputWindows");
2687#endif
2688    { // acquire lock
2689        AutoMutex _l(mLock);
2690
2691        Vector<sp<InputWindowHandle> > oldWindowHandles = mWindowHandles;
2692        mWindowHandles = inputWindowHandles;
2693
2694        sp<InputWindowHandle> newFocusedWindowHandle;
2695        bool foundHoveredWindow = false;
2696        for (size_t i = 0; i < mWindowHandles.size(); i++) {
2697            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
2698            if (!windowHandle->updateInfo() || windowHandle->getInputChannel() == NULL) {
2699                mWindowHandles.removeAt(i--);
2700                continue;
2701            }
2702            if (windowHandle->getInfo()->hasFocus) {
2703                newFocusedWindowHandle = windowHandle;
2704            }
2705            if (windowHandle == mLastHoverWindowHandle) {
2706                foundHoveredWindow = true;
2707            }
2708        }
2709
2710        if (!foundHoveredWindow) {
2711            mLastHoverWindowHandle = NULL;
2712        }
2713
2714        if (mFocusedWindowHandle != newFocusedWindowHandle) {
2715            if (mFocusedWindowHandle != NULL) {
2716#if DEBUG_FOCUS
2717                ALOGD("Focus left window: %s",
2718                        mFocusedWindowHandle->getName().string());
2719#endif
2720                sp<InputChannel> focusedInputChannel = mFocusedWindowHandle->getInputChannel();
2721                if (focusedInputChannel != NULL) {
2722                    CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
2723                            "focus left window");
2724                    synthesizeCancelationEventsForInputChannelLocked(
2725                            focusedInputChannel, options);
2726                }
2727            }
2728            if (newFocusedWindowHandle != NULL) {
2729#if DEBUG_FOCUS
2730                ALOGD("Focus entered window: %s",
2731                        newFocusedWindowHandle->getName().string());
2732#endif
2733            }
2734            mFocusedWindowHandle = newFocusedWindowHandle;
2735        }
2736
2737        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2738            TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2739            if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
2740#if DEBUG_FOCUS
2741                ALOGD("Touched window was removed: %s",
2742                        touchedWindow.windowHandle->getName().string());
2743#endif
2744                sp<InputChannel> touchedInputChannel =
2745                        touchedWindow.windowHandle->getInputChannel();
2746                if (touchedInputChannel != NULL) {
2747                    CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
2748                            "touched window was removed");
2749                    synthesizeCancelationEventsForInputChannelLocked(
2750                            touchedInputChannel, options);
2751                }
2752                mTouchState.windows.removeAt(i--);
2753            }
2754        }
2755
2756        // Release information for windows that are no longer present.
2757        // This ensures that unused input channels are released promptly.
2758        // Otherwise, they might stick around until the window handle is destroyed
2759        // which might not happen until the next GC.
2760        for (size_t i = 0; i < oldWindowHandles.size(); i++) {
2761            const sp<InputWindowHandle>& oldWindowHandle = oldWindowHandles.itemAt(i);
2762            if (!hasWindowHandleLocked(oldWindowHandle)) {
2763#if DEBUG_FOCUS
2764                ALOGD("Window went away: %s", oldWindowHandle->getName().string());
2765#endif
2766                oldWindowHandle->releaseInfo();
2767            }
2768        }
2769    } // release lock
2770
2771    // Wake up poll loop since it may need to make new input dispatching choices.
2772    mLooper->wake();
2773}
2774
2775void InputDispatcher::setFocusedApplication(
2776        const sp<InputApplicationHandle>& inputApplicationHandle) {
2777#if DEBUG_FOCUS
2778    ALOGD("setFocusedApplication");
2779#endif
2780    { // acquire lock
2781        AutoMutex _l(mLock);
2782
2783        if (inputApplicationHandle != NULL && inputApplicationHandle->updateInfo()) {
2784            if (mFocusedApplicationHandle != inputApplicationHandle) {
2785                if (mFocusedApplicationHandle != NULL) {
2786                    resetANRTimeoutsLocked();
2787                    mFocusedApplicationHandle->releaseInfo();
2788                }
2789                mFocusedApplicationHandle = inputApplicationHandle;
2790            }
2791        } else if (mFocusedApplicationHandle != NULL) {
2792            resetANRTimeoutsLocked();
2793            mFocusedApplicationHandle->releaseInfo();
2794            mFocusedApplicationHandle.clear();
2795        }
2796
2797#if DEBUG_FOCUS
2798        //logDispatchStateLocked();
2799#endif
2800    } // release lock
2801
2802    // Wake up poll loop since it may need to make new input dispatching choices.
2803    mLooper->wake();
2804}
2805
2806void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2807#if DEBUG_FOCUS
2808    ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2809#endif
2810
2811    bool changed;
2812    { // acquire lock
2813        AutoMutex _l(mLock);
2814
2815        if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2816            if (mDispatchFrozen && !frozen) {
2817                resetANRTimeoutsLocked();
2818            }
2819
2820            if (mDispatchEnabled && !enabled) {
2821                resetAndDropEverythingLocked("dispatcher is being disabled");
2822            }
2823
2824            mDispatchEnabled = enabled;
2825            mDispatchFrozen = frozen;
2826            changed = true;
2827        } else {
2828            changed = false;
2829        }
2830
2831#if DEBUG_FOCUS
2832        //logDispatchStateLocked();
2833#endif
2834    } // release lock
2835
2836    if (changed) {
2837        // Wake up poll loop since it may need to make new input dispatching choices.
2838        mLooper->wake();
2839    }
2840}
2841
2842void InputDispatcher::setInputFilterEnabled(bool enabled) {
2843#if DEBUG_FOCUS
2844    ALOGD("setInputFilterEnabled: enabled=%d", enabled);
2845#endif
2846
2847    { // acquire lock
2848        AutoMutex _l(mLock);
2849
2850        if (mInputFilterEnabled == enabled) {
2851            return;
2852        }
2853
2854        mInputFilterEnabled = enabled;
2855        resetAndDropEverythingLocked("input filter is being enabled or disabled");
2856    } // release lock
2857
2858    // Wake up poll loop since there might be work to do to drop everything.
2859    mLooper->wake();
2860}
2861
2862bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2863        const sp<InputChannel>& toChannel) {
2864#if DEBUG_FOCUS
2865    ALOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2866            fromChannel->getName().string(), toChannel->getName().string());
2867#endif
2868    { // acquire lock
2869        AutoMutex _l(mLock);
2870
2871        sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromChannel);
2872        sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toChannel);
2873        if (fromWindowHandle == NULL || toWindowHandle == NULL) {
2874#if DEBUG_FOCUS
2875            ALOGD("Cannot transfer focus because from or to window not found.");
2876#endif
2877            return false;
2878        }
2879        if (fromWindowHandle == toWindowHandle) {
2880#if DEBUG_FOCUS
2881            ALOGD("Trivial transfer to same window.");
2882#endif
2883            return true;
2884        }
2885
2886        bool found = false;
2887        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2888            const TouchedWindow& touchedWindow = mTouchState.windows[i];
2889            if (touchedWindow.windowHandle == fromWindowHandle) {
2890                int32_t oldTargetFlags = touchedWindow.targetFlags;
2891                BitSet32 pointerIds = touchedWindow.pointerIds;
2892
2893                mTouchState.windows.removeAt(i);
2894
2895                int32_t newTargetFlags = oldTargetFlags
2896                        & (InputTarget::FLAG_FOREGROUND
2897                                | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
2898                mTouchState.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
2899
2900                found = true;
2901                break;
2902            }
2903        }
2904
2905        if (! found) {
2906#if DEBUG_FOCUS
2907            ALOGD("Focus transfer failed because from window did not have focus.");
2908#endif
2909            return false;
2910        }
2911
2912        ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
2913        ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
2914        if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
2915            sp<Connection> fromConnection = mConnectionsByFd.valueAt(fromConnectionIndex);
2916            sp<Connection> toConnection = mConnectionsByFd.valueAt(toConnectionIndex);
2917
2918            fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
2919            CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
2920                    "transferring touch focus from this window to another window");
2921            synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
2922        }
2923
2924#if DEBUG_FOCUS
2925        logDispatchStateLocked();
2926#endif
2927    } // release lock
2928
2929    // Wake up poll loop since it may need to make new input dispatching choices.
2930    mLooper->wake();
2931    return true;
2932}
2933
2934void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
2935#if DEBUG_FOCUS
2936    ALOGD("Resetting and dropping all events (%s).", reason);
2937#endif
2938
2939    CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
2940    synthesizeCancelationEventsForAllConnectionsLocked(options);
2941
2942    resetKeyRepeatLocked();
2943    releasePendingEventLocked();
2944    drainInboundQueueLocked();
2945    resetANRTimeoutsLocked();
2946
2947    mTouchState.reset();
2948    mLastHoverWindowHandle.clear();
2949}
2950
2951void InputDispatcher::logDispatchStateLocked() {
2952    String8 dump;
2953    dumpDispatchStateLocked(dump);
2954
2955    char* text = dump.lockBuffer(dump.size());
2956    char* start = text;
2957    while (*start != '\0') {
2958        char* end = strchr(start, '\n');
2959        if (*end == '\n') {
2960            *(end++) = '\0';
2961        }
2962        ALOGD("%s", start);
2963        start = end;
2964    }
2965}
2966
2967void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
2968    dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
2969    dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
2970
2971    if (mFocusedApplicationHandle != NULL) {
2972        dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
2973                mFocusedApplicationHandle->getName().string(),
2974                mFocusedApplicationHandle->getDispatchingTimeout(
2975                        DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
2976    } else {
2977        dump.append(INDENT "FocusedApplication: <null>\n");
2978    }
2979    dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
2980            mFocusedWindowHandle != NULL ? mFocusedWindowHandle->getName().string() : "<null>");
2981
2982    dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
2983    dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
2984    dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
2985    dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
2986    if (!mTouchState.windows.isEmpty()) {
2987        dump.append(INDENT "TouchedWindows:\n");
2988        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2989            const TouchedWindow& touchedWindow = mTouchState.windows[i];
2990            dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2991                    i, touchedWindow.windowHandle->getName().string(),
2992                    touchedWindow.pointerIds.value,
2993                    touchedWindow.targetFlags);
2994        }
2995    } else {
2996        dump.append(INDENT "TouchedWindows: <none>\n");
2997    }
2998
2999    if (!mWindowHandles.isEmpty()) {
3000        dump.append(INDENT "Windows:\n");
3001        for (size_t i = 0; i < mWindowHandles.size(); i++) {
3002            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
3003            const InputWindowInfo* windowInfo = windowHandle->getInfo();
3004
3005            dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
3006                    "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
3007                    "frame=[%d,%d][%d,%d], scale=%f, "
3008                    "touchableRegion=",
3009                    i, windowInfo->name.string(),
3010                    toString(windowInfo->paused),
3011                    toString(windowInfo->hasFocus),
3012                    toString(windowInfo->hasWallpaper),
3013                    toString(windowInfo->visible),
3014                    toString(windowInfo->canReceiveKeys),
3015                    windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
3016                    windowInfo->layer,
3017                    windowInfo->frameLeft, windowInfo->frameTop,
3018                    windowInfo->frameRight, windowInfo->frameBottom,
3019                    windowInfo->scaleFactor);
3020            dumpRegion(dump, windowInfo->touchableRegion);
3021            dump.appendFormat(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3022            dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
3023                    windowInfo->ownerPid, windowInfo->ownerUid,
3024                    windowInfo->dispatchingTimeout / 1000000.0);
3025        }
3026    } else {
3027        dump.append(INDENT "Windows: <none>\n");
3028    }
3029
3030    if (!mMonitoringChannels.isEmpty()) {
3031        dump.append(INDENT "MonitoringChannels:\n");
3032        for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3033            const sp<InputChannel>& channel = mMonitoringChannels[i];
3034            dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
3035        }
3036    } else {
3037        dump.append(INDENT "MonitoringChannels: <none>\n");
3038    }
3039
3040    dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
3041
3042    if (isAppSwitchPendingLocked()) {
3043        dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
3044                (mAppSwitchDueTime - now()) / 1000000.0);
3045    } else {
3046        dump.append(INDENT "AppSwitch: not pending\n");
3047    }
3048}
3049
3050status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
3051        const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
3052#if DEBUG_REGISTRATION
3053    ALOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
3054            toString(monitor));
3055#endif
3056
3057    { // acquire lock
3058        AutoMutex _l(mLock);
3059
3060        if (getConnectionIndexLocked(inputChannel) >= 0) {
3061            ALOGW("Attempted to register already registered input channel '%s'",
3062                    inputChannel->getName().string());
3063            return BAD_VALUE;
3064        }
3065
3066        sp<Connection> connection = new Connection(inputChannel, inputWindowHandle, monitor);
3067
3068        int32_t fd = inputChannel->getFd();
3069        mConnectionsByFd.add(fd, connection);
3070
3071        if (monitor) {
3072            mMonitoringChannels.push(inputChannel);
3073        }
3074
3075        mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
3076
3077        runCommandsLockedInterruptible();
3078    } // release lock
3079    return OK;
3080}
3081
3082status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
3083#if DEBUG_REGISTRATION
3084    ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
3085#endif
3086
3087    { // acquire lock
3088        AutoMutex _l(mLock);
3089
3090        status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
3091        if (status) {
3092            return status;
3093        }
3094    } // release lock
3095
3096    // Wake the poll loop because removing the connection may have changed the current
3097    // synchronization state.
3098    mLooper->wake();
3099    return OK;
3100}
3101
3102status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
3103        bool notify) {
3104    ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
3105    if (connectionIndex < 0) {
3106        ALOGW("Attempted to unregister already unregistered input channel '%s'",
3107                inputChannel->getName().string());
3108        return BAD_VALUE;
3109    }
3110
3111    sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
3112    mConnectionsByFd.removeItemsAt(connectionIndex);
3113
3114    if (connection->monitor) {
3115        removeMonitorChannelLocked(inputChannel);
3116    }
3117
3118    mLooper->removeFd(inputChannel->getFd());
3119
3120    nsecs_t currentTime = now();
3121    abortBrokenDispatchCycleLocked(currentTime, connection, notify);
3122
3123    runCommandsLockedInterruptible();
3124
3125    connection->status = Connection::STATUS_ZOMBIE;
3126    return OK;
3127}
3128
3129void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
3130    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3131         if (mMonitoringChannels[i] == inputChannel) {
3132             mMonitoringChannels.removeAt(i);
3133             break;
3134         }
3135    }
3136}
3137
3138ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
3139    ssize_t connectionIndex = mConnectionsByFd.indexOfKey(inputChannel->getFd());
3140    if (connectionIndex >= 0) {
3141        sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
3142        if (connection->inputChannel.get() == inputChannel.get()) {
3143            return connectionIndex;
3144        }
3145    }
3146
3147    return -1;
3148}
3149
3150void InputDispatcher::onDispatchCycleStartedLocked(
3151        nsecs_t currentTime, const sp<Connection>& connection) {
3152}
3153
3154void InputDispatcher::onDispatchCycleFinishedLocked(
3155        nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
3156    CommandEntry* commandEntry = postCommandLocked(
3157            & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
3158    commandEntry->connection = connection;
3159    commandEntry->handled = handled;
3160}
3161
3162void InputDispatcher::onDispatchCycleBrokenLocked(
3163        nsecs_t currentTime, const sp<Connection>& connection) {
3164    ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3165            connection->getInputChannelName());
3166
3167    CommandEntry* commandEntry = postCommandLocked(
3168            & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
3169    commandEntry->connection = connection;
3170}
3171
3172void InputDispatcher::onANRLocked(
3173        nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
3174        const sp<InputWindowHandle>& windowHandle,
3175        nsecs_t eventTime, nsecs_t waitStartTime) {
3176    ALOGI("Application is not responding: %s.  "
3177            "%01.1fms since event, %01.1fms since wait started",
3178            getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
3179            (currentTime - eventTime) / 1000000.0,
3180            (currentTime - waitStartTime) / 1000000.0);
3181
3182    CommandEntry* commandEntry = postCommandLocked(
3183            & InputDispatcher::doNotifyANRLockedInterruptible);
3184    commandEntry->inputApplicationHandle = applicationHandle;
3185    commandEntry->inputWindowHandle = windowHandle;
3186}
3187
3188void InputDispatcher::doNotifyConfigurationChangedInterruptible(
3189        CommandEntry* commandEntry) {
3190    mLock.unlock();
3191
3192    mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
3193
3194    mLock.lock();
3195}
3196
3197void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
3198        CommandEntry* commandEntry) {
3199    sp<Connection> connection = commandEntry->connection;
3200
3201    if (connection->status != Connection::STATUS_ZOMBIE) {
3202        mLock.unlock();
3203
3204        mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
3205
3206        mLock.lock();
3207    }
3208}
3209
3210void InputDispatcher::doNotifyANRLockedInterruptible(
3211        CommandEntry* commandEntry) {
3212    mLock.unlock();
3213
3214    nsecs_t newTimeout = mPolicy->notifyANR(
3215            commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
3216
3217    mLock.lock();
3218
3219    resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
3220            commandEntry->inputWindowHandle != NULL
3221                    ? commandEntry->inputWindowHandle->getInputChannel() : NULL);
3222}
3223
3224void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3225        CommandEntry* commandEntry) {
3226    KeyEntry* entry = commandEntry->keyEntry;
3227
3228    KeyEvent event;
3229    initializeKeyEvent(&event, entry);
3230
3231    mLock.unlock();
3232
3233    nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
3234            &event, entry->policyFlags);
3235
3236    mLock.lock();
3237
3238    if (delay < 0) {
3239        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
3240    } else if (!delay) {
3241        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3242    } else {
3243        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
3244        entry->interceptKeyWakeupTime = now() + delay;
3245    }
3246    entry->release();
3247}
3248
3249void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
3250        CommandEntry* commandEntry) {
3251    sp<Connection> connection = commandEntry->connection;
3252    bool handled = commandEntry->handled;
3253
3254    bool skipNext = false;
3255    if (!connection->outboundQueue.isEmpty()) {
3256        DispatchEntry* dispatchEntry = connection->outboundQueue.head;
3257        if (dispatchEntry->inProgress) {
3258            if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3259                KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
3260                skipNext = afterKeyEventLockedInterruptible(connection,
3261                        dispatchEntry, keyEntry, handled);
3262            } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
3263                MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
3264                skipNext = afterMotionEventLockedInterruptible(connection,
3265                        dispatchEntry, motionEntry, handled);
3266            }
3267        }
3268    }
3269
3270    if (!skipNext) {
3271        startNextDispatchCycleLocked(now(), connection);
3272    }
3273}
3274
3275bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
3276        DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
3277    if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
3278        // Get the fallback key state.
3279        // Clear it out after dispatching the UP.
3280        int32_t originalKeyCode = keyEntry->keyCode;
3281        int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
3282        if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
3283            connection->inputState.removeFallbackKey(originalKeyCode);
3284        }
3285
3286        if (handled || !dispatchEntry->hasForegroundTarget()) {
3287            // If the application handles the original key for which we previously
3288            // generated a fallback or if the window is not a foreground window,
3289            // then cancel the associated fallback key, if any.
3290            if (fallbackKeyCode != -1) {
3291                if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
3292                    CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
3293                            "application handled the original non-fallback key "
3294                            "or is no longer a foreground target, "
3295                            "canceling previously dispatched fallback key");
3296                    options.keyCode = fallbackKeyCode;
3297                    synthesizeCancelationEventsForConnectionLocked(connection, options);
3298                }
3299                connection->inputState.removeFallbackKey(originalKeyCode);
3300            }
3301        } else {
3302            // If the application did not handle a non-fallback key, first check
3303            // that we are in a good state to perform unhandled key event processing
3304            // Then ask the policy what to do with it.
3305            bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
3306                    && keyEntry->repeatCount == 0;
3307            if (fallbackKeyCode == -1 && !initialDown) {
3308#if DEBUG_OUTBOUND_EVENT_DETAILS
3309                ALOGD("Unhandled key event: Skipping unhandled key event processing "
3310                        "since this is not an initial down.  "
3311                        "keyCode=%d, action=%d, repeatCount=%d",
3312                        originalKeyCode, keyEntry->action, keyEntry->repeatCount);
3313#endif
3314                return false;
3315            }
3316
3317            // Dispatch the unhandled key to the policy.
3318#if DEBUG_OUTBOUND_EVENT_DETAILS
3319            ALOGD("Unhandled key event: Asking policy to perform fallback action.  "
3320                    "keyCode=%d, action=%d, repeatCount=%d",
3321                    keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount);
3322#endif
3323            KeyEvent event;
3324            initializeKeyEvent(&event, keyEntry);
3325
3326            mLock.unlock();
3327
3328            bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
3329                    &event, keyEntry->policyFlags, &event);
3330
3331            mLock.lock();
3332
3333            if (connection->status != Connection::STATUS_NORMAL) {
3334                connection->inputState.removeFallbackKey(originalKeyCode);
3335                return true; // skip next cycle
3336            }
3337
3338            ALOG_ASSERT(connection->outboundQueue.head == dispatchEntry);
3339
3340            // Latch the fallback keycode for this key on an initial down.
3341            // The fallback keycode cannot change at any other point in the lifecycle.
3342            if (initialDown) {
3343                if (fallback) {
3344                    fallbackKeyCode = event.getKeyCode();
3345                } else {
3346                    fallbackKeyCode = AKEYCODE_UNKNOWN;
3347                }
3348                connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
3349            }
3350
3351            ALOG_ASSERT(fallbackKeyCode != -1);
3352
3353            // Cancel the fallback key if the policy decides not to send it anymore.
3354            // We will continue to dispatch the key to the policy but we will no
3355            // longer dispatch a fallback key to the application.
3356            if (fallbackKeyCode != AKEYCODE_UNKNOWN
3357                    && (!fallback || fallbackKeyCode != event.getKeyCode())) {
3358#if DEBUG_OUTBOUND_EVENT_DETAILS
3359                if (fallback) {
3360                    ALOGD("Unhandled key event: Policy requested to send key %d"
3361                            "as a fallback for %d, but on the DOWN it had requested "
3362                            "to send %d instead.  Fallback canceled.",
3363                            event.getKeyCode(), originalKeyCode, fallbackKeyCode);
3364                } else {
3365                    ALOGD("Unhandled key event: Policy did not request fallback for %d,"
3366                            "but on the DOWN it had requested to send %d.  "
3367                            "Fallback canceled.",
3368                            originalKeyCode, fallbackKeyCode);
3369                }
3370#endif
3371
3372                CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
3373                        "canceling fallback, policy no longer desires it");
3374                options.keyCode = fallbackKeyCode;
3375                synthesizeCancelationEventsForConnectionLocked(connection, options);
3376
3377                fallback = false;
3378                fallbackKeyCode = AKEYCODE_UNKNOWN;
3379                if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
3380                    connection->inputState.setFallbackKey(originalKeyCode,
3381                            fallbackKeyCode);
3382                }
3383            }
3384
3385#if DEBUG_OUTBOUND_EVENT_DETAILS
3386            {
3387                String8 msg;
3388                const KeyedVector<int32_t, int32_t>& fallbackKeys =
3389                        connection->inputState.getFallbackKeys();
3390                for (size_t i = 0; i < fallbackKeys.size(); i++) {
3391                    msg.appendFormat(", %d->%d", fallbackKeys.keyAt(i),
3392                            fallbackKeys.valueAt(i));
3393                }
3394                ALOGD("Unhandled key event: %d currently tracked fallback keys%s.",
3395                        fallbackKeys.size(), msg.string());
3396            }
3397#endif
3398
3399            if (fallback) {
3400                // Restart the dispatch cycle using the fallback key.
3401                keyEntry->eventTime = event.getEventTime();
3402                keyEntry->deviceId = event.getDeviceId();
3403                keyEntry->source = event.getSource();
3404                keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
3405                keyEntry->keyCode = fallbackKeyCode;
3406                keyEntry->scanCode = event.getScanCode();
3407                keyEntry->metaState = event.getMetaState();
3408                keyEntry->repeatCount = event.getRepeatCount();
3409                keyEntry->downTime = event.getDownTime();
3410                keyEntry->syntheticRepeat = false;
3411
3412#if DEBUG_OUTBOUND_EVENT_DETAILS
3413                ALOGD("Unhandled key event: Dispatching fallback key.  "
3414                        "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
3415                        originalKeyCode, fallbackKeyCode, keyEntry->metaState);
3416#endif
3417
3418                dispatchEntry->inProgress = false;
3419                startDispatchCycleLocked(now(), connection);
3420                return true; // already started next cycle
3421            } else {
3422#if DEBUG_OUTBOUND_EVENT_DETAILS
3423                ALOGD("Unhandled key event: No fallback key.");
3424#endif
3425            }
3426        }
3427    }
3428    return false;
3429}
3430
3431bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
3432        DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
3433    return false;
3434}
3435
3436void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
3437    mLock.unlock();
3438
3439    mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
3440
3441    mLock.lock();
3442}
3443
3444void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
3445    event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
3446            entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
3447            entry->downTime, entry->eventTime);
3448}
3449
3450void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
3451        int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
3452    // TODO Write some statistics about how long we spend waiting.
3453}
3454
3455void InputDispatcher::dump(String8& dump) {
3456    AutoMutex _l(mLock);
3457
3458    dump.append("Input Dispatcher State:\n");
3459    dumpDispatchStateLocked(dump);
3460
3461    dump.append(INDENT "Configuration:\n");
3462    dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
3463    dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n", mConfig.keyRepeatTimeout * 0.000001f);
3464}
3465
3466void InputDispatcher::monitor() {
3467    // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
3468    mLock.lock();
3469    mLooper->wake();
3470    mDispatcherIsAliveCondition.wait(mLock);
3471    mLock.unlock();
3472}
3473
3474
3475// --- InputDispatcher::Queue ---
3476
3477template <typename T>
3478uint32_t InputDispatcher::Queue<T>::count() const {
3479    uint32_t result = 0;
3480    for (const T* entry = head; entry; entry = entry->next) {
3481        result += 1;
3482    }
3483    return result;
3484}
3485
3486
3487// --- InputDispatcher::InjectionState ---
3488
3489InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
3490        refCount(1),
3491        injectorPid(injectorPid), injectorUid(injectorUid),
3492        injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
3493        pendingForegroundDispatches(0) {
3494}
3495
3496InputDispatcher::InjectionState::~InjectionState() {
3497}
3498
3499void InputDispatcher::InjectionState::release() {
3500    refCount -= 1;
3501    if (refCount == 0) {
3502        delete this;
3503    } else {
3504        ALOG_ASSERT(refCount > 0);
3505    }
3506}
3507
3508
3509// --- InputDispatcher::EventEntry ---
3510
3511InputDispatcher::EventEntry::EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags) :
3512        refCount(1), type(type), eventTime(eventTime), policyFlags(policyFlags),
3513        injectionState(NULL), dispatchInProgress(false) {
3514}
3515
3516InputDispatcher::EventEntry::~EventEntry() {
3517    releaseInjectionState();
3518}
3519
3520void InputDispatcher::EventEntry::release() {
3521    refCount -= 1;
3522    if (refCount == 0) {
3523        delete this;
3524    } else {
3525        ALOG_ASSERT(refCount > 0);
3526    }
3527}
3528
3529void InputDispatcher::EventEntry::releaseInjectionState() {
3530    if (injectionState) {
3531        injectionState->release();
3532        injectionState = NULL;
3533    }
3534}
3535
3536
3537// --- InputDispatcher::ConfigurationChangedEntry ---
3538
3539InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(nsecs_t eventTime) :
3540        EventEntry(TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
3541}
3542
3543InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
3544}
3545
3546
3547// --- InputDispatcher::DeviceResetEntry ---
3548
3549InputDispatcher::DeviceResetEntry::DeviceResetEntry(nsecs_t eventTime, int32_t deviceId) :
3550        EventEntry(TYPE_DEVICE_RESET, eventTime, 0),
3551        deviceId(deviceId) {
3552}
3553
3554InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
3555}
3556
3557
3558// --- InputDispatcher::KeyEntry ---
3559
3560InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
3561        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
3562        int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
3563        int32_t repeatCount, nsecs_t downTime) :
3564        EventEntry(TYPE_KEY, eventTime, policyFlags),
3565        deviceId(deviceId), source(source), action(action), flags(flags),
3566        keyCode(keyCode), scanCode(scanCode), metaState(metaState),
3567        repeatCount(repeatCount), downTime(downTime),
3568        syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
3569        interceptKeyWakeupTime(0) {
3570}
3571
3572InputDispatcher::KeyEntry::~KeyEntry() {
3573}
3574
3575void InputDispatcher::KeyEntry::recycle() {
3576    releaseInjectionState();
3577
3578    dispatchInProgress = false;
3579    syntheticRepeat = false;
3580    interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
3581    interceptKeyWakeupTime = 0;
3582}
3583
3584
3585// --- InputDispatcher::MotionEntry ---
3586
3587InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,
3588        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
3589        int32_t metaState, int32_t buttonState,
3590        int32_t edgeFlags, float xPrecision, float yPrecision,
3591        nsecs_t downTime, uint32_t pointerCount,
3592        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) :
3593        EventEntry(TYPE_MOTION, eventTime, policyFlags),
3594        eventTime(eventTime),
3595        deviceId(deviceId), source(source), action(action), flags(flags),
3596        metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
3597        xPrecision(xPrecision), yPrecision(yPrecision),
3598        downTime(downTime), pointerCount(pointerCount) {
3599    for (uint32_t i = 0; i < pointerCount; i++) {
3600        this->pointerProperties[i].copyFrom(pointerProperties[i]);
3601        this->pointerCoords[i].copyFrom(pointerCoords[i]);
3602    }
3603}
3604
3605InputDispatcher::MotionEntry::~MotionEntry() {
3606}
3607
3608
3609// --- InputDispatcher::DispatchEntry ---
3610
3611InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
3612        int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) :
3613        eventEntry(eventEntry), targetFlags(targetFlags),
3614        xOffset(xOffset), yOffset(yOffset), scaleFactor(scaleFactor),
3615        inProgress(false),
3616        resolvedAction(0), resolvedFlags(0) {
3617    eventEntry->refCount += 1;
3618}
3619
3620InputDispatcher::DispatchEntry::~DispatchEntry() {
3621    eventEntry->release();
3622}
3623
3624
3625// --- InputDispatcher::InputState ---
3626
3627InputDispatcher::InputState::InputState() {
3628}
3629
3630InputDispatcher::InputState::~InputState() {
3631}
3632
3633bool InputDispatcher::InputState::isNeutral() const {
3634    return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3635}
3636
3637bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source) const {
3638    for (size_t i = 0; i < mMotionMementos.size(); i++) {
3639        const MotionMemento& memento = mMotionMementos.itemAt(i);
3640        if (memento.deviceId == deviceId
3641                && memento.source == source
3642                && memento.hovering) {
3643            return true;
3644        }
3645    }
3646    return false;
3647}
3648
3649bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
3650        int32_t action, int32_t flags) {
3651    switch (action) {
3652    case AKEY_EVENT_ACTION_UP: {
3653        if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
3654            for (size_t i = 0; i < mFallbackKeys.size(); ) {
3655                if (mFallbackKeys.valueAt(i) == entry->keyCode) {
3656                    mFallbackKeys.removeItemsAt(i);
3657                } else {
3658                    i += 1;
3659                }
3660            }
3661        }
3662        ssize_t index = findKeyMemento(entry);
3663        if (index >= 0) {
3664            mKeyMementos.removeAt(index);
3665            return true;
3666        }
3667        /* FIXME: We can't just drop the key up event because that prevents creating
3668         * popup windows that are automatically shown when a key is held and then
3669         * dismissed when the key is released.  The problem is that the popup will
3670         * not have received the original key down, so the key up will be considered
3671         * to be inconsistent with its observed state.  We could perhaps handle this
3672         * by synthesizing a key down but that will cause other problems.
3673         *
3674         * So for now, allow inconsistent key up events to be dispatched.
3675         *
3676#if DEBUG_OUTBOUND_EVENT_DETAILS
3677        ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
3678                "keyCode=%d, scanCode=%d",
3679                entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
3680#endif
3681        return false;
3682        */
3683        return true;
3684    }
3685
3686    case AKEY_EVENT_ACTION_DOWN: {
3687        ssize_t index = findKeyMemento(entry);
3688        if (index >= 0) {
3689            mKeyMementos.removeAt(index);
3690        }
3691        addKeyMemento(entry, flags);
3692        return true;
3693    }
3694
3695    default:
3696        return true;
3697    }
3698}
3699
3700bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
3701        int32_t action, int32_t flags) {
3702    int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
3703    switch (actionMasked) {
3704    case AMOTION_EVENT_ACTION_UP:
3705    case AMOTION_EVENT_ACTION_CANCEL: {
3706        ssize_t index = findMotionMemento(entry, false /*hovering*/);
3707        if (index >= 0) {
3708            mMotionMementos.removeAt(index);
3709            return true;
3710        }
3711#if DEBUG_OUTBOUND_EVENT_DETAILS
3712        ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
3713                "actionMasked=%d",
3714                entry->deviceId, entry->source, actionMasked);
3715#endif
3716        return false;
3717    }
3718
3719    case AMOTION_EVENT_ACTION_DOWN: {
3720        ssize_t index = findMotionMemento(entry, false /*hovering*/);
3721        if (index >= 0) {
3722            mMotionMementos.removeAt(index);
3723        }
3724        addMotionMemento(entry, flags, false /*hovering*/);
3725        return true;
3726    }
3727
3728    case AMOTION_EVENT_ACTION_POINTER_UP:
3729    case AMOTION_EVENT_ACTION_POINTER_DOWN:
3730    case AMOTION_EVENT_ACTION_MOVE: {
3731        ssize_t index = findMotionMemento(entry, false /*hovering*/);
3732        if (index >= 0) {
3733            MotionMemento& memento = mMotionMementos.editItemAt(index);
3734            memento.setPointers(entry);
3735            return true;
3736        }
3737        if (actionMasked == AMOTION_EVENT_ACTION_MOVE
3738                && (entry->source & (AINPUT_SOURCE_CLASS_JOYSTICK
3739                        | AINPUT_SOURCE_CLASS_NAVIGATION))) {
3740            // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
3741            return true;
3742        }
3743#if DEBUG_OUTBOUND_EVENT_DETAILS
3744        ALOGD("Dropping inconsistent motion pointer up/down or move event: "
3745                "deviceId=%d, source=%08x, actionMasked=%d",
3746                entry->deviceId, entry->source, actionMasked);
3747#endif
3748        return false;
3749    }
3750
3751    case AMOTION_EVENT_ACTION_HOVER_EXIT: {
3752        ssize_t index = findMotionMemento(entry, true /*hovering*/);
3753        if (index >= 0) {
3754            mMotionMementos.removeAt(index);
3755            return true;
3756        }
3757#if DEBUG_OUTBOUND_EVENT_DETAILS
3758        ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x",
3759                entry->deviceId, entry->source);
3760#endif
3761        return false;
3762    }
3763
3764    case AMOTION_EVENT_ACTION_HOVER_ENTER:
3765    case AMOTION_EVENT_ACTION_HOVER_MOVE: {
3766        ssize_t index = findMotionMemento(entry, true /*hovering*/);
3767        if (index >= 0) {
3768            mMotionMementos.removeAt(index);
3769        }
3770        addMotionMemento(entry, flags, true /*hovering*/);
3771        return true;
3772    }
3773
3774    default:
3775        return true;
3776    }
3777}
3778
3779ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
3780    for (size_t i = 0; i < mKeyMementos.size(); i++) {
3781        const KeyMemento& memento = mKeyMementos.itemAt(i);
3782        if (memento.deviceId == entry->deviceId
3783                && memento.source == entry->source
3784                && memento.keyCode == entry->keyCode
3785                && memento.scanCode == entry->scanCode) {
3786            return i;
3787        }
3788    }
3789    return -1;
3790}
3791
3792ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
3793        bool hovering) const {
3794    for (size_t i = 0; i < mMotionMementos.size(); i++) {
3795        const MotionMemento& memento = mMotionMementos.itemAt(i);
3796        if (memento.deviceId == entry->deviceId
3797                && memento.source == entry->source
3798                && memento.hovering == hovering) {
3799            return i;
3800        }
3801    }
3802    return -1;
3803}
3804
3805void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
3806    mKeyMementos.push();
3807    KeyMemento& memento = mKeyMementos.editTop();
3808    memento.deviceId = entry->deviceId;
3809    memento.source = entry->source;
3810    memento.keyCode = entry->keyCode;
3811    memento.scanCode = entry->scanCode;
3812    memento.flags = flags;
3813    memento.downTime = entry->downTime;
3814}
3815
3816void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
3817        int32_t flags, bool hovering) {
3818    mMotionMementos.push();
3819    MotionMemento& memento = mMotionMementos.editTop();
3820    memento.deviceId = entry->deviceId;
3821    memento.source = entry->source;
3822    memento.flags = flags;
3823    memento.xPrecision = entry->xPrecision;
3824    memento.yPrecision = entry->yPrecision;
3825    memento.downTime = entry->downTime;
3826    memento.setPointers(entry);
3827    memento.hovering = hovering;
3828}
3829
3830void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3831    pointerCount = entry->pointerCount;
3832    for (uint32_t i = 0; i < entry->pointerCount; i++) {
3833        pointerProperties[i].copyFrom(entry->pointerProperties[i]);
3834        pointerCoords[i].copyFrom(entry->pointerCoords[i]);
3835    }
3836}
3837
3838void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
3839        Vector<EventEntry*>& outEvents, const CancelationOptions& options) {
3840    for (size_t i = 0; i < mKeyMementos.size(); i++) {
3841        const KeyMemento& memento = mKeyMementos.itemAt(i);
3842        if (shouldCancelKey(memento, options)) {
3843            outEvents.push(new KeyEntry(currentTime,
3844                    memento.deviceId, memento.source, 0,
3845                    AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
3846                    memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3847        }
3848    }
3849
3850    for (size_t i = 0; i < mMotionMementos.size(); i++) {
3851        const MotionMemento& memento = mMotionMementos.itemAt(i);
3852        if (shouldCancelMotion(memento, options)) {
3853            outEvents.push(new MotionEntry(currentTime,
3854                    memento.deviceId, memento.source, 0,
3855                    memento.hovering
3856                            ? AMOTION_EVENT_ACTION_HOVER_EXIT
3857                            : AMOTION_EVENT_ACTION_CANCEL,
3858                    memento.flags, 0, 0, 0,
3859                    memento.xPrecision, memento.yPrecision, memento.downTime,
3860                    memento.pointerCount, memento.pointerProperties, memento.pointerCoords));
3861        }
3862    }
3863}
3864
3865void InputDispatcher::InputState::clear() {
3866    mKeyMementos.clear();
3867    mMotionMementos.clear();
3868    mFallbackKeys.clear();
3869}
3870
3871void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
3872    for (size_t i = 0; i < mMotionMementos.size(); i++) {
3873        const MotionMemento& memento = mMotionMementos.itemAt(i);
3874        if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
3875            for (size_t j = 0; j < other.mMotionMementos.size(); ) {
3876                const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
3877                if (memento.deviceId == otherMemento.deviceId
3878                        && memento.source == otherMemento.source) {
3879                    other.mMotionMementos.removeAt(j);
3880                } else {
3881                    j += 1;
3882                }
3883            }
3884            other.mMotionMementos.push(memento);
3885        }
3886    }
3887}
3888
3889int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
3890    ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
3891    return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
3892}
3893
3894void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
3895        int32_t fallbackKeyCode) {
3896    ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
3897    if (index >= 0) {
3898        mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
3899    } else {
3900        mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
3901    }
3902}
3903
3904void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
3905    mFallbackKeys.removeItem(originalKeyCode);
3906}
3907
3908bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
3909        const CancelationOptions& options) {
3910    if (options.keyCode != -1 && memento.keyCode != options.keyCode) {
3911        return false;
3912    }
3913
3914    if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
3915        return false;
3916    }
3917
3918    switch (options.mode) {
3919    case CancelationOptions::CANCEL_ALL_EVENTS:
3920    case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
3921        return true;
3922    case CancelationOptions::CANCEL_FALLBACK_EVENTS:
3923        return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
3924    default:
3925        return false;
3926    }
3927}
3928
3929bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
3930        const CancelationOptions& options) {
3931    if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
3932        return false;
3933    }
3934
3935    switch (options.mode) {
3936    case CancelationOptions::CANCEL_ALL_EVENTS:
3937        return true;
3938    case CancelationOptions::CANCEL_POINTER_EVENTS:
3939        return memento.source & AINPUT_SOURCE_CLASS_POINTER;
3940    case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
3941        return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
3942    default:
3943        return false;
3944    }
3945}
3946
3947
3948// --- InputDispatcher::Connection ---
3949
3950InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
3951        const sp<InputWindowHandle>& inputWindowHandle, bool monitor) :
3952        status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
3953        monitor(monitor),
3954        inputPublisher(inputChannel),
3955        lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
3956}
3957
3958InputDispatcher::Connection::~Connection() {
3959}
3960
3961const char* InputDispatcher::Connection::getStatusLabel() const {
3962    switch (status) {
3963    case STATUS_NORMAL:
3964        return "NORMAL";
3965
3966    case STATUS_BROKEN:
3967        return "BROKEN";
3968
3969    case STATUS_ZOMBIE:
3970        return "ZOMBIE";
3971
3972    default:
3973        return "UNKNOWN";
3974    }
3975}
3976
3977InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3978        const EventEntry* eventEntry) const {
3979    for (DispatchEntry* dispatchEntry = outboundQueue.tail; dispatchEntry;
3980            dispatchEntry = dispatchEntry->prev) {
3981        if (dispatchEntry->eventEntry == eventEntry) {
3982            return dispatchEntry;
3983        }
3984    }
3985    return NULL;
3986}
3987
3988
3989// --- InputDispatcher::CommandEntry ---
3990
3991InputDispatcher::CommandEntry::CommandEntry(Command command) :
3992    command(command), eventTime(0), keyEntry(NULL), userActivityEventType(0), handled(false) {
3993}
3994
3995InputDispatcher::CommandEntry::~CommandEntry() {
3996}
3997
3998
3999// --- InputDispatcher::TouchState ---
4000
4001InputDispatcher::TouchState::TouchState() :
4002    down(false), split(false), deviceId(-1), source(0) {
4003}
4004
4005InputDispatcher::TouchState::~TouchState() {
4006}
4007
4008void InputDispatcher::TouchState::reset() {
4009    down = false;
4010    split = false;
4011    deviceId = -1;
4012    source = 0;
4013    windows.clear();
4014}
4015
4016void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
4017    down = other.down;
4018    split = other.split;
4019    deviceId = other.deviceId;
4020    source = other.source;
4021    windows = other.windows;
4022}
4023
4024void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
4025        int32_t targetFlags, BitSet32 pointerIds) {
4026    if (targetFlags & InputTarget::FLAG_SPLIT) {
4027        split = true;
4028    }
4029
4030    for (size_t i = 0; i < windows.size(); i++) {
4031        TouchedWindow& touchedWindow = windows.editItemAt(i);
4032        if (touchedWindow.windowHandle == windowHandle) {
4033            touchedWindow.targetFlags |= targetFlags;
4034            if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
4035                touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
4036            }
4037            touchedWindow.pointerIds.value |= pointerIds.value;
4038            return;
4039        }
4040    }
4041
4042    windows.push();
4043
4044    TouchedWindow& touchedWindow = windows.editTop();
4045    touchedWindow.windowHandle = windowHandle;
4046    touchedWindow.targetFlags = targetFlags;
4047    touchedWindow.pointerIds = pointerIds;
4048}
4049
4050void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
4051    for (size_t i = 0 ; i < windows.size(); ) {
4052        TouchedWindow& window = windows.editItemAt(i);
4053        if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
4054                | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
4055            window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
4056            window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
4057            i += 1;
4058        } else {
4059            windows.removeAt(i);
4060        }
4061    }
4062}
4063
4064sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
4065    for (size_t i = 0; i < windows.size(); i++) {
4066        const TouchedWindow& window = windows.itemAt(i);
4067        if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
4068            return window.windowHandle;
4069        }
4070    }
4071    return NULL;
4072}
4073
4074bool InputDispatcher::TouchState::isSlippery() const {
4075    // Must have exactly one foreground window.
4076    bool haveSlipperyForegroundWindow = false;
4077    for (size_t i = 0; i < windows.size(); i++) {
4078        const TouchedWindow& window = windows.itemAt(i);
4079        if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
4080            if (haveSlipperyForegroundWindow
4081                    || !(window.windowHandle->getInfo()->layoutParamsFlags
4082                            & InputWindowInfo::FLAG_SLIPPERY)) {
4083                return false;
4084            }
4085            haveSlipperyForegroundWindow = true;
4086        }
4087    }
4088    return haveSlipperyForegroundWindow;
4089}
4090
4091
4092// --- InputDispatcherThread ---
4093
4094InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
4095        Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
4096}
4097
4098InputDispatcherThread::~InputDispatcherThread() {
4099}
4100
4101bool InputDispatcherThread::threadLoop() {
4102    mDispatcher->dispatchOnce();
4103    return true;
4104}
4105
4106} // namespace android
4107