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