widget/gonk/libui/InputDispatcher.cpp

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     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  */
    17 #define LOG_TAG "InputDispatcher"
    18 #define ATRACE_TAG ATRACE_TAG_INPUT
    20 //#define LOG_NDEBUG 0
    21 #include "cutils_log.h"
    23 // Log detailed debug messages about each inbound event notification to the dispatcher.
    24 #define DEBUG_INBOUND_EVENT_DETAILS 0
    26 // Log detailed debug messages about each outbound event processed by the dispatcher.
    27 #define DEBUG_OUTBOUND_EVENT_DETAILS 0
    29 // Log debug messages about the dispatch cycle.
    30 #define DEBUG_DISPATCH_CYCLE 0
    32 // Log debug messages about registrations.
    33 #define DEBUG_REGISTRATION 0
    35 // Log debug messages about input event injection.
    36 #define DEBUG_INJECTION 0
    38 // Log debug messages about input focus tracking.
    39 #define DEBUG_FOCUS 0
    41 // Log debug messages about the app switch latency optimization.
    42 #define DEBUG_APP_SWITCH 0
    44 // Log debug messages about hover events.
    45 #define DEBUG_HOVER 0
    47 #include "InputDispatcher.h"
    49 #include "Trace.h"
    50 #include "PowerManager.h"
    52 #include <stddef.h>
    53 #include <unistd.h>
    54 #include <errno.h>
    55 #include <limits.h>
    56 #include <time.h>
    58 #define INDENT "  "
    59 #define INDENT2 "    "
    60 #define INDENT3 "      "
    61 #define INDENT4 "        "
    63 namespace android {
    65 // Default input dispatching timeout if there is no focused application or paused window
    66 // from which to determine an appropriate dispatching timeout.
    67 const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
    69 // Amount of time to allow for all pending events to be processed when an app switch
    70 // key is on the way.  This is used to preempt input dispatch and drop input events
    71 // when an application takes too long to respond and the user has pressed an app switch key.
    72 const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
    74 // Amount of time to allow for an event to be dispatched (measured since its eventTime)
    75 // before considering it stale and dropping it.
    76 const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
    78 // Amount of time to allow touch events to be streamed out to a connection before requiring
    79 // that the first event be finished.  This value extends the ANR timeout by the specified
    80 // amount.  For example, if streaming is allowed to get ahead by one second relative to the
    81 // queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
    82 const nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
    84 // Log a warning when an event takes longer than this to process, even if an ANR does not occur.
    85 const nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
    88 static inline nsecs_t now() {
    89     return systemTime(SYSTEM_TIME_MONOTONIC);
    90 }
    92 static inline const char* toString(bool value) {
    93     return value ? "true" : "false";
    94 }
    96 static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
    97     return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
    98             >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
    99 }
   101 static bool isValidKeyAction(int32_t action) {
   102     switch (action) {
   103     case AKEY_EVENT_ACTION_DOWN:
   104     case AKEY_EVENT_ACTION_UP:
   105         return true;
   106     default:
   107         return false;
   108     }
   109 }
   111 static bool validateKeyEvent(int32_t action) {
   112     if (! isValidKeyAction(action)) {
   113         ALOGE("Key event has invalid action code 0x%x", action);
   114         return false;
   115     }
   116     return true;
   117 }
   119 static bool isValidMotionAction(int32_t action, size_t pointerCount) {
   120     switch (action & AMOTION_EVENT_ACTION_MASK) {
   121     case AMOTION_EVENT_ACTION_DOWN:
   122     case AMOTION_EVENT_ACTION_UP:
   123     case AMOTION_EVENT_ACTION_CANCEL:
   124     case AMOTION_EVENT_ACTION_MOVE:
   125     case AMOTION_EVENT_ACTION_OUTSIDE:
   126     case AMOTION_EVENT_ACTION_HOVER_ENTER:
   127     case AMOTION_EVENT_ACTION_HOVER_MOVE:
   128     case AMOTION_EVENT_ACTION_HOVER_EXIT:
   129     case AMOTION_EVENT_ACTION_SCROLL:
   130         return true;
   131     case AMOTION_EVENT_ACTION_POINTER_DOWN:
   132     case AMOTION_EVENT_ACTION_POINTER_UP: {
   133         int32_t index = getMotionEventActionPointerIndex(action);
   134         return index >= 0 && size_t(index) < pointerCount;
   135     }
   136     default:
   137         return false;
   138     }
   139 }
   141 static bool validateMotionEvent(int32_t action, size_t pointerCount,
   142         const PointerProperties* pointerProperties) {
   143     if (! isValidMotionAction(action, pointerCount)) {
   144         ALOGE("Motion event has invalid action code 0x%x", action);
   145         return false;
   146     }
   147     if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
   148         ALOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
   149                 pointerCount, MAX_POINTERS);
   150         return false;
   151     }
   152     BitSet32 pointerIdBits;
   153     for (size_t i = 0; i < pointerCount; i++) {
   154         int32_t id = pointerProperties[i].id;
   155         if (id < 0 || id > MAX_POINTER_ID) {
   156             ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
   157                     id, MAX_POINTER_ID);
   158             return false;
   159         }
   160         if (pointerIdBits.hasBit(id)) {
   161             ALOGE("Motion event has duplicate pointer id %d", id);
   162             return false;
   163         }
   164         pointerIdBits.markBit(id);
   165     }
   166     return true;
   167 }
   169 static bool isMainDisplay(int32_t displayId) {
   170     return displayId == ADISPLAY_ID_DEFAULT || displayId == ADISPLAY_ID_NONE;
   171 }
   173 static void dumpRegion(String8& dump, const SkRegion& region) {
   174     if (region.isEmpty()) {
   175         dump.append("<empty>");
   176         return;
   177     }
   179     bool first = true;
   180     for (SkRegion::Iterator it(region); !it.done(); it.next()) {
   181         if (first) {
   182             first = false;
   183         } else {
   184             dump.append("|");
   185         }
   186         const SkIRect& rect = it.rect();
   187         dump.appendFormat("[%d,%d][%d,%d]", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
   188     }
   189 }
   192 // --- InputDispatcher ---
   194 InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
   195     mPolicy(policy),
   196     mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
   197     mNextUnblockedEvent(NULL),
   198     mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false),
   199     mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
   200     mLooper = new Looper(false);
   202     mKeyRepeatState.lastKeyEntry = NULL;
   204     policy->getDispatcherConfiguration(&mConfig);
   205 }
   207 InputDispatcher::~InputDispatcher() {
   208     { // acquire lock
   209         AutoMutex _l(mLock);
   211         resetKeyRepeatLocked();
   212         releasePendingEventLocked();
   213         drainInboundQueueLocked();
   214     }
   216     while (mConnectionsByFd.size() != 0) {
   217         unregisterInputChannel(mConnectionsByFd.valueAt(0)->inputChannel);
   218     }
   219 }
   221 void InputDispatcher::dispatchOnce() {
   222     nsecs_t nextWakeupTime = LONG_LONG_MAX;
   223     { // acquire lock
   224         AutoMutex _l(mLock);
   225         mDispatcherIsAliveCondition.broadcast();
   227         // Run a dispatch loop if there are no pending commands.
   228         // The dispatch loop might enqueue commands to run afterwards.
   229         if (!haveCommandsLocked()) {
   230             dispatchOnceInnerLocked(&nextWakeupTime);
   231         }
   233         // Run all pending commands if there are any.
   234         // If any commands were run then force the next poll to wake up immediately.
   235         if (runCommandsLockedInterruptible()) {
   236             nextWakeupTime = LONG_LONG_MIN;
   237         }
   238     } // release lock
   240     // Wait for callback or timeout or wake.  (make sure we round up, not down)
   241     nsecs_t currentTime = now();
   242     int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
   243     mLooper->pollOnce(timeoutMillis);
   244 }
   246 void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
   247     nsecs_t currentTime = now();
   249     // Reset the key repeat timer whenever we disallow key events, even if the next event
   250     // is not a key.  This is to ensure that we abort a key repeat if the device is just coming
   251     // out of sleep.
   252     if (!mPolicy->isKeyRepeatEnabled()) {
   253         resetKeyRepeatLocked();
   254     }
   256     // If dispatching is frozen, do not process timeouts or try to deliver any new events.
   257     if (mDispatchFrozen) {
   258 #if DEBUG_FOCUS
   259         ALOGD("Dispatch frozen.  Waiting some more.");
   260 #endif
   261         return;
   262     }
   264     // Optimize latency of app switches.
   265     // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
   266     // been pressed.  When it expires, we preempt dispatch and drop all other pending events.
   267     bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
   268     if (mAppSwitchDueTime < *nextWakeupTime) {
   269         *nextWakeupTime = mAppSwitchDueTime;
   270     }
   272     // Ready to start a new event.
   273     // If we don't already have a pending event, go grab one.
   274     if (! mPendingEvent) {
   275         if (mInboundQueue.isEmpty()) {
   276             if (isAppSwitchDue) {
   277                 // The inbound queue is empty so the app switch key we were waiting
   278                 // for will never arrive.  Stop waiting for it.
   279                 resetPendingAppSwitchLocked(false);
   280                 isAppSwitchDue = false;
   281             }
   283             // Synthesize a key repeat if appropriate.
   284             if (mKeyRepeatState.lastKeyEntry) {
   285                 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
   286                     mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
   287                 } else {
   288                     if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
   289                         *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
   290                     }
   291                 }
   292             }
   294             // Nothing to do if there is no pending event.
   295             if (!mPendingEvent) {
   296                 return;
   297             }
   298         } else {
   299             // Inbound queue has at least one entry.
   300             mPendingEvent = mInboundQueue.dequeueAtHead();
   301             traceInboundQueueLengthLocked();
   302         }
   304         // Poke user activity for this event.
   305         if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
   306             pokeUserActivityLocked(mPendingEvent);
   307         }
   309         // Get ready to dispatch the event.
   310         resetANRTimeoutsLocked();
   311     }
   313     // Now we have an event to dispatch.
   314     // All events are eventually dequeued and processed this way, even if we intend to drop them.
   315     ALOG_ASSERT(mPendingEvent != NULL);
   316     bool done = false;
   317     DropReason dropReason = DROP_REASON_NOT_DROPPED;
   318     if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
   319         dropReason = DROP_REASON_POLICY;
   320     } else if (!mDispatchEnabled) {
   321         dropReason = DROP_REASON_DISABLED;
   322     }
   324     if (mNextUnblockedEvent == mPendingEvent) {
   325         mNextUnblockedEvent = NULL;
   326     }
   328     switch (mPendingEvent->type) {
   329     case EventEntry::TYPE_CONFIGURATION_CHANGED: {
   330         ConfigurationChangedEntry* typedEntry =
   331                 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
   332         done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
   333         dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
   334         break;
   335     }
   337     case EventEntry::TYPE_DEVICE_RESET: {
   338         DeviceResetEntry* typedEntry =
   339                 static_cast<DeviceResetEntry*>(mPendingEvent);
   340         done = dispatchDeviceResetLocked(currentTime, typedEntry);
   341         dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
   342         break;
   343     }
   345     case EventEntry::TYPE_KEY: {
   346         KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
   347         if (isAppSwitchDue) {
   348             if (isAppSwitchKeyEventLocked(typedEntry)) {
   349                 resetPendingAppSwitchLocked(true);
   350                 isAppSwitchDue = false;
   351             } else if (dropReason == DROP_REASON_NOT_DROPPED) {
   352                 dropReason = DROP_REASON_APP_SWITCH;
   353             }
   354         }
   355         if (dropReason == DROP_REASON_NOT_DROPPED
   356                 && isStaleEventLocked(currentTime, typedEntry)) {
   357             dropReason = DROP_REASON_STALE;
   358         }
   359         if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
   360             dropReason = DROP_REASON_BLOCKED;
   361         }
   362         done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
   363         break;
   364     }
   366     case EventEntry::TYPE_MOTION: {
   367         MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
   368         if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
   369             dropReason = DROP_REASON_APP_SWITCH;
   370         }
   371         if (dropReason == DROP_REASON_NOT_DROPPED
   372                 && isStaleEventLocked(currentTime, typedEntry)) {
   373             dropReason = DROP_REASON_STALE;
   374         }
   375         if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
   376             dropReason = DROP_REASON_BLOCKED;
   377         }
   378         done = dispatchMotionLocked(currentTime, typedEntry,
   379                 &dropReason, nextWakeupTime);
   380         break;
   381     }
   383     default:
   384         ALOG_ASSERT(false);
   385         break;
   386     }
   388     if (done) {
   389         if (dropReason != DROP_REASON_NOT_DROPPED) {
   390             dropInboundEventLocked(mPendingEvent, dropReason);
   391         }
   393         releasePendingEventLocked();
   394         *nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately
   395     }
   396 }
   398 bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
   399     bool needWake = mInboundQueue.isEmpty();
   400     mInboundQueue.enqueueAtTail(entry);
   401     traceInboundQueueLengthLocked();
   403     switch (entry->type) {
   404     case EventEntry::TYPE_KEY: {
   405         // Optimize app switch latency.
   406         // If the application takes too long to catch up then we drop all events preceding
   407         // the app switch key.
   408         KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
   409         if (isAppSwitchKeyEventLocked(keyEntry)) {
   410             if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
   411                 mAppSwitchSawKeyDown = true;
   412             } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
   413                 if (mAppSwitchSawKeyDown) {
   414 #if DEBUG_APP_SWITCH
   415                     ALOGD("App switch is pending!");
   416 #endif
   417                     mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
   418                     mAppSwitchSawKeyDown = false;
   419                     needWake = true;
   420                 }
   421             }
   422         }
   423         break;
   424     }
   426     case EventEntry::TYPE_MOTION: {
   427         // Optimize case where the current application is unresponsive and the user
   428         // decides to touch a window in a different application.
   429         // If the application takes too long to catch up then we drop all events preceding
   430         // the touch into the other window.
   431         MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
   432         if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
   433                 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
   434                 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
   435                 && mInputTargetWaitApplicationHandle != NULL) {
   436             int32_t displayId = motionEntry->displayId;
   437             int32_t x = int32_t(motionEntry->pointerCoords[0].
   438                     getAxisValue(AMOTION_EVENT_AXIS_X));
   439             int32_t y = int32_t(motionEntry->pointerCoords[0].
   440                     getAxisValue(AMOTION_EVENT_AXIS_Y));
   441             sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
   442             if (touchedWindowHandle != NULL
   443                     && touchedWindowHandle->inputApplicationHandle
   444                             != mInputTargetWaitApplicationHandle) {
   445                 // User touched a different application than the one we are waiting on.
   446                 // Flag the event, and start pruning the input queue.
   447                 mNextUnblockedEvent = motionEntry;
   448                 needWake = true;
   449             }
   450         }
   451         break;
   452     }
   453     }
   455     return needWake;
   456 }
   458 sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
   459         int32_t x, int32_t y) {
   460     // Traverse windows from front to back to find touched window.
   461     size_t numWindows = mWindowHandles.size();
   462     for (size_t i = 0; i < numWindows; i++) {
   463         sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
   464         const InputWindowInfo* windowInfo = windowHandle->getInfo();
   465         if (windowInfo->displayId == displayId) {
   466             int32_t flags = windowInfo->layoutParamsFlags;
   468             if (windowInfo->visible) {
   469                 if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
   470                     bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
   471                             | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
   472                     if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
   473                         // Found window.
   474                         return windowHandle;
   475                     }
   476                 }
   477             }
   479             if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
   480                 // Error window is on top but not visible, so touch is dropped.
   481                 return NULL;
   482             }
   483         }
   484     }
   485     return NULL;
   486 }
   488 void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
   489     const char* reason;
   490     switch (dropReason) {
   491     case DROP_REASON_POLICY:
   492 #if DEBUG_INBOUND_EVENT_DETAILS
   493         ALOGD("Dropped event because policy consumed it.");
   494 #endif
   495         reason = "inbound event was dropped because the policy consumed it";
   496         break;
   497     case DROP_REASON_DISABLED:
   498         ALOGI("Dropped event because input dispatch is disabled.");
   499         reason = "inbound event was dropped because input dispatch is disabled";
   500         break;
   501     case DROP_REASON_APP_SWITCH:
   502         ALOGI("Dropped event because of pending overdue app switch.");
   503         reason = "inbound event was dropped because of pending overdue app switch";
   504         break;
   505     case DROP_REASON_BLOCKED:
   506         ALOGI("Dropped event because the current application is not responding and the user "
   507                 "has started interacting with a different application.");
   508         reason = "inbound event was dropped because the current application is not responding "
   509                 "and the user has started interacting with a different application";
   510         break;
   511     case DROP_REASON_STALE:
   512         ALOGI("Dropped event because it is stale.");
   513         reason = "inbound event was dropped because it is stale";
   514         break;
   515     default:
   516         ALOG_ASSERT(false);
   517         return;
   518     }
   520     switch (entry->type) {
   521     case EventEntry::TYPE_KEY: {
   522         CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
   523         synthesizeCancelationEventsForAllConnectionsLocked(options);
   524         break;
   525     }
   526     case EventEntry::TYPE_MOTION: {
   527         MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
   528         if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
   529             CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
   530             synthesizeCancelationEventsForAllConnectionsLocked(options);
   531         } else {
   532             CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
   533             synthesizeCancelationEventsForAllConnectionsLocked(options);
   534         }
   535         break;
   536     }
   537     }
   538 }
   540 bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
   541     return keyCode == AKEYCODE_HOME
   542             || keyCode == AKEYCODE_ENDCALL
   543             || keyCode == AKEYCODE_APP_SWITCH;
   544 }
   546 bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
   547     return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
   548             && isAppSwitchKeyCode(keyEntry->keyCode)
   549             && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
   550             && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
   551 }
   553 bool InputDispatcher::isAppSwitchPendingLocked() {
   554     return mAppSwitchDueTime != LONG_LONG_MAX;
   555 }
   557 void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
   558     mAppSwitchDueTime = LONG_LONG_MAX;
   560 #if DEBUG_APP_SWITCH
   561     if (handled) {
   562         ALOGD("App switch has arrived.");
   563     } else {
   564         ALOGD("App switch was abandoned.");
   565     }
   566 #endif
   567 }
   569 bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
   570     return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
   571 }
   573 bool InputDispatcher::haveCommandsLocked() const {
   574     return !mCommandQueue.isEmpty();
   575 }
   577 bool InputDispatcher::runCommandsLockedInterruptible() {
   578     if (mCommandQueue.isEmpty()) {
   579         return false;
   580     }
   582     do {
   583         CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
   585         Command command = commandEntry->command;
   586         (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
   588         commandEntry->connection.clear();
   589         delete commandEntry;
   590     } while (! mCommandQueue.isEmpty());
   591     return true;
   592 }
   594 InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
   595     CommandEntry* commandEntry = new CommandEntry(command);
   596     mCommandQueue.enqueueAtTail(commandEntry);
   597     return commandEntry;
   598 }
   600 void InputDispatcher::drainInboundQueueLocked() {
   601     while (! mInboundQueue.isEmpty()) {
   602         EventEntry* entry = mInboundQueue.dequeueAtHead();
   603         releaseInboundEventLocked(entry);
   604     }
   605     traceInboundQueueLengthLocked();
   606 }
   608 void InputDispatcher::releasePendingEventLocked() {
   609     if (mPendingEvent) {
   610         resetANRTimeoutsLocked();
   611         releaseInboundEventLocked(mPendingEvent);
   612         mPendingEvent = NULL;
   613     }
   614 }
   616 void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
   617     InjectionState* injectionState = entry->injectionState;
   618     if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
   619 #if DEBUG_DISPATCH_CYCLE
   620         ALOGD("Injected inbound event was dropped.");
   621 #endif
   622         setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
   623     }
   624     if (entry == mNextUnblockedEvent) {
   625         mNextUnblockedEvent = NULL;
   626     }
   627     entry->release();
   628 }
   630 void InputDispatcher::resetKeyRepeatLocked() {
   631     if (mKeyRepeatState.lastKeyEntry) {
   632         mKeyRepeatState.lastKeyEntry->release();
   633         mKeyRepeatState.lastKeyEntry = NULL;
   634     }
   635 }
   637 InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
   638     KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
   640     // Reuse the repeated key entry if it is otherwise unreferenced.
   641     uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
   642             | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
   643     if (entry->refCount == 1) {
   644         entry->recycle();
   645         entry->eventTime = currentTime;
   646         entry->policyFlags = policyFlags;
   647         entry->repeatCount += 1;
   648     } else {
   649         KeyEntry* newEntry = new KeyEntry(currentTime,
   650                 entry->deviceId, entry->source, policyFlags,
   651                 entry->action, entry->flags, entry->keyCode, entry->scanCode,
   652                 entry->metaState, entry->repeatCount + 1, entry->downTime);
   654         mKeyRepeatState.lastKeyEntry = newEntry;
   655         entry->release();
   657         entry = newEntry;
   658     }
   659     entry->syntheticRepeat = true;
   661     // Increment reference count since we keep a reference to the event in
   662     // mKeyRepeatState.lastKeyEntry in addition to the one we return.
   663     entry->refCount += 1;
   665     mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
   666     return entry;
   667 }
   669 bool InputDispatcher::dispatchConfigurationChangedLocked(
   670         nsecs_t currentTime, ConfigurationChangedEntry* entry) {
   671 #if DEBUG_OUTBOUND_EVENT_DETAILS
   672     ALOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
   673 #endif
   675     // Reset key repeating in case a keyboard device was added or removed or something.
   676     resetKeyRepeatLocked();
   678     // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
   679     CommandEntry* commandEntry = postCommandLocked(
   680             & InputDispatcher::doNotifyConfigurationChangedInterruptible);
   681     commandEntry->eventTime = entry->eventTime;
   682     return true;
   683 }
   685 bool InputDispatcher::dispatchDeviceResetLocked(
   686         nsecs_t currentTime, DeviceResetEntry* entry) {
   687 #if DEBUG_OUTBOUND_EVENT_DETAILS
   688     ALOGD("dispatchDeviceReset - eventTime=%lld, deviceId=%d", entry->eventTime, entry->deviceId);
   689 #endif
   691     CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
   692             "device was reset");
   693     options.deviceId = entry->deviceId;
   694     synthesizeCancelationEventsForAllConnectionsLocked(options);
   695     return true;
   696 }
   698 bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
   699         DropReason* dropReason, nsecs_t* nextWakeupTime) {
   700     // Preprocessing.
   701     if (! entry->dispatchInProgress) {
   702         if (entry->repeatCount == 0
   703                 && entry->action == AKEY_EVENT_ACTION_DOWN
   704                 && (entry->policyFlags & POLICY_FLAG_TRUSTED)
   705                 && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
   706             if (mKeyRepeatState.lastKeyEntry
   707                     && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
   708                 // We have seen two identical key downs in a row which indicates that the device
   709                 // driver is automatically generating key repeats itself.  We take note of the
   710                 // repeat here, but we disable our own next key repeat timer since it is clear that
   711                 // we will not need to synthesize key repeats ourselves.
   712                 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
   713                 resetKeyRepeatLocked();
   714                 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
   715             } else {
   716                 // Not a repeat.  Save key down state in case we do see a repeat later.
   717                 resetKeyRepeatLocked();
   718                 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
   719             }
   720             mKeyRepeatState.lastKeyEntry = entry;
   721             entry->refCount += 1;
   722         } else if (! entry->syntheticRepeat) {
   723             resetKeyRepeatLocked();
   724         }
   726         if (entry->repeatCount == 1) {
   727             entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
   728         } else {
   729             entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
   730         }
   732         entry->dispatchInProgress = true;
   734         logOutboundKeyDetailsLocked("dispatchKey - ", entry);
   735     }
   737     // Handle case where the policy asked us to try again later last time.
   738     if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
   739         if (currentTime < entry->interceptKeyWakeupTime) {
   740             if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
   741                 *nextWakeupTime = entry->interceptKeyWakeupTime;
   742             }
   743             return false; // wait until next wakeup
   744         }
   745         entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
   746         entry->interceptKeyWakeupTime = 0;
   747     }
   749     // Give the policy a chance to intercept the key.
   750     if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
   751         if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
   752             CommandEntry* commandEntry = postCommandLocked(
   753                     & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
   754             if (mFocusedWindowHandle != NULL) {
   755                 commandEntry->inputWindowHandle = mFocusedWindowHandle;
   756             }
   757             commandEntry->keyEntry = entry;
   758             entry->refCount += 1;
   759             return false; // wait for the command to run
   760         } else {
   761             entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
   762         }
   763     } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
   764         if (*dropReason == DROP_REASON_NOT_DROPPED) {
   765             *dropReason = DROP_REASON_POLICY;
   766         }
   767     }
   769     // Clean up if dropping the event.
   770     if (*dropReason != DROP_REASON_NOT_DROPPED) {
   771         setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
   772                 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
   773         return true;
   774     }
   776     // Identify targets.
   777     Vector<InputTarget> inputTargets;
   778     int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
   779             entry, inputTargets, nextWakeupTime);
   780     if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
   781         return false;
   782     }
   784     setInjectionResultLocked(entry, injectionResult);
   785     if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
   786         return true;
   787     }
   789     addMonitoringTargetsLocked(inputTargets);
   791     // Dispatch the key.
   792     dispatchEventLocked(currentTime, entry, inputTargets);
   793     return true;
   794 }
   796 void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
   797 #if DEBUG_OUTBOUND_EVENT_DETAILS
   798     ALOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
   799             "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
   800             "repeatCount=%d, downTime=%lld",
   801             prefix,
   802             entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
   803             entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
   804             entry->repeatCount, entry->downTime);
   805 #endif
   806 }
   808 bool InputDispatcher::dispatchMotionLocked(
   809         nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
   810     // Preprocessing.
   811     if (! entry->dispatchInProgress) {
   812         entry->dispatchInProgress = true;
   814         logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
   815     }
   817     // Clean up if dropping the event.
   818     if (*dropReason != DROP_REASON_NOT_DROPPED) {
   819         setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
   820                 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
   821         return true;
   822     }
   824     bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
   826     // Identify targets.
   827     Vector<InputTarget> inputTargets;
   829     bool conflictingPointerActions = false;
   830     int32_t injectionResult;
   831     if (isPointerEvent) {
   832         // Pointer event.  (eg. touchscreen)
   833         injectionResult = findTouchedWindowTargetsLocked(currentTime,
   834                 entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
   835     } else {
   836         // Non touch event.  (eg. trackball)
   837         injectionResult = findFocusedWindowTargetsLocked(currentTime,
   838                 entry, inputTargets, nextWakeupTime);
   839     }
   840     if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
   841         return false;
   842     }
   844     setInjectionResultLocked(entry, injectionResult);
   845     if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
   846         return true;
   847     }
   849     // TODO: support sending secondary display events to input monitors
   850     if (isMainDisplay(entry->displayId)) {
   851         addMonitoringTargetsLocked(inputTargets);
   852     }
   854     // Dispatch the motion.
   855     if (conflictingPointerActions) {
   856         CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
   857                 "conflicting pointer actions");
   858         synthesizeCancelationEventsForAllConnectionsLocked(options);
   859     }
   860     dispatchEventLocked(currentTime, entry, inputTargets);
   861     return true;
   862 }
   865 void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
   866 #if DEBUG_OUTBOUND_EVENT_DETAILS
   867     ALOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
   868             "action=0x%x, flags=0x%x, "
   869             "metaState=0x%x, buttonState=0x%x, "
   870             "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
   871             prefix,
   872             entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
   873             entry->action, entry->flags,
   874             entry->metaState, entry->buttonState,
   875             entry->edgeFlags, entry->xPrecision, entry->yPrecision,
   876             entry->downTime);
   878     for (uint32_t i = 0; i < entry->pointerCount; i++) {
   879         ALOGD("  Pointer %d: id=%d, toolType=%d, "
   880                 "x=%f, y=%f, pressure=%f, size=%f, "
   881                 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
   882                 "orientation=%f",
   883                 i, entry->pointerProperties[i].id,
   884                 entry->pointerProperties[i].toolType,
   885                 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
   886                 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
   887                 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
   888                 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
   889                 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
   890                 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
   891                 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
   892                 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
   893                 entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
   894     }
   895 #endif
   896 }
   898 void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
   899         EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
   900 #if DEBUG_DISPATCH_CYCLE
   901     ALOGD("dispatchEventToCurrentInputTargets");
   902 #endif
   904     ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
   906     pokeUserActivityLocked(eventEntry);
   908     for (size_t i = 0; i < inputTargets.size(); i++) {
   909         const InputTarget& inputTarget = inputTargets.itemAt(i);
   911         ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
   912         if (connectionIndex >= 0) {
   913             sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
   914             prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
   915         } else {
   916 #if DEBUG_FOCUS
   917             ALOGD("Dropping event delivery to target with channel '%s' because it "
   918                     "is no longer registered with the input dispatcher.",
   919                     inputTarget.inputChannel->getName().string());
   920 #endif
   921         }
   922     }
   923 }
   925 int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
   926         const EventEntry* entry,
   927         const sp<InputApplicationHandle>& applicationHandle,
   928         const sp<InputWindowHandle>& windowHandle,
   929         nsecs_t* nextWakeupTime, const char* reason) {
   930     if (applicationHandle == NULL && windowHandle == NULL) {
   931         if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
   932 #if DEBUG_FOCUS
   933             ALOGD("Waiting for system to become ready for input.  Reason: %s", reason);
   934 #endif
   935             mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
   936             mInputTargetWaitStartTime = currentTime;
   937             mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
   938             mInputTargetWaitTimeoutExpired = false;
   939             mInputTargetWaitApplicationHandle.clear();
   940         }
   941     } else {
   942         if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
   943 #if DEBUG_FOCUS
   944             ALOGD("Waiting for application to become ready for input: %s.  Reason: %s",
   945                     getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
   946                     reason);
   947 #endif
   948             nsecs_t timeout;
   949             if (windowHandle != NULL) {
   950                 timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
   951             } else if (applicationHandle != NULL) {
   952                 timeout = applicationHandle->getDispatchingTimeout(
   953                         DEFAULT_INPUT_DISPATCHING_TIMEOUT);
   954             } else {
   955                 timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
   956             }
   958             mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
   959             mInputTargetWaitStartTime = currentTime;
   960             mInputTargetWaitTimeoutTime = currentTime + timeout;
   961             mInputTargetWaitTimeoutExpired = false;
   962             mInputTargetWaitApplicationHandle.clear();
   964             if (windowHandle != NULL) {
   965                 mInputTargetWaitApplicationHandle = windowHandle->inputApplicationHandle;
   966             }
   967             if (mInputTargetWaitApplicationHandle == NULL && applicationHandle != NULL) {
   968                 mInputTargetWaitApplicationHandle = applicationHandle;
   969             }
   970         }
   971     }
   973     if (mInputTargetWaitTimeoutExpired) {
   974         return INPUT_EVENT_INJECTION_TIMED_OUT;
   975     }
   977     if (currentTime >= mInputTargetWaitTimeoutTime) {
   978         onANRLocked(currentTime, applicationHandle, windowHandle,
   979                 entry->eventTime, mInputTargetWaitStartTime, reason);
   981         // Force poll loop to wake up immediately on next iteration once we get the
   982         // ANR response back from the policy.
   983         *nextWakeupTime = LONG_LONG_MIN;
   984         return INPUT_EVENT_INJECTION_PENDING;
   985     } else {
   986         // Force poll loop to wake up when timeout is due.
   987         if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
   988             *nextWakeupTime = mInputTargetWaitTimeoutTime;
   989         }
   990         return INPUT_EVENT_INJECTION_PENDING;
   991     }
   992 }
   994 void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
   995         const sp<InputChannel>& inputChannel) {
   996     if (newTimeout > 0) {
   997         // Extend the timeout.
   998         mInputTargetWaitTimeoutTime = now() + newTimeout;
   999     } else {
  1000         // Give up.
  1001         mInputTargetWaitTimeoutExpired = true;
  1003         // Input state will not be realistic.  Mark it out of sync.
  1004         if (inputChannel.get()) {
  1005             ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
  1006             if (connectionIndex >= 0) {
  1007                 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
  1008                 sp<InputWindowHandle> windowHandle = connection->inputWindowHandle;
  1010                 if (windowHandle != NULL) {
  1011                     mTouchState.removeWindow(windowHandle);
  1014                 if (connection->status == Connection::STATUS_NORMAL) {
  1015                     CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
  1016                             "application not responding");
  1017                     synthesizeCancelationEventsForConnectionLocked(connection, options);
  1024 nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
  1025         nsecs_t currentTime) {
  1026     if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
  1027         return currentTime - mInputTargetWaitStartTime;
  1029     return 0;
  1032 void InputDispatcher::resetANRTimeoutsLocked() {
  1033 #if DEBUG_FOCUS
  1034         ALOGD("Resetting ANR timeouts.");
  1035 #endif
  1037     // Reset input target wait timeout.
  1038     mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
  1039     mInputTargetWaitApplicationHandle.clear();
  1042 int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
  1043         const EventEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
  1044     int32_t injectionResult;
  1046     // If there is no currently focused window and no focused application
  1047     // then drop the event.
  1048     if (mFocusedWindowHandle == NULL) {
  1049         if (mFocusedApplicationHandle != NULL) {
  1050             injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
  1051                     mFocusedApplicationHandle, NULL, nextWakeupTime,
  1052                     "Waiting because no window has focus but there is a "
  1053                     "focused application that may eventually add a window "
  1054                     "when it finishes starting up.");
  1055             goto Unresponsive;
  1058         ALOGI("Dropping event because there is no focused window or focused application.");
  1059         injectionResult = INPUT_EVENT_INJECTION_FAILED;
  1060         goto Failed;
  1063     // Check permissions.
  1064     if (! checkInjectionPermission(mFocusedWindowHandle, entry->injectionState)) {
  1065         injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
  1066         goto Failed;
  1069     // If the currently focused window is paused then keep waiting.
  1070     if (mFocusedWindowHandle->getInfo()->paused) {
  1071         injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
  1072                 mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime,
  1073                 "Waiting because the focused window is paused.");
  1074         goto Unresponsive;
  1077     // If the currently focused window is still working on previous events then keep waiting.
  1078     if (!isWindowReadyForMoreInputLocked(currentTime, mFocusedWindowHandle, entry)) {
  1079         injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
  1080                 mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime,
  1081                 "Waiting because the focused window has not finished "
  1082                 "processing the input events that were previously delivered to it.");
  1083         goto Unresponsive;
  1086     // Success!  Output targets.
  1087     injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
  1088     addWindowTargetLocked(mFocusedWindowHandle,
  1089             InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
  1090             inputTargets);
  1092     // Done.
  1093 Failed:
  1094 Unresponsive:
  1095     nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
  1096     updateDispatchStatisticsLocked(currentTime, entry,
  1097             injectionResult, timeSpentWaitingForApplication);
  1098 #if DEBUG_FOCUS
  1099     ALOGD("findFocusedWindow finished: injectionResult=%d, "
  1100             "timeSpentWaitingForApplication=%0.1fms",
  1101             injectionResult, timeSpentWaitingForApplication / 1000000.0);
  1102 #endif
  1103     return injectionResult;
  1106 int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
  1107         const MotionEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
  1108         bool* outConflictingPointerActions) {
  1109     enum InjectionPermission {
  1110         INJECTION_PERMISSION_UNKNOWN,
  1111         INJECTION_PERMISSION_GRANTED,
  1112         INJECTION_PERMISSION_DENIED
  1113     };
  1115     nsecs_t startTime = now();
  1117     // For security reasons, we defer updating the touch state until we are sure that
  1118     // event injection will be allowed.
  1119     //
  1120     // FIXME In the original code, screenWasOff could never be set to true.
  1121     //       The reason is that the POLICY_FLAG_WOKE_HERE
  1122     //       and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
  1123     //       EV_KEY, EV_REL and EV_ABS events.  As it happens, the touch event was
  1124     //       actually enqueued using the policyFlags that appeared in the final EV_SYN
  1125     //       events upon which no preprocessing took place.  So policyFlags was always 0.
  1126     //       In the new native input dispatcher we're a bit more careful about event
  1127     //       preprocessing so the touches we receive can actually have non-zero policyFlags.
  1128     //       Unfortunately we obtain undesirable behavior.
  1129     //
  1130     //       Here's what happens:
  1131     //
  1132     //       When the device dims in anticipation of going to sleep, touches
  1133     //       in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
  1134     //       the device to brighten and reset the user activity timer.
  1135     //       Touches on other windows (such as the launcher window)
  1136     //       are dropped.  Then after a moment, the device goes to sleep.  Oops.
  1137     //
  1138     //       Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
  1139     //       instead of POLICY_FLAG_WOKE_HERE...
  1140     //
  1141     bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
  1143     int32_t displayId = entry->displayId;
  1144     int32_t action = entry->action;
  1145     int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
  1147     // Update the touch state as needed based on the properties of the touch event.
  1148     int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
  1149     InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
  1150     sp<InputWindowHandle> newHoverWindowHandle;
  1152     bool isSplit = mTouchState.split;
  1153     bool switchedDevice = mTouchState.deviceId >= 0 && mTouchState.displayId >= 0
  1154             && (mTouchState.deviceId != entry->deviceId
  1155                     || mTouchState.source != entry->source
  1156                     || mTouchState.displayId != displayId);
  1157     bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
  1158             || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
  1159             || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
  1160     bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
  1161             || maskedAction == AMOTION_EVENT_ACTION_SCROLL
  1162             || isHoverAction);
  1163     bool wrongDevice = false;
  1164     if (newGesture) {
  1165         bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
  1166         if (switchedDevice && mTouchState.down && !down) {
  1167 #if DEBUG_FOCUS
  1168             ALOGD("Dropping event because a pointer for a different device is already down.");
  1169 #endif
  1170             mTempTouchState.copyFrom(mTouchState);
  1171             injectionResult = INPUT_EVENT_INJECTION_FAILED;
  1172             switchedDevice = false;
  1173             wrongDevice = true;
  1174             goto Failed;
  1176         mTempTouchState.reset();
  1177         mTempTouchState.down = down;
  1178         mTempTouchState.deviceId = entry->deviceId;
  1179         mTempTouchState.source = entry->source;
  1180         mTempTouchState.displayId = displayId;
  1181         isSplit = false;
  1182     } else {
  1183         mTempTouchState.copyFrom(mTouchState);
  1186     if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
  1187         /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
  1189         int32_t pointerIndex = getMotionEventActionPointerIndex(action);
  1190         int32_t x = int32_t(entry->pointerCoords[pointerIndex].
  1191                 getAxisValue(AMOTION_EVENT_AXIS_X));
  1192         int32_t y = int32_t(entry->pointerCoords[pointerIndex].
  1193                 getAxisValue(AMOTION_EVENT_AXIS_Y));
  1194         sp<InputWindowHandle> newTouchedWindowHandle;
  1195         sp<InputWindowHandle> topErrorWindowHandle;
  1196         bool isTouchModal = false;
  1198         // Traverse windows from front to back to find touched window and outside targets.
  1199         size_t numWindows = mWindowHandles.size();
  1200         for (size_t i = 0; i < numWindows; i++) {
  1201             sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
  1202             const InputWindowInfo* windowInfo = windowHandle->getInfo();
  1203             if (windowInfo->displayId != displayId) {
  1204                 continue; // wrong display
  1207             int32_t flags = windowInfo->layoutParamsFlags;
  1208             if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
  1209                 if (topErrorWindowHandle == NULL) {
  1210                     topErrorWindowHandle = windowHandle;
  1214             if (windowInfo->visible) {
  1215                 if (! (flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
  1216                     isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
  1217                             | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
  1218                     if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
  1219                         if (! screenWasOff
  1220                                 || (flags & InputWindowInfo::FLAG_TOUCHABLE_WHEN_WAKING)) {
  1221                             newTouchedWindowHandle = windowHandle;
  1223                         break; // found touched window, exit window loop
  1227                 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
  1228                         && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
  1229                     int32_t outsideTargetFlags = InputTarget::FLAG_DISPATCH_AS_OUTSIDE;
  1230                     if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
  1231                         outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
  1234                     mTempTouchState.addOrUpdateWindow(
  1235                             windowHandle, outsideTargetFlags, BitSet32(0));
  1240         // If there is an error window but it is not taking focus (typically because
  1241         // it is invisible) then wait for it.  Any other focused window may in
  1242         // fact be in ANR state.
  1243         if (topErrorWindowHandle != NULL && newTouchedWindowHandle != topErrorWindowHandle) {
  1244             injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
  1245                     NULL, NULL, nextWakeupTime,
  1246                     "Waiting because a system error window is about to be displayed.");
  1247             injectionPermission = INJECTION_PERMISSION_UNKNOWN;
  1248             goto Unresponsive;
  1251         // Figure out whether splitting will be allowed for this window.
  1252         if (newTouchedWindowHandle != NULL
  1253                 && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
  1254             // New window supports splitting.
  1255             isSplit = true;
  1256         } else if (isSplit) {
  1257             // New window does not support splitting but we have already split events.
  1258             // Ignore the new window.
  1259             newTouchedWindowHandle = NULL;
  1262         // Handle the case where we did not find a window.
  1263         if (newTouchedWindowHandle == NULL) {
  1264             // Try to assign the pointer to the first foreground window we find, if there is one.
  1265             newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
  1266             if (newTouchedWindowHandle == NULL) {
  1267                 // There is no touched window.  If this is an initial down event
  1268                 // then wait for a window to appear that will handle the touch.  This is
  1269                 // to ensure that we report an ANR in the case where an application has started
  1270                 // but not yet put up a window and the user is starting to get impatient.
  1271                 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
  1272                         && mFocusedApplicationHandle != NULL) {
  1273                     injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
  1274                             mFocusedApplicationHandle, NULL, nextWakeupTime,
  1275                             "Waiting because there is no touchable window that can "
  1276                             "handle the event but there is focused application that may "
  1277                             "eventually add a new window when it finishes starting up.");
  1278                     goto Unresponsive;
  1281                 ALOGI("Dropping event because there is no touched window.");
  1282                 injectionResult = INPUT_EVENT_INJECTION_FAILED;
  1283                 goto Failed;
  1287         // Set target flags.
  1288         int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
  1289         if (isSplit) {
  1290             targetFlags |= InputTarget::FLAG_SPLIT;
  1292         if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
  1293             targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
  1296         // Update hover state.
  1297         if (isHoverAction) {
  1298             newHoverWindowHandle = newTouchedWindowHandle;
  1299         } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
  1300             newHoverWindowHandle = mLastHoverWindowHandle;
  1303         // Update the temporary touch state.
  1304         BitSet32 pointerIds;
  1305         if (isSplit) {
  1306             uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
  1307             pointerIds.markBit(pointerId);
  1309         mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
  1310     } else {
  1311         /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
  1313         // If the pointer is not currently down, then ignore the event.
  1314         if (! mTempTouchState.down) {
  1315 #if DEBUG_FOCUS
  1316             ALOGD("Dropping event because the pointer is not down or we previously "
  1317                     "dropped the pointer down event.");
  1318 #endif
  1319             injectionResult = INPUT_EVENT_INJECTION_FAILED;
  1320             goto Failed;
  1323         // Check whether touches should slip outside of the current foreground window.
  1324         if (maskedAction == AMOTION_EVENT_ACTION_MOVE
  1325                 && entry->pointerCount == 1
  1326                 && mTempTouchState.isSlippery()) {
  1327             int32_t x = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
  1328             int32_t y = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
  1330             sp<InputWindowHandle> oldTouchedWindowHandle =
  1331                     mTempTouchState.getFirstForegroundWindowHandle();
  1332             sp<InputWindowHandle> newTouchedWindowHandle =
  1333                     findTouchedWindowAtLocked(displayId, x, y);
  1334             if (oldTouchedWindowHandle != newTouchedWindowHandle
  1335                     && newTouchedWindowHandle != NULL) {
  1336 #if DEBUG_FOCUS
  1337                 ALOGD("Touch is slipping out of window %s into window %s.",
  1338                         oldTouchedWindowHandle->getName().string(),
  1339                         newTouchedWindowHandle->getName().string());
  1340 #endif
  1341                 // Make a slippery exit from the old window.
  1342                 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
  1343                         InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
  1345                 // Make a slippery entrance into the new window.
  1346                 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
  1347                     isSplit = true;
  1350                 int32_t targetFlags = InputTarget::FLAG_FOREGROUND
  1351                         | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
  1352                 if (isSplit) {
  1353                     targetFlags |= InputTarget::FLAG_SPLIT;
  1355                 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
  1356                     targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
  1359                 BitSet32 pointerIds;
  1360                 if (isSplit) {
  1361                     pointerIds.markBit(entry->pointerProperties[0].id);
  1363                 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
  1368     if (newHoverWindowHandle != mLastHoverWindowHandle) {
  1369         // Let the previous window know that the hover sequence is over.
  1370         if (mLastHoverWindowHandle != NULL) {
  1371 #if DEBUG_HOVER
  1372             ALOGD("Sending hover exit event to window %s.",
  1373                     mLastHoverWindowHandle->getName().string());
  1374 #endif
  1375             mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
  1376                     InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
  1379         // Let the new window know that the hover sequence is starting.
  1380         if (newHoverWindowHandle != NULL) {
  1381 #if DEBUG_HOVER
  1382             ALOGD("Sending hover enter event to window %s.",
  1383                     newHoverWindowHandle->getName().string());
  1384 #endif
  1385             mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
  1386                     InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
  1390     // Check permission to inject into all touched foreground windows and ensure there
  1391     // is at least one touched foreground window.
  1393         bool haveForegroundWindow = false;
  1394         for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
  1395             const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
  1396             if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
  1397                 haveForegroundWindow = true;
  1398                 if (! checkInjectionPermission(touchedWindow.windowHandle,
  1399                         entry->injectionState)) {
  1400                     injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
  1401                     injectionPermission = INJECTION_PERMISSION_DENIED;
  1402                     goto Failed;
  1406         if (! haveForegroundWindow) {
  1407 #if DEBUG_FOCUS
  1408             ALOGD("Dropping event because there is no touched foreground window to receive it.");
  1409 #endif
  1410             injectionResult = INPUT_EVENT_INJECTION_FAILED;
  1411             goto Failed;
  1414         // Permission granted to injection into all touched foreground windows.
  1415         injectionPermission = INJECTION_PERMISSION_GRANTED;
  1418     // Check whether windows listening for outside touches are owned by the same UID. If it is
  1419     // set the policy flag that we will not reveal coordinate information to this window.
  1420     if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
  1421         sp<InputWindowHandle> foregroundWindowHandle =
  1422                 mTempTouchState.getFirstForegroundWindowHandle();
  1423         const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
  1424         for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
  1425             const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
  1426             if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
  1427                 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
  1428                 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
  1429                     mTempTouchState.addOrUpdateWindow(inputWindowHandle,
  1430                             InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
  1436     // Ensure all touched foreground windows are ready for new input.
  1437     for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
  1438         const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
  1439         if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
  1440             // If the touched window is paused then keep waiting.
  1441             if (touchedWindow.windowHandle->getInfo()->paused) {
  1442                 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
  1443                         NULL, touchedWindow.windowHandle, nextWakeupTime,
  1444                         "Waiting because the touched window is paused.");
  1445                 goto Unresponsive;
  1448             // If the touched window is still working on previous events then keep waiting.
  1449             if (!isWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle, entry)) {
  1450                 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
  1451                         NULL, touchedWindow.windowHandle, nextWakeupTime,
  1452                         "Waiting because the touched window has not finished "
  1453                         "processing the input events that were previously delivered to it.");
  1454                 goto Unresponsive;
  1459     // If this is the first pointer going down and the touched window has a wallpaper
  1460     // then also add the touched wallpaper windows so they are locked in for the duration
  1461     // of the touch gesture.
  1462     // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
  1463     // engine only supports touch events.  We would need to add a mechanism similar
  1464     // to View.onGenericMotionEvent to enable wallpapers to handle these events.
  1465     if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
  1466         sp<InputWindowHandle> foregroundWindowHandle =
  1467                 mTempTouchState.getFirstForegroundWindowHandle();
  1468         if (foregroundWindowHandle->getInfo()->hasWallpaper) {
  1469             for (size_t i = 0; i < mWindowHandles.size(); i++) {
  1470                 sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
  1471                 const InputWindowInfo* info = windowHandle->getInfo();
  1472                 if (info->displayId == displayId
  1473                         && windowHandle->getInfo()->layoutParamsType
  1474                                 == InputWindowInfo::TYPE_WALLPAPER) {
  1475                     mTempTouchState.addOrUpdateWindow(windowHandle,
  1476                             InputTarget::FLAG_WINDOW_IS_OBSCURED
  1477                                     | InputTarget::FLAG_DISPATCH_AS_IS,
  1478                             BitSet32(0));
  1484     // Success!  Output targets.
  1485     injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
  1487     for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
  1488         const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
  1489         addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
  1490                 touchedWindow.pointerIds, inputTargets);
  1493     // Drop the outside or hover touch windows since we will not care about them
  1494     // in the next iteration.
  1495     mTempTouchState.filterNonAsIsTouchWindows();
  1497 Failed:
  1498     // Check injection permission once and for all.
  1499     if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
  1500         if (checkInjectionPermission(NULL, entry->injectionState)) {
  1501             injectionPermission = INJECTION_PERMISSION_GRANTED;
  1502         } else {
  1503             injectionPermission = INJECTION_PERMISSION_DENIED;
  1507     // Update final pieces of touch state if the injector had permission.
  1508     if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
  1509         if (!wrongDevice) {
  1510             if (switchedDevice) {
  1511 #if DEBUG_FOCUS
  1512                 ALOGD("Conflicting pointer actions: Switched to a different device.");
  1513 #endif
  1514                 *outConflictingPointerActions = true;
  1517             if (isHoverAction) {
  1518                 // Started hovering, therefore no longer down.
  1519                 if (mTouchState.down) {
  1520 #if DEBUG_FOCUS
  1521                     ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
  1522 #endif
  1523                     *outConflictingPointerActions = true;
  1525                 mTouchState.reset();
  1526                 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
  1527                         || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
  1528                     mTouchState.deviceId = entry->deviceId;
  1529                     mTouchState.source = entry->source;
  1530                     mTouchState.displayId = displayId;
  1532             } else if (maskedAction == AMOTION_EVENT_ACTION_UP
  1533                     || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
  1534                 // All pointers up or canceled.
  1535                 mTouchState.reset();
  1536             } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
  1537                 // First pointer went down.
  1538                 if (mTouchState.down) {
  1539 #if DEBUG_FOCUS
  1540                     ALOGD("Conflicting pointer actions: Down received while already down.");
  1541 #endif
  1542                     *outConflictingPointerActions = true;
  1544                 mTouchState.copyFrom(mTempTouchState);
  1545             } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
  1546                 // One pointer went up.
  1547                 if (isSplit) {
  1548                     int32_t pointerIndex = getMotionEventActionPointerIndex(action);
  1549                     uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
  1551                     for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
  1552                         TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
  1553                         if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
  1554                             touchedWindow.pointerIds.clearBit(pointerId);
  1555                             if (touchedWindow.pointerIds.isEmpty()) {
  1556                                 mTempTouchState.windows.removeAt(i);
  1557                                 continue;
  1560                         i += 1;
  1563                 mTouchState.copyFrom(mTempTouchState);
  1564             } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
  1565                 // Discard temporary touch state since it was only valid for this action.
  1566             } else {
  1567                 // Save changes to touch state as-is for all other actions.
  1568                 mTouchState.copyFrom(mTempTouchState);
  1571             // Update hover state.
  1572             mLastHoverWindowHandle = newHoverWindowHandle;
  1574     } else {
  1575 #if DEBUG_FOCUS
  1576         ALOGD("Not updating touch focus because injection was denied.");
  1577 #endif
  1580 Unresponsive:
  1581     // Reset temporary touch state to ensure we release unnecessary references to input channels.
  1582     mTempTouchState.reset();
  1584     nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
  1585     updateDispatchStatisticsLocked(currentTime, entry,
  1586             injectionResult, timeSpentWaitingForApplication);
  1587 #if DEBUG_FOCUS
  1588     ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
  1589             "timeSpentWaitingForApplication=%0.1fms",
  1590             injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
  1591 #endif
  1592     return injectionResult;
  1595 void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
  1596         int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) {
  1597     inputTargets.push();
  1599     const InputWindowInfo* windowInfo = windowHandle->getInfo();
  1600     InputTarget& target = inputTargets.editTop();
  1601     target.inputChannel = windowInfo->inputChannel;
  1602     target.flags = targetFlags;
  1603     target.xOffset = - windowInfo->frameLeft;
  1604     target.yOffset = - windowInfo->frameTop;
  1605     target.scaleFactor = windowInfo->scaleFactor;
  1606     target.pointerIds = pointerIds;
  1609 void InputDispatcher::addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets) {
  1610     for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
  1611         inputTargets.push();
  1613         InputTarget& target = inputTargets.editTop();
  1614         target.inputChannel = mMonitoringChannels[i];
  1615         target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
  1616         target.xOffset = 0;
  1617         target.yOffset = 0;
  1618         target.pointerIds.clear();
  1619         target.scaleFactor = 1.0f;
  1623 bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
  1624         const InjectionState* injectionState) {
  1625     if (injectionState
  1626             && (windowHandle == NULL
  1627                     || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
  1628             && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
  1629         if (windowHandle != NULL) {
  1630             ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
  1631                     "owned by uid %d",
  1632                     injectionState->injectorPid, injectionState->injectorUid,
  1633                     windowHandle->getName().string(),
  1634                     windowHandle->getInfo()->ownerUid);
  1635         } else {
  1636             ALOGW("Permission denied: injecting event from pid %d uid %d",
  1637                     injectionState->injectorPid, injectionState->injectorUid);
  1639         return false;
  1641     return true;
  1644 bool InputDispatcher::isWindowObscuredAtPointLocked(
  1645         const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
  1646     int32_t displayId = windowHandle->getInfo()->displayId;
  1647     size_t numWindows = mWindowHandles.size();
  1648     for (size_t i = 0; i < numWindows; i++) {
  1649         sp<InputWindowHandle> otherHandle = mWindowHandles.itemAt(i);
  1650         if (otherHandle == windowHandle) {
  1651             break;
  1654         const InputWindowInfo* otherInfo = otherHandle->getInfo();
  1655         if (otherInfo->displayId == displayId
  1656                 && otherInfo->visible && !otherInfo->isTrustedOverlay()
  1657                 && otherInfo->frameContainsPoint(x, y)) {
  1658             return true;
  1661     return false;
  1664 bool InputDispatcher::isWindowReadyForMoreInputLocked(nsecs_t currentTime,
  1665         const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry) {
  1666     ssize_t connectionIndex = getConnectionIndexLocked(windowHandle->getInputChannel());
  1667     if (connectionIndex >= 0) {
  1668         sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
  1669         if (connection->inputPublisherBlocked) {
  1670             return false;
  1672         if (eventEntry->type == EventEntry::TYPE_KEY) {
  1673             // If the event is a key event, then we must wait for all previous events to
  1674             // complete before delivering it because previous events may have the
  1675             // side-effect of transferring focus to a different window and we want to
  1676             // ensure that the following keys are sent to the new window.
  1677             //
  1678             // Suppose the user touches a button in a window then immediately presses "A".
  1679             // If the button causes a pop-up window to appear then we want to ensure that
  1680             // the "A" key is delivered to the new pop-up window.  This is because users
  1681             // often anticipate pending UI changes when typing on a keyboard.
  1682             // To obtain this behavior, we must serialize key events with respect to all
  1683             // prior input events.
  1684             return connection->outboundQueue.isEmpty()
  1685                     && connection->waitQueue.isEmpty();
  1687         // Touch events can always be sent to a window immediately because the user intended
  1688         // to touch whatever was visible at the time.  Even if focus changes or a new
  1689         // window appears moments later, the touch event was meant to be delivered to
  1690         // whatever window happened to be on screen at the time.
  1691         //
  1692         // Generic motion events, such as trackball or joystick events are a little trickier.
  1693         // Like key events, generic motion events are delivered to the focused window.
  1694         // Unlike key events, generic motion events don't tend to transfer focus to other
  1695         // windows and it is not important for them to be serialized.  So we prefer to deliver
  1696         // generic motion events as soon as possible to improve efficiency and reduce lag
  1697         // through batching.
  1698         //
  1699         // The one case where we pause input event delivery is when the wait queue is piling
  1700         // up with lots of events because the application is not responding.
  1701         // This condition ensures that ANRs are detected reliably.
  1702         if (!connection->waitQueue.isEmpty()
  1703                 && currentTime >= connection->waitQueue.head->eventEntry->eventTime
  1704                         + STREAM_AHEAD_EVENT_TIMEOUT) {
  1705             return false;
  1708     return true;
  1711 String8 InputDispatcher::getApplicationWindowLabelLocked(
  1712         const sp<InputApplicationHandle>& applicationHandle,
  1713         const sp<InputWindowHandle>& windowHandle) {
  1714     if (applicationHandle != NULL) {
  1715         if (windowHandle != NULL) {
  1716             String8 label(applicationHandle->getName());
  1717             label.append(" - ");
  1718             label.append(windowHandle->getName());
  1719             return label;
  1720         } else {
  1721             return applicationHandle->getName();
  1723     } else if (windowHandle != NULL) {
  1724         return windowHandle->getName();
  1725     } else {
  1726         return String8("<unknown application or window>");
  1730 void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
  1731     if (mFocusedWindowHandle != NULL) {
  1732         const InputWindowInfo* info = mFocusedWindowHandle->getInfo();
  1733         if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
  1734 #if DEBUG_DISPATCH_CYCLE
  1735             ALOGD("Not poking user activity: disabled by window '%s'.", info->name.string());
  1736 #endif
  1737             return;
  1741     int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
  1742     switch (eventEntry->type) {
  1743     case EventEntry::TYPE_MOTION: {
  1744         const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
  1745         if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
  1746             return;
  1749         if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
  1750             eventType = USER_ACTIVITY_EVENT_TOUCH;
  1752         break;
  1754     case EventEntry::TYPE_KEY: {
  1755         const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
  1756         if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
  1757             return;
  1759         eventType = USER_ACTIVITY_EVENT_BUTTON;
  1760         break;
  1764     CommandEntry* commandEntry = postCommandLocked(
  1765             & InputDispatcher::doPokeUserActivityLockedInterruptible);
  1766     commandEntry->eventTime = eventEntry->eventTime;
  1767     commandEntry->userActivityEventType = eventType;
  1770 void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
  1771         const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
  1772 #if DEBUG_DISPATCH_CYCLE
  1773     ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
  1774             "xOffset=%f, yOffset=%f, scaleFactor=%f, "
  1775             "pointerIds=0x%x",
  1776             connection->getInputChannelName(), inputTarget->flags,
  1777             inputTarget->xOffset, inputTarget->yOffset,
  1778             inputTarget->scaleFactor, inputTarget->pointerIds.value);
  1779 #endif
  1781     // Skip this event if the connection status is not normal.
  1782     // We don't want to enqueue additional outbound events if the connection is broken.
  1783     if (connection->status != Connection::STATUS_NORMAL) {
  1784 #if DEBUG_DISPATCH_CYCLE
  1785         ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
  1786                 connection->getInputChannelName(), connection->getStatusLabel());
  1787 #endif
  1788         return;
  1791     // Split a motion event if needed.
  1792     if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
  1793         ALOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
  1795         MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
  1796         if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
  1797             MotionEntry* splitMotionEntry = splitMotionEvent(
  1798                     originalMotionEntry, inputTarget->pointerIds);
  1799             if (!splitMotionEntry) {
  1800                 return; // split event was dropped
  1802 #if DEBUG_FOCUS
  1803             ALOGD("channel '%s' ~ Split motion event.",
  1804                     connection->getInputChannelName());
  1805             logOutboundMotionDetailsLocked("  ", splitMotionEntry);
  1806 #endif
  1807             enqueueDispatchEntriesLocked(currentTime, connection,
  1808                     splitMotionEntry, inputTarget);
  1809             splitMotionEntry->release();
  1810             return;
  1814     // Not splitting.  Enqueue dispatch entries for the event as is.
  1815     enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
  1818 void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
  1819         const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
  1820     bool wasEmpty = connection->outboundQueue.isEmpty();
  1822     // Enqueue dispatch entries for the requested modes.
  1823     enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
  1824             InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
  1825     enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
  1826             InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
  1827     enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
  1828             InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
  1829     enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
  1830             InputTarget::FLAG_DISPATCH_AS_IS);
  1831     enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
  1832             InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
  1833     enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
  1834             InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
  1836     // If the outbound queue was previously empty, start the dispatch cycle going.
  1837     if (wasEmpty && !connection->outboundQueue.isEmpty()) {
  1838         startDispatchCycleLocked(currentTime, connection);
  1842 void InputDispatcher::enqueueDispatchEntryLocked(
  1843         const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
  1844         int32_t dispatchMode) {
  1845     int32_t inputTargetFlags = inputTarget->flags;
  1846     if (!(inputTargetFlags & dispatchMode)) {
  1847         return;
  1849     inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
  1851     // This is a new event.
  1852     // Enqueue a new dispatch entry onto the outbound queue for this connection.
  1853     DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
  1854             inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
  1855             inputTarget->scaleFactor);
  1857     // Apply target flags and update the connection's input state.
  1858     switch (eventEntry->type) {
  1859     case EventEntry::TYPE_KEY: {
  1860         KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
  1861         dispatchEntry->resolvedAction = keyEntry->action;
  1862         dispatchEntry->resolvedFlags = keyEntry->flags;
  1864         if (!connection->inputState.trackKey(keyEntry,
  1865                 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
  1866 #if DEBUG_DISPATCH_CYCLE
  1867             ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
  1868                     connection->getInputChannelName());
  1869 #endif
  1870             delete dispatchEntry;
  1871             return; // skip the inconsistent event
  1873         break;
  1876     case EventEntry::TYPE_MOTION: {
  1877         MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
  1878         if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
  1879             dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
  1880         } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
  1881             dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
  1882         } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
  1883             dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
  1884         } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
  1885             dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
  1886         } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
  1887             dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
  1888         } else {
  1889             dispatchEntry->resolvedAction = motionEntry->action;
  1891         if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
  1892                 && !connection->inputState.isHovering(
  1893                         motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
  1894 #if DEBUG_DISPATCH_CYCLE
  1895         ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
  1896                 connection->getInputChannelName());
  1897 #endif
  1898             dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
  1901         dispatchEntry->resolvedFlags = motionEntry->flags;
  1902         if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
  1903             dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
  1906         if (!connection->inputState.trackMotion(motionEntry,
  1907                 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
  1908 #if DEBUG_DISPATCH_CYCLE
  1909             ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
  1910                     connection->getInputChannelName());
  1911 #endif
  1912             delete dispatchEntry;
  1913             return; // skip the inconsistent event
  1915         break;
  1919     // Remember that we are waiting for this dispatch to complete.
  1920     if (dispatchEntry->hasForegroundTarget()) {
  1921         incrementPendingForegroundDispatchesLocked(eventEntry);
  1924     // Enqueue the dispatch entry.
  1925     connection->outboundQueue.enqueueAtTail(dispatchEntry);
  1926     traceOutboundQueueLengthLocked(connection);
  1929 void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
  1930         const sp<Connection>& connection) {
  1931 #if DEBUG_DISPATCH_CYCLE
  1932     ALOGD("channel '%s' ~ startDispatchCycle",
  1933             connection->getInputChannelName());
  1934 #endif
  1936     while (connection->status == Connection::STATUS_NORMAL
  1937             && !connection->outboundQueue.isEmpty()) {
  1938         DispatchEntry* dispatchEntry = connection->outboundQueue.head;
  1939         dispatchEntry->deliveryTime = currentTime;
  1941         // Publish the event.
  1942         status_t status;
  1943         EventEntry* eventEntry = dispatchEntry->eventEntry;
  1944         switch (eventEntry->type) {
  1945         case EventEntry::TYPE_KEY: {
  1946             KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
  1948             // Publish the key event.
  1949             status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
  1950                     keyEntry->deviceId, keyEntry->source,
  1951                     dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
  1952                     keyEntry->keyCode, keyEntry->scanCode,
  1953                     keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
  1954                     keyEntry->eventTime);
  1955             break;
  1958         case EventEntry::TYPE_MOTION: {
  1959             MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
  1961             PointerCoords scaledCoords[MAX_POINTERS];
  1962             const PointerCoords* usingCoords = motionEntry->pointerCoords;
  1964             // Set the X and Y offset depending on the input source.
  1965             float xOffset, yOffset, scaleFactor;
  1966             if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
  1967                     && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
  1968                 scaleFactor = dispatchEntry->scaleFactor;
  1969                 xOffset = dispatchEntry->xOffset * scaleFactor;
  1970                 yOffset = dispatchEntry->yOffset * scaleFactor;
  1971                 if (scaleFactor != 1.0f) {
  1972                     for (size_t i = 0; i < motionEntry->pointerCount; i++) {
  1973                         scaledCoords[i] = motionEntry->pointerCoords[i];
  1974                         scaledCoords[i].scale(scaleFactor);
  1976                     usingCoords = scaledCoords;
  1978             } else {
  1979                 xOffset = 0.0f;
  1980                 yOffset = 0.0f;
  1981                 scaleFactor = 1.0f;
  1983                 // We don't want the dispatch target to know.
  1984                 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
  1985                     for (size_t i = 0; i < motionEntry->pointerCount; i++) {
  1986                         scaledCoords[i].clear();
  1988                     usingCoords = scaledCoords;
  1992             // Publish the motion event.
  1993             status = connection->inputPublisher.publishMotionEvent(dispatchEntry->seq,
  1994                     motionEntry->deviceId, motionEntry->source,
  1995                     dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
  1996                     motionEntry->edgeFlags, motionEntry->metaState, motionEntry->buttonState,
  1997                     xOffset, yOffset,
  1998                     motionEntry->xPrecision, motionEntry->yPrecision,
  1999                     motionEntry->downTime, motionEntry->eventTime,
  2000                     motionEntry->pointerCount, motionEntry->pointerProperties,
  2001                     usingCoords);
  2002             break;
  2005         default:
  2006             ALOG_ASSERT(false);
  2007             return;
  2010         // Check the result.
  2011         if (status) {
  2012             if (status == WOULD_BLOCK) {
  2013                 if (connection->waitQueue.isEmpty()) {
  2014                     ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
  2015                             "This is unexpected because the wait queue is empty, so the pipe "
  2016                             "should be empty and we shouldn't have any problems writing an "
  2017                             "event to it, status=%d", connection->getInputChannelName(), status);
  2018                     abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
  2019                 } else {
  2020                     // Pipe is full and we are waiting for the app to finish process some events
  2021                     // before sending more events to it.
  2022 #if DEBUG_DISPATCH_CYCLE
  2023                     ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
  2024                             "waiting for the application to catch up",
  2025                             connection->getInputChannelName());
  2026 #endif
  2027                     connection->inputPublisherBlocked = true;
  2029             } else {
  2030                 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
  2031                         "status=%d", connection->getInputChannelName(), status);
  2032                 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
  2034             return;
  2037         // Re-enqueue the event on the wait queue.
  2038         connection->outboundQueue.dequeue(dispatchEntry);
  2039         traceOutboundQueueLengthLocked(connection);
  2040         connection->waitQueue.enqueueAtTail(dispatchEntry);
  2041         traceWaitQueueLengthLocked(connection);
  2045 void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
  2046         const sp<Connection>& connection, uint32_t seq, bool handled) {
  2047 #if DEBUG_DISPATCH_CYCLE
  2048     ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
  2049             connection->getInputChannelName(), seq, toString(handled));
  2050 #endif
  2052     connection->inputPublisherBlocked = false;
  2054     if (connection->status == Connection::STATUS_BROKEN
  2055             || connection->status == Connection::STATUS_ZOMBIE) {
  2056         return;
  2059     // Notify other system components and prepare to start the next dispatch cycle.
  2060     onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
  2063 void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
  2064         const sp<Connection>& connection, bool notify) {
  2065 #if DEBUG_DISPATCH_CYCLE
  2066     ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
  2067             connection->getInputChannelName(), toString(notify));
  2068 #endif
  2070     // Clear the dispatch queues.
  2071     drainDispatchQueueLocked(&connection->outboundQueue);
  2072     traceOutboundQueueLengthLocked(connection);
  2073     drainDispatchQueueLocked(&connection->waitQueue);
  2074     traceWaitQueueLengthLocked(connection);
  2076     // The connection appears to be unrecoverably broken.
  2077     // Ignore already broken or zombie connections.
  2078     if (connection->status == Connection::STATUS_NORMAL) {
  2079         connection->status = Connection::STATUS_BROKEN;
  2081         if (notify) {
  2082             // Notify other system components.
  2083             onDispatchCycleBrokenLocked(currentTime, connection);
  2088 void InputDispatcher::drainDispatchQueueLocked(Queue<DispatchEntry>* queue) {
  2089     while (!queue->isEmpty()) {
  2090         DispatchEntry* dispatchEntry = queue->dequeueAtHead();
  2091         releaseDispatchEntryLocked(dispatchEntry);
  2095 void InputDispatcher::releaseDispatchEntryLocked(DispatchEntry* dispatchEntry) {
  2096     if (dispatchEntry->hasForegroundTarget()) {
  2097         decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
  2099     delete dispatchEntry;
  2102 int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
  2103     InputDispatcher* d = static_cast<InputDispatcher*>(data);
  2105     { // acquire lock
  2106         AutoMutex _l(d->mLock);
  2108         ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
  2109         if (connectionIndex < 0) {
  2110             ALOGE("Received spurious receive callback for unknown input channel.  "
  2111                     "fd=%d, events=0x%x", fd, events);
  2112             return 0; // remove the callback
  2115         bool notify;
  2116         sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
  2117         if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
  2118             if (!(events & ALOOPER_EVENT_INPUT)) {
  2119                 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
  2120                         "events=0x%x", connection->getInputChannelName(), events);
  2121                 return 1;
  2124             nsecs_t currentTime = now();
  2125             bool gotOne = false;
  2126             status_t status;
  2127             for (;;) {
  2128                 uint32_t seq;
  2129                 bool handled;
  2130                 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
  2131                 if (status) {
  2132                     break;
  2134                 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
  2135                 gotOne = true;
  2137             if (gotOne) {
  2138                 d->runCommandsLockedInterruptible();
  2139                 if (status == WOULD_BLOCK) {
  2140                     return 1;
  2144             notify = status != DEAD_OBJECT || !connection->monitor;
  2145             if (notify) {
  2146                 ALOGE("channel '%s' ~ Failed to receive finished signal.  status=%d",
  2147                         connection->getInputChannelName(), status);
  2149         } else {
  2150             // Monitor channels are never explicitly unregistered.
  2151             // We do it automatically when the remote endpoint is closed so don't warn
  2152             // about them.
  2153             notify = !connection->monitor;
  2154             if (notify) {
  2155                 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred.  "
  2156                         "events=0x%x", connection->getInputChannelName(), events);
  2160         // Unregister the channel.
  2161         d->unregisterInputChannelLocked(connection->inputChannel, notify);
  2162         return 0; // remove the callback
  2163     } // release lock
  2166 void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
  2167         const CancelationOptions& options) {
  2168     for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
  2169         synthesizeCancelationEventsForConnectionLocked(
  2170                 mConnectionsByFd.valueAt(i), options);
  2174 void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
  2175         const sp<InputChannel>& channel, const CancelationOptions& options) {
  2176     ssize_t index = getConnectionIndexLocked(channel);
  2177     if (index >= 0) {
  2178         synthesizeCancelationEventsForConnectionLocked(
  2179                 mConnectionsByFd.valueAt(index), options);
  2183 void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
  2184         const sp<Connection>& connection, const CancelationOptions& options) {
  2185     if (connection->status == Connection::STATUS_BROKEN) {
  2186         return;
  2189     nsecs_t currentTime = now();
  2191     Vector<EventEntry*> cancelationEvents;
  2192     connection->inputState.synthesizeCancelationEvents(currentTime,
  2193             cancelationEvents, options);
  2195     if (!cancelationEvents.isEmpty()) {
  2196 #if DEBUG_OUTBOUND_EVENT_DETAILS
  2197         ALOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
  2198                 "with reality: %s, mode=%d.",
  2199                 connection->getInputChannelName(), cancelationEvents.size(),
  2200                 options.reason, options.mode);
  2201 #endif
  2202         for (size_t i = 0; i < cancelationEvents.size(); i++) {
  2203             EventEntry* cancelationEventEntry = cancelationEvents.itemAt(i);
  2204             switch (cancelationEventEntry->type) {
  2205             case EventEntry::TYPE_KEY:
  2206                 logOutboundKeyDetailsLocked("cancel - ",
  2207                         static_cast<KeyEntry*>(cancelationEventEntry));
  2208                 break;
  2209             case EventEntry::TYPE_MOTION:
  2210                 logOutboundMotionDetailsLocked("cancel - ",
  2211                         static_cast<MotionEntry*>(cancelationEventEntry));
  2212                 break;
  2215             InputTarget target;
  2216             sp<InputWindowHandle> windowHandle = getWindowHandleLocked(connection->inputChannel);
  2217             if (windowHandle != NULL) {
  2218                 const InputWindowInfo* windowInfo = windowHandle->getInfo();
  2219                 target.xOffset = -windowInfo->frameLeft;
  2220                 target.yOffset = -windowInfo->frameTop;
  2221                 target.scaleFactor = windowInfo->scaleFactor;
  2222             } else {
  2223                 target.xOffset = 0;
  2224                 target.yOffset = 0;
  2225                 target.scaleFactor = 1.0f;
  2227             target.inputChannel = connection->inputChannel;
  2228             target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
  2230             enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
  2231                     &target, InputTarget::FLAG_DISPATCH_AS_IS);
  2233             cancelationEventEntry->release();
  2236         startDispatchCycleLocked(currentTime, connection);
  2240 InputDispatcher::MotionEntry*
  2241 InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
  2242     ALOG_ASSERT(pointerIds.value != 0);
  2244     uint32_t splitPointerIndexMap[MAX_POINTERS];
  2245     PointerProperties splitPointerProperties[MAX_POINTERS];
  2246     PointerCoords splitPointerCoords[MAX_POINTERS];
  2248     uint32_t originalPointerCount = originalMotionEntry->pointerCount;
  2249     uint32_t splitPointerCount = 0;
  2251     for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
  2252             originalPointerIndex++) {
  2253         const PointerProperties& pointerProperties =
  2254                 originalMotionEntry->pointerProperties[originalPointerIndex];
  2255         uint32_t pointerId = uint32_t(pointerProperties.id);
  2256         if (pointerIds.hasBit(pointerId)) {
  2257             splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
  2258             splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
  2259             splitPointerCoords[splitPointerCount].copyFrom(
  2260                     originalMotionEntry->pointerCoords[originalPointerIndex]);
  2261             splitPointerCount += 1;
  2265     if (splitPointerCount != pointerIds.count()) {
  2266         // This is bad.  We are missing some of the pointers that we expected to deliver.
  2267         // Most likely this indicates that we received an ACTION_MOVE events that has
  2268         // different pointer ids than we expected based on the previous ACTION_DOWN
  2269         // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
  2270         // in this way.
  2271         ALOGW("Dropping split motion event because the pointer count is %d but "
  2272                 "we expected there to be %d pointers.  This probably means we received "
  2273                 "a broken sequence of pointer ids from the input device.",
  2274                 splitPointerCount, pointerIds.count());
  2275         return NULL;
  2278     int32_t action = originalMotionEntry->action;
  2279     int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
  2280     if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
  2281             || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
  2282         int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
  2283         const PointerProperties& pointerProperties =
  2284                 originalMotionEntry->pointerProperties[originalPointerIndex];
  2285         uint32_t pointerId = uint32_t(pointerProperties.id);
  2286         if (pointerIds.hasBit(pointerId)) {
  2287             if (pointerIds.count() == 1) {
  2288                 // The first/last pointer went down/up.
  2289                 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
  2290                         ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
  2291             } else {
  2292                 // A secondary pointer went down/up.
  2293                 uint32_t splitPointerIndex = 0;
  2294                 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
  2295                     splitPointerIndex += 1;
  2297                 action = maskedAction | (splitPointerIndex
  2298                         << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
  2300         } else {
  2301             // An unrelated pointer changed.
  2302             action = AMOTION_EVENT_ACTION_MOVE;
  2306     MotionEntry* splitMotionEntry = new MotionEntry(
  2307             originalMotionEntry->eventTime,
  2308             originalMotionEntry->deviceId,
  2309             originalMotionEntry->source,
  2310             originalMotionEntry->policyFlags,
  2311             action,
  2312             originalMotionEntry->flags,
  2313             originalMotionEntry->metaState,
  2314             originalMotionEntry->buttonState,
  2315             originalMotionEntry->edgeFlags,
  2316             originalMotionEntry->xPrecision,
  2317             originalMotionEntry->yPrecision,
  2318             originalMotionEntry->downTime,
  2319             originalMotionEntry->displayId,
  2320             splitPointerCount, splitPointerProperties, splitPointerCoords);
  2322     if (originalMotionEntry->injectionState) {
  2323         splitMotionEntry->injectionState = originalMotionEntry->injectionState;
  2324         splitMotionEntry->injectionState->refCount += 1;
  2327     return splitMotionEntry;
  2330 void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
  2331 #if DEBUG_INBOUND_EVENT_DETAILS
  2332     ALOGD("notifyConfigurationChanged - eventTime=%lld", args->eventTime);
  2333 #endif
  2335     bool needWake;
  2336     { // acquire lock
  2337         AutoMutex _l(mLock);
  2339         ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(args->eventTime);
  2340         needWake = enqueueInboundEventLocked(newEntry);
  2341     } // release lock
  2343     if (needWake) {
  2344         mLooper->wake();
  2348 void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
  2349 #if DEBUG_INBOUND_EVENT_DETAILS
  2350     ALOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
  2351             "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
  2352             args->eventTime, args->deviceId, args->source, args->policyFlags,
  2353             args->action, args->flags, args->keyCode, args->scanCode,
  2354             args->metaState, args->downTime);
  2355 #endif
  2356     if (!validateKeyEvent(args->action)) {
  2357         return;
  2360     uint32_t policyFlags = args->policyFlags;
  2361     int32_t flags = args->flags;
  2362     int32_t metaState = args->metaState;
  2363     if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
  2364         policyFlags |= POLICY_FLAG_VIRTUAL;
  2365         flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
  2367     if (policyFlags & POLICY_FLAG_ALT) {
  2368         metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON;
  2370     if (policyFlags & POLICY_FLAG_ALT_GR) {
  2371         metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON;
  2373     if (policyFlags & POLICY_FLAG_SHIFT) {
  2374         metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON;
  2376     if (policyFlags & POLICY_FLAG_CAPS_LOCK) {
  2377         metaState |= AMETA_CAPS_LOCK_ON;
  2379     if (policyFlags & POLICY_FLAG_FUNCTION) {
  2380         metaState |= AMETA_FUNCTION_ON;
  2383     policyFlags |= POLICY_FLAG_TRUSTED;
  2385     KeyEvent event;
  2386     event.initialize(args->deviceId, args->source, args->action,
  2387             flags, args->keyCode, args->scanCode, metaState, 0,
  2388             args->downTime, args->eventTime);
  2390     mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
  2392     if (policyFlags & POLICY_FLAG_WOKE_HERE) {
  2393         flags |= AKEY_EVENT_FLAG_WOKE_HERE;
  2396     bool needWake;
  2397     { // acquire lock
  2398         mLock.lock();
  2400         if (shouldSendKeyToInputFilterLocked(args)) {
  2401             mLock.unlock();
  2403             policyFlags |= POLICY_FLAG_FILTERED;
  2404             if (!mPolicy->filterInputEvent(&event, policyFlags)) {
  2405                 return; // event was consumed by the filter
  2408             mLock.lock();
  2411         int32_t repeatCount = 0;
  2412         KeyEntry* newEntry = new KeyEntry(args->eventTime,
  2413                 args->deviceId, args->source, policyFlags,
  2414                 args->action, flags, args->keyCode, args->scanCode,
  2415                 metaState, repeatCount, args->downTime);
  2417         needWake = enqueueInboundEventLocked(newEntry);
  2418         mLock.unlock();
  2419     } // release lock
  2421     if (needWake) {
  2422         mLooper->wake();
  2426 bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
  2427     return mInputFilterEnabled;
  2430 void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
  2431 #if DEBUG_INBOUND_EVENT_DETAILS
  2432     ALOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
  2433             "action=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, edgeFlags=0x%x, "
  2434             "xPrecision=%f, yPrecision=%f, downTime=%lld",
  2435             args->eventTime, args->deviceId, args->source, args->policyFlags,
  2436             args->action, args->flags, args->metaState, args->buttonState,
  2437             args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
  2438     for (uint32_t i = 0; i < args->pointerCount; i++) {
  2439         ALOGD("  Pointer %d: id=%d, toolType=%d, "
  2440                 "x=%f, y=%f, pressure=%f, size=%f, "
  2441                 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
  2442                 "orientation=%f",
  2443                 i, args->pointerProperties[i].id,
  2444                 args->pointerProperties[i].toolType,
  2445                 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
  2446                 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
  2447                 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
  2448                 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
  2449                 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
  2450                 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
  2451                 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
  2452                 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
  2453                 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
  2455 #endif
  2456     if (!validateMotionEvent(args->action, args->pointerCount, args->pointerProperties)) {
  2457         return;
  2460     uint32_t policyFlags = args->policyFlags;
  2461     policyFlags |= POLICY_FLAG_TRUSTED;
  2462     mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
  2464     bool needWake;
  2465     { // acquire lock
  2466         mLock.lock();
  2468         if (shouldSendMotionToInputFilterLocked(args)) {
  2469             mLock.unlock();
  2471             MotionEvent event;
  2472             event.initialize(args->deviceId, args->source, args->action, args->flags,
  2473                     args->edgeFlags, args->metaState, args->buttonState, 0, 0,
  2474                     args->xPrecision, args->yPrecision,
  2475                     args->downTime, args->eventTime,
  2476                     args->pointerCount, args->pointerProperties, args->pointerCoords);
  2478             policyFlags |= POLICY_FLAG_FILTERED;
  2479             if (!mPolicy->filterInputEvent(&event, policyFlags)) {
  2480                 return; // event was consumed by the filter
  2483             mLock.lock();
  2486         // Just enqueue a new motion event.
  2487         MotionEntry* newEntry = new MotionEntry(args->eventTime,
  2488                 args->deviceId, args->source, policyFlags,
  2489                 args->action, args->flags, args->metaState, args->buttonState,
  2490                 args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
  2491                 args->displayId,
  2492                 args->pointerCount, args->pointerProperties, args->pointerCoords);
  2494         needWake = enqueueInboundEventLocked(newEntry);
  2495         mLock.unlock();
  2496     } // release lock
  2498     if (needWake) {
  2499         mLooper->wake();
  2503 bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
  2504     // TODO: support sending secondary display events to input filter
  2505     return mInputFilterEnabled && isMainDisplay(args->displayId);
  2508 void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
  2509 #if DEBUG_INBOUND_EVENT_DETAILS
  2510     ALOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchValues=0x%08x, switchMask=0x%08x",
  2511             args->eventTime, args->policyFlags,
  2512             args->switchValues, args->switchMask);
  2513 #endif
  2515     uint32_t policyFlags = args->policyFlags;
  2516     policyFlags |= POLICY_FLAG_TRUSTED;
  2517     mPolicy->notifySwitch(args->eventTime,
  2518             args->switchValues, args->switchMask, policyFlags);
  2521 void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
  2522 #if DEBUG_INBOUND_EVENT_DETAILS
  2523     ALOGD("notifyDeviceReset - eventTime=%lld, deviceId=%d",
  2524             args->eventTime, args->deviceId);
  2525 #endif
  2527     bool needWake;
  2528     { // acquire lock
  2529         AutoMutex _l(mLock);
  2531         DeviceResetEntry* newEntry = new DeviceResetEntry(args->eventTime, args->deviceId);
  2532         needWake = enqueueInboundEventLocked(newEntry);
  2533     } // release lock
  2535     if (needWake) {
  2536         mLooper->wake();
  2540 int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
  2541         int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
  2542         uint32_t policyFlags) {
  2543 #if DEBUG_INBOUND_EVENT_DETAILS
  2544     ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
  2545             "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
  2546             event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
  2547 #endif
  2549     nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
  2551     policyFlags |= POLICY_FLAG_INJECTED;
  2552     if (hasInjectionPermission(injectorPid, injectorUid)) {
  2553         policyFlags |= POLICY_FLAG_TRUSTED;
  2556     EventEntry* firstInjectedEntry;
  2557     EventEntry* lastInjectedEntry;
  2558     switch (event->getType()) {
  2559     case AINPUT_EVENT_TYPE_KEY: {
  2560         const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
  2561         int32_t action = keyEvent->getAction();
  2562         if (! validateKeyEvent(action)) {
  2563             return INPUT_EVENT_INJECTION_FAILED;
  2566         int32_t flags = keyEvent->getFlags();
  2567         if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
  2568             policyFlags |= POLICY_FLAG_VIRTUAL;
  2571         if (!(policyFlags & POLICY_FLAG_FILTERED)) {
  2572             mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
  2575         if (policyFlags & POLICY_FLAG_WOKE_HERE) {
  2576             flags |= AKEY_EVENT_FLAG_WOKE_HERE;
  2579         mLock.lock();
  2580         firstInjectedEntry = new KeyEntry(keyEvent->getEventTime(),
  2581                 keyEvent->getDeviceId(), keyEvent->getSource(),
  2582                 policyFlags, action, flags,
  2583                 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
  2584                 keyEvent->getRepeatCount(), keyEvent->getDownTime());
  2585         lastInjectedEntry = firstInjectedEntry;
  2586         break;
  2589     case AINPUT_EVENT_TYPE_MOTION: {
  2590         const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
  2591         int32_t displayId = ADISPLAY_ID_DEFAULT;
  2592         int32_t action = motionEvent->getAction();
  2593         size_t pointerCount = motionEvent->getPointerCount();
  2594         const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
  2595         if (! validateMotionEvent(action, pointerCount, pointerProperties)) {
  2596             return INPUT_EVENT_INJECTION_FAILED;
  2599         if (!(policyFlags & POLICY_FLAG_FILTERED)) {
  2600             nsecs_t eventTime = motionEvent->getEventTime();
  2601             mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
  2604         mLock.lock();
  2605         const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
  2606         const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
  2607         firstInjectedEntry = new MotionEntry(*sampleEventTimes,
  2608                 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
  2609                 action, motionEvent->getFlags(),
  2610                 motionEvent->getMetaState(), motionEvent->getButtonState(),
  2611                 motionEvent->getEdgeFlags(),
  2612                 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
  2613                 motionEvent->getDownTime(), displayId,
  2614                 uint32_t(pointerCount), pointerProperties, samplePointerCoords);
  2615         lastInjectedEntry = firstInjectedEntry;
  2616         for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
  2617             sampleEventTimes += 1;
  2618             samplePointerCoords += pointerCount;
  2619             MotionEntry* nextInjectedEntry = new MotionEntry(*sampleEventTimes,
  2620                     motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
  2621                     action, motionEvent->getFlags(),
  2622                     motionEvent->getMetaState(), motionEvent->getButtonState(),
  2623                     motionEvent->getEdgeFlags(),
  2624                     motionEvent->getXPrecision(), motionEvent->getYPrecision(),
  2625                     motionEvent->getDownTime(), displayId,
  2626                     uint32_t(pointerCount), pointerProperties, samplePointerCoords);
  2627             lastInjectedEntry->next = nextInjectedEntry;
  2628             lastInjectedEntry = nextInjectedEntry;
  2630         break;
  2633     default:
  2634         ALOGW("Cannot inject event of type %d", event->getType());
  2635         return INPUT_EVENT_INJECTION_FAILED;
  2638     InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
  2639     if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
  2640         injectionState->injectionIsAsync = true;
  2643     injectionState->refCount += 1;
  2644     lastInjectedEntry->injectionState = injectionState;
  2646     bool needWake = false;
  2647     for (EventEntry* entry = firstInjectedEntry; entry != NULL; ) {
  2648         EventEntry* nextEntry = entry->next;
  2649         needWake |= enqueueInboundEventLocked(entry);
  2650         entry = nextEntry;
  2653     mLock.unlock();
  2655     if (needWake) {
  2656         mLooper->wake();
  2659     int32_t injectionResult;
  2660     { // acquire lock
  2661         AutoMutex _l(mLock);
  2663         if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
  2664             injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
  2665         } else {
  2666             for (;;) {
  2667                 injectionResult = injectionState->injectionResult;
  2668                 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
  2669                     break;
  2672                 nsecs_t remainingTimeout = endTime - now();
  2673                 if (remainingTimeout <= 0) {
  2674 #if DEBUG_INJECTION
  2675                     ALOGD("injectInputEvent - Timed out waiting for injection result "
  2676                             "to become available.");
  2677 #endif
  2678                     injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
  2679                     break;
  2682                 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
  2685             if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
  2686                     && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
  2687                 while (injectionState->pendingForegroundDispatches != 0) {
  2688 #if DEBUG_INJECTION
  2689                     ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
  2690                             injectionState->pendingForegroundDispatches);
  2691 #endif
  2692                     nsecs_t remainingTimeout = endTime - now();
  2693                     if (remainingTimeout <= 0) {
  2694 #if DEBUG_INJECTION
  2695                     ALOGD("injectInputEvent - Timed out waiting for pending foreground "
  2696                             "dispatches to finish.");
  2697 #endif
  2698                         injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
  2699                         break;
  2702                     mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
  2707         injectionState->release();
  2708     } // release lock
  2710 #if DEBUG_INJECTION
  2711     ALOGD("injectInputEvent - Finished with result %d.  "
  2712             "injectorPid=%d, injectorUid=%d",
  2713             injectionResult, injectorPid, injectorUid);
  2714 #endif
  2716     return injectionResult;
  2719 bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
  2720     return injectorUid == 0
  2721             || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
  2724 void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
  2725     InjectionState* injectionState = entry->injectionState;
  2726     if (injectionState) {
  2727 #if DEBUG_INJECTION
  2728         ALOGD("Setting input event injection result to %d.  "
  2729                 "injectorPid=%d, injectorUid=%d",
  2730                  injectionResult, injectionState->injectorPid, injectionState->injectorUid);
  2731 #endif
  2733         if (injectionState->injectionIsAsync
  2734                 && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
  2735             // Log the outcome since the injector did not wait for the injection result.
  2736             switch (injectionResult) {
  2737             case INPUT_EVENT_INJECTION_SUCCEEDED:
  2738                 ALOGV("Asynchronous input event injection succeeded.");
  2739                 break;
  2740             case INPUT_EVENT_INJECTION_FAILED:
  2741                 ALOGW("Asynchronous input event injection failed.");
  2742                 break;
  2743             case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
  2744                 ALOGW("Asynchronous input event injection permission denied.");
  2745                 break;
  2746             case INPUT_EVENT_INJECTION_TIMED_OUT:
  2747                 ALOGW("Asynchronous input event injection timed out.");
  2748                 break;
  2752         injectionState->injectionResult = injectionResult;
  2753         mInjectionResultAvailableCondition.broadcast();
  2757 void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
  2758     InjectionState* injectionState = entry->injectionState;
  2759     if (injectionState) {
  2760         injectionState->pendingForegroundDispatches += 1;
  2764 void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
  2765     InjectionState* injectionState = entry->injectionState;
  2766     if (injectionState) {
  2767         injectionState->pendingForegroundDispatches -= 1;
  2769         if (injectionState->pendingForegroundDispatches == 0) {
  2770             mInjectionSyncFinishedCondition.broadcast();
  2775 sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
  2776         const sp<InputChannel>& inputChannel) const {
  2777     size_t numWindows = mWindowHandles.size();
  2778     for (size_t i = 0; i < numWindows; i++) {
  2779         const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
  2780         if (windowHandle->getInputChannel() == inputChannel) {
  2781             return windowHandle;
  2784     return NULL;
  2787 bool InputDispatcher::hasWindowHandleLocked(
  2788         const sp<InputWindowHandle>& windowHandle) const {
  2789     size_t numWindows = mWindowHandles.size();
  2790     for (size_t i = 0; i < numWindows; i++) {
  2791         if (mWindowHandles.itemAt(i) == windowHandle) {
  2792             return true;
  2795     return false;
  2798 void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) {
  2799 #if DEBUG_FOCUS
  2800     ALOGD("setInputWindows");
  2801 #endif
  2802     { // acquire lock
  2803         AutoMutex _l(mLock);
  2805         Vector<sp<InputWindowHandle> > oldWindowHandles = mWindowHandles;
  2806         mWindowHandles = inputWindowHandles;
  2808         sp<InputWindowHandle> newFocusedWindowHandle;
  2809         bool foundHoveredWindow = false;
  2810         for (size_t i = 0; i < mWindowHandles.size(); i++) {
  2811             const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
  2812             if (!windowHandle->updateInfo() || windowHandle->getInputChannel() == NULL) {
  2813                 mWindowHandles.removeAt(i--);
  2814                 continue;
  2816             if (windowHandle->getInfo()->hasFocus) {
  2817                 newFocusedWindowHandle = windowHandle;
  2819             if (windowHandle == mLastHoverWindowHandle) {
  2820                 foundHoveredWindow = true;
  2824         if (!foundHoveredWindow) {
  2825             mLastHoverWindowHandle = NULL;
  2828         if (mFocusedWindowHandle != newFocusedWindowHandle) {
  2829             if (mFocusedWindowHandle != NULL) {
  2830 #if DEBUG_FOCUS
  2831                 ALOGD("Focus left window: %s",
  2832                         mFocusedWindowHandle->getName().string());
  2833 #endif
  2834                 sp<InputChannel> focusedInputChannel = mFocusedWindowHandle->getInputChannel();
  2835                 if (focusedInputChannel != NULL) {
  2836                     CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
  2837                             "focus left window");
  2838                     synthesizeCancelationEventsForInputChannelLocked(
  2839                             focusedInputChannel, options);
  2842             if (newFocusedWindowHandle != NULL) {
  2843 #if DEBUG_FOCUS
  2844                 ALOGD("Focus entered window: %s",
  2845                         newFocusedWindowHandle->getName().string());
  2846 #endif
  2848             mFocusedWindowHandle = newFocusedWindowHandle;
  2851         for (size_t i = 0; i < mTouchState.windows.size(); i++) {
  2852             TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
  2853             if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
  2854 #if DEBUG_FOCUS
  2855                 ALOGD("Touched window was removed: %s",
  2856                         touchedWindow.windowHandle->getName().string());
  2857 #endif
  2858                 sp<InputChannel> touchedInputChannel =
  2859                         touchedWindow.windowHandle->getInputChannel();
  2860                 if (touchedInputChannel != NULL) {
  2861                     CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
  2862                             "touched window was removed");
  2863                     synthesizeCancelationEventsForInputChannelLocked(
  2864                             touchedInputChannel, options);
  2866                 mTouchState.windows.removeAt(i--);
  2870         // Release information for windows that are no longer present.
  2871         // This ensures that unused input channels are released promptly.
  2872         // Otherwise, they might stick around until the window handle is destroyed
  2873         // which might not happen until the next GC.
  2874         for (size_t i = 0; i < oldWindowHandles.size(); i++) {
  2875             const sp<InputWindowHandle>& oldWindowHandle = oldWindowHandles.itemAt(i);
  2876             if (!hasWindowHandleLocked(oldWindowHandle)) {
  2877 #if DEBUG_FOCUS
  2878                 ALOGD("Window went away: %s", oldWindowHandle->getName().string());
  2879 #endif
  2880                 oldWindowHandle->releaseInfo();
  2883     } // release lock
  2885     // Wake up poll loop since it may need to make new input dispatching choices.
  2886     mLooper->wake();
  2889 void InputDispatcher::setFocusedApplication(
  2890         const sp<InputApplicationHandle>& inputApplicationHandle) {
  2891 #if DEBUG_FOCUS
  2892     ALOGD("setFocusedApplication");
  2893 #endif
  2894     { // acquire lock
  2895         AutoMutex _l(mLock);
  2897         if (inputApplicationHandle != NULL && inputApplicationHandle->updateInfo()) {
  2898             if (mFocusedApplicationHandle != inputApplicationHandle) {
  2899                 if (mFocusedApplicationHandle != NULL) {
  2900                     resetANRTimeoutsLocked();
  2901                     mFocusedApplicationHandle->releaseInfo();
  2903                 mFocusedApplicationHandle = inputApplicationHandle;
  2905         } else if (mFocusedApplicationHandle != NULL) {
  2906             resetANRTimeoutsLocked();
  2907             mFocusedApplicationHandle->releaseInfo();
  2908             mFocusedApplicationHandle.clear();
  2911 #if DEBUG_FOCUS
  2912         //logDispatchStateLocked();
  2913 #endif
  2914     } // release lock
  2916     // Wake up poll loop since it may need to make new input dispatching choices.
  2917     mLooper->wake();
  2920 void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
  2921 #if DEBUG_FOCUS
  2922     ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
  2923 #endif
  2925     bool changed;
  2926     { // acquire lock
  2927         AutoMutex _l(mLock);
  2929         if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
  2930             if (mDispatchFrozen && !frozen) {
  2931                 resetANRTimeoutsLocked();
  2934             if (mDispatchEnabled && !enabled) {
  2935                 resetAndDropEverythingLocked("dispatcher is being disabled");
  2938             mDispatchEnabled = enabled;
  2939             mDispatchFrozen = frozen;
  2940             changed = true;
  2941         } else {
  2942             changed = false;
  2945 #if DEBUG_FOCUS
  2946         //logDispatchStateLocked();
  2947 #endif
  2948     } // release lock
  2950     if (changed) {
  2951         // Wake up poll loop since it may need to make new input dispatching choices.
  2952         mLooper->wake();
  2956 void InputDispatcher::setInputFilterEnabled(bool enabled) {
  2957 #if DEBUG_FOCUS
  2958     ALOGD("setInputFilterEnabled: enabled=%d", enabled);
  2959 #endif
  2961     { // acquire lock
  2962         AutoMutex _l(mLock);
  2964         if (mInputFilterEnabled == enabled) {
  2965             return;
  2968         mInputFilterEnabled = enabled;
  2969         resetAndDropEverythingLocked("input filter is being enabled or disabled");
  2970     } // release lock
  2972     // Wake up poll loop since there might be work to do to drop everything.
  2973     mLooper->wake();
  2976 bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
  2977         const sp<InputChannel>& toChannel) {
  2978 #if DEBUG_FOCUS
  2979     ALOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
  2980             fromChannel->getName().string(), toChannel->getName().string());
  2981 #endif
  2982     { // acquire lock
  2983         AutoMutex _l(mLock);
  2985         sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromChannel);
  2986         sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toChannel);
  2987         if (fromWindowHandle == NULL || toWindowHandle == NULL) {
  2988 #if DEBUG_FOCUS
  2989             ALOGD("Cannot transfer focus because from or to window not found.");
  2990 #endif
  2991             return false;
  2993         if (fromWindowHandle == toWindowHandle) {
  2994 #if DEBUG_FOCUS
  2995             ALOGD("Trivial transfer to same window.");
  2996 #endif
  2997             return true;
  2999         if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
  3000 #if DEBUG_FOCUS
  3001             ALOGD("Cannot transfer focus because windows are on different displays.");
  3002 #endif
  3003             return false;
  3006         bool found = false;
  3007         for (size_t i = 0; i < mTouchState.windows.size(); i++) {
  3008             const TouchedWindow& touchedWindow = mTouchState.windows[i];
  3009             if (touchedWindow.windowHandle == fromWindowHandle) {
  3010                 int32_t oldTargetFlags = touchedWindow.targetFlags;
  3011                 BitSet32 pointerIds = touchedWindow.pointerIds;
  3013                 mTouchState.windows.removeAt(i);
  3015                 int32_t newTargetFlags = oldTargetFlags
  3016                         & (InputTarget::FLAG_FOREGROUND
  3017                                 | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
  3018                 mTouchState.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
  3020                 found = true;
  3021                 break;
  3025         if (! found) {
  3026 #if DEBUG_FOCUS
  3027             ALOGD("Focus transfer failed because from window did not have focus.");
  3028 #endif
  3029             return false;
  3032         ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
  3033         ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
  3034         if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
  3035             sp<Connection> fromConnection = mConnectionsByFd.valueAt(fromConnectionIndex);
  3036             sp<Connection> toConnection = mConnectionsByFd.valueAt(toConnectionIndex);
  3038             fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
  3039             CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
  3040                     "transferring touch focus from this window to another window");
  3041             synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
  3044 #if DEBUG_FOCUS
  3045         logDispatchStateLocked();
  3046 #endif
  3047     } // release lock
  3049     // Wake up poll loop since it may need to make new input dispatching choices.
  3050     mLooper->wake();
  3051     return true;
  3054 void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
  3055 #if DEBUG_FOCUS
  3056     ALOGD("Resetting and dropping all events (%s).", reason);
  3057 #endif
  3059     CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
  3060     synthesizeCancelationEventsForAllConnectionsLocked(options);
  3062     resetKeyRepeatLocked();
  3063     releasePendingEventLocked();
  3064     drainInboundQueueLocked();
  3065     resetANRTimeoutsLocked();
  3067     mTouchState.reset();
  3068     mLastHoverWindowHandle.clear();
  3071 void InputDispatcher::logDispatchStateLocked() {
  3072     String8 dump;
  3073     dumpDispatchStateLocked(dump);
  3075     char* text = dump.lockBuffer(dump.size());
  3076     char* start = text;
  3077     while (*start != '\0') {
  3078         char* end = strchr(start, '\n');
  3079         if (*end == '\n') {
  3080             *(end++) = '\0';
  3082         ALOGD("%s", start);
  3083         start = end;
  3087 void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
  3088     dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
  3089     dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
  3091     if (mFocusedApplicationHandle != NULL) {
  3092         dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
  3093                 mFocusedApplicationHandle->getName().string(),
  3094                 mFocusedApplicationHandle->getDispatchingTimeout(
  3095                         DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
  3096     } else {
  3097         dump.append(INDENT "FocusedApplication: <null>\n");
  3099     dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
  3100             mFocusedWindowHandle != NULL ? mFocusedWindowHandle->getName().string() : "<null>");
  3102     dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
  3103     dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
  3104     dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
  3105     dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
  3106     dump.appendFormat(INDENT "TouchDisplayId: %d\n", mTouchState.displayId);
  3107     if (!mTouchState.windows.isEmpty()) {
  3108         dump.append(INDENT "TouchedWindows:\n");
  3109         for (size_t i = 0; i < mTouchState.windows.size(); i++) {
  3110             const TouchedWindow& touchedWindow = mTouchState.windows[i];
  3111             dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
  3112                     i, touchedWindow.windowHandle->getName().string(),
  3113                     touchedWindow.pointerIds.value,
  3114                     touchedWindow.targetFlags);
  3116     } else {
  3117         dump.append(INDENT "TouchedWindows: <none>\n");
  3120     if (!mWindowHandles.isEmpty()) {
  3121         dump.append(INDENT "Windows:\n");
  3122         for (size_t i = 0; i < mWindowHandles.size(); i++) {
  3123             const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
  3124             const InputWindowInfo* windowInfo = windowHandle->getInfo();
  3126             dump.appendFormat(INDENT2 "%d: name='%s', displayId=%d, "
  3127                     "paused=%s, hasFocus=%s, hasWallpaper=%s, "
  3128                     "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
  3129                     "frame=[%d,%d][%d,%d], scale=%f, "
  3130                     "touchableRegion=",
  3131                     i, windowInfo->name.string(), windowInfo->displayId,
  3132                     toString(windowInfo->paused),
  3133                     toString(windowInfo->hasFocus),
  3134                     toString(windowInfo->hasWallpaper),
  3135                     toString(windowInfo->visible),
  3136                     toString(windowInfo->canReceiveKeys),
  3137                     windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
  3138                     windowInfo->layer,
  3139                     windowInfo->frameLeft, windowInfo->frameTop,
  3140                     windowInfo->frameRight, windowInfo->frameBottom,
  3141                     windowInfo->scaleFactor);
  3142             dumpRegion(dump, windowInfo->touchableRegion);
  3143             dump.appendFormat(", inputFeatures=0x%08x", windowInfo->inputFeatures);
  3144             dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
  3145                     windowInfo->ownerPid, windowInfo->ownerUid,
  3146                     windowInfo->dispatchingTimeout / 1000000.0);
  3148     } else {
  3149         dump.append(INDENT "Windows: <none>\n");
  3152     if (!mMonitoringChannels.isEmpty()) {
  3153         dump.append(INDENT "MonitoringChannels:\n");
  3154         for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
  3155             const sp<InputChannel>& channel = mMonitoringChannels[i];
  3156             dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
  3158     } else {
  3159         dump.append(INDENT "MonitoringChannels: <none>\n");
  3162     nsecs_t currentTime = now();
  3164     if (!mInboundQueue.isEmpty()) {
  3165         dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
  3166         for (EventEntry* entry = mInboundQueue.head; entry; entry = entry->next) {
  3167             dump.append(INDENT2);
  3168             entry->appendDescription(dump);
  3169             dump.appendFormat(", age=%0.1fms\n",
  3170                     (currentTime - entry->eventTime) * 0.000001f);
  3172     } else {
  3173         dump.append(INDENT "InboundQueue: <empty>\n");
  3176     if (!mConnectionsByFd.isEmpty()) {
  3177         dump.append(INDENT "Connections:\n");
  3178         for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
  3179             const sp<Connection>& connection = mConnectionsByFd.valueAt(i);
  3180             dump.appendFormat(INDENT2 "%d: channelName='%s', windowName='%s', "
  3181                     "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
  3182                     i, connection->getInputChannelName(), connection->getWindowName(),
  3183                     connection->getStatusLabel(), toString(connection->monitor),
  3184                     toString(connection->inputPublisherBlocked));
  3186             if (!connection->outboundQueue.isEmpty()) {
  3187                 dump.appendFormat(INDENT3 "OutboundQueue: length=%u\n",
  3188                         connection->outboundQueue.count());
  3189                 for (DispatchEntry* entry = connection->outboundQueue.head; entry;
  3190                         entry = entry->next) {
  3191                     dump.append(INDENT4);
  3192                     entry->eventEntry->appendDescription(dump);
  3193                     dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
  3194                             entry->targetFlags, entry->resolvedAction,
  3195                             (currentTime - entry->eventEntry->eventTime) * 0.000001f);
  3197             } else {
  3198                 dump.append(INDENT3 "OutboundQueue: <empty>\n");
  3201             if (!connection->waitQueue.isEmpty()) {
  3202                 dump.appendFormat(INDENT3 "WaitQueue: length=%u\n",
  3203                         connection->waitQueue.count());
  3204                 for (DispatchEntry* entry = connection->waitQueue.head; entry;
  3205                         entry = entry->next) {
  3206                     dump.append(INDENT4);
  3207                     entry->eventEntry->appendDescription(dump);
  3208                     dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, "
  3209                             "age=%0.1fms, wait=%0.1fms\n",
  3210                             entry->targetFlags, entry->resolvedAction,
  3211                             (currentTime - entry->eventEntry->eventTime) * 0.000001f,
  3212                             (currentTime - entry->deliveryTime) * 0.000001f);
  3214             } else {
  3215                 dump.append(INDENT3 "WaitQueue: <empty>\n");
  3218     } else {
  3219         dump.append(INDENT "Connections: <none>\n");
  3222     if (isAppSwitchPendingLocked()) {
  3223         dump.appendFormat(INDENT "AppSwitch: pending, due in %0.1fms\n",
  3224                 (mAppSwitchDueTime - now()) / 1000000.0);
  3225     } else {
  3226         dump.append(INDENT "AppSwitch: not pending\n");
  3229     dump.append(INDENT "Configuration:\n");
  3230     dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n",
  3231             mConfig.keyRepeatDelay * 0.000001f);
  3232     dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
  3233             mConfig.keyRepeatTimeout * 0.000001f);
  3236 status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
  3237         const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
  3238 #if DEBUG_REGISTRATION
  3239     ALOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
  3240             toString(monitor));
  3241 #endif
  3243     { // acquire lock
  3244         AutoMutex _l(mLock);
  3246         if (getConnectionIndexLocked(inputChannel) >= 0) {
  3247             ALOGW("Attempted to register already registered input channel '%s'",
  3248                     inputChannel->getName().string());
  3249             return BAD_VALUE;
  3252         sp<Connection> connection = new Connection(inputChannel, inputWindowHandle, monitor);
  3254         int fd = inputChannel->getFd();
  3255         mConnectionsByFd.add(fd, connection);
  3257         if (monitor) {
  3258             mMonitoringChannels.push(inputChannel);
  3261         mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
  3262     } // release lock
  3264     // Wake the looper because some connections have changed.
  3265     mLooper->wake();
  3266     return OK;
  3269 status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
  3270 #if DEBUG_REGISTRATION
  3271     ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
  3272 #endif
  3274     { // acquire lock
  3275         AutoMutex _l(mLock);
  3277         status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
  3278         if (status) {
  3279             return status;
  3281     } // release lock
  3283     // Wake the poll loop because removing the connection may have changed the current
  3284     // synchronization state.
  3285     mLooper->wake();
  3286     return OK;
  3289 status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
  3290         bool notify) {
  3291     ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
  3292     if (connectionIndex < 0) {
  3293         ALOGW("Attempted to unregister already unregistered input channel '%s'",
  3294                 inputChannel->getName().string());
  3295         return BAD_VALUE;
  3298     sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
  3299     mConnectionsByFd.removeItemsAt(connectionIndex);
  3301     if (connection->monitor) {
  3302         removeMonitorChannelLocked(inputChannel);
  3305     mLooper->removeFd(inputChannel->getFd());
  3307     nsecs_t currentTime = now();
  3308     abortBrokenDispatchCycleLocked(currentTime, connection, notify);
  3310     connection->status = Connection::STATUS_ZOMBIE;
  3311     return OK;
  3314 void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
  3315     for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
  3316          if (mMonitoringChannels[i] == inputChannel) {
  3317              mMonitoringChannels.removeAt(i);
  3318              break;
  3323 ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
  3324     ssize_t connectionIndex = mConnectionsByFd.indexOfKey(inputChannel->getFd());
  3325     if (connectionIndex >= 0) {
  3326         sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
  3327         if (connection->inputChannel.get() == inputChannel.get()) {
  3328             return connectionIndex;
  3332     return -1;
  3335 void InputDispatcher::onDispatchCycleFinishedLocked(
  3336         nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
  3337     CommandEntry* commandEntry = postCommandLocked(
  3338             & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
  3339     commandEntry->connection = connection;
  3340     commandEntry->eventTime = currentTime;
  3341     commandEntry->seq = seq;
  3342     commandEntry->handled = handled;
  3345 void InputDispatcher::onDispatchCycleBrokenLocked(
  3346         nsecs_t currentTime, const sp<Connection>& connection) {
  3347     ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
  3348             connection->getInputChannelName());
  3350     CommandEntry* commandEntry = postCommandLocked(
  3351             & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
  3352     commandEntry->connection = connection;
  3355 void InputDispatcher::onANRLocked(
  3356         nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
  3357         const sp<InputWindowHandle>& windowHandle,
  3358         nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
  3359     float dispatchLatency = (currentTime - eventTime) * 0.000001f;
  3360     float waitDuration = (currentTime - waitStartTime) * 0.000001f;
  3361     ALOGI("Application is not responding: %s.  "
  3362             "It has been %0.1fms since event, %0.1fms since wait started.  Reason: %s",
  3363             getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
  3364             dispatchLatency, waitDuration, reason);
  3366     // Capture a record of the InputDispatcher state at the time of the ANR.
  3367     time_t t = time(NULL);
  3368     struct tm tm;
  3369     localtime_r(&t, &tm);
  3370     char timestr[64];
  3371     strftime(timestr, sizeof(timestr), "%F %T", &tm);
  3372     mLastANRState.clear();
  3373     mLastANRState.append(INDENT "ANR:\n");
  3374     mLastANRState.appendFormat(INDENT2 "Time: %s\n", timestr);
  3375     mLastANRState.appendFormat(INDENT2 "Window: %s\n",
  3376             getApplicationWindowLabelLocked(applicationHandle, windowHandle).string());
  3377     mLastANRState.appendFormat(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
  3378     mLastANRState.appendFormat(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
  3379     mLastANRState.appendFormat(INDENT2 "Reason: %s\n", reason);
  3380     dumpDispatchStateLocked(mLastANRState);
  3382     CommandEntry* commandEntry = postCommandLocked(
  3383             & InputDispatcher::doNotifyANRLockedInterruptible);
  3384     commandEntry->inputApplicationHandle = applicationHandle;
  3385     commandEntry->inputWindowHandle = windowHandle;
  3388 void InputDispatcher::doNotifyConfigurationChangedInterruptible(
  3389         CommandEntry* commandEntry) {
  3390     mLock.unlock();
  3392     mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
  3394     mLock.lock();
  3397 void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
  3398         CommandEntry* commandEntry) {
  3399     sp<Connection> connection = commandEntry->connection;
  3401     if (connection->status != Connection::STATUS_ZOMBIE) {
  3402         mLock.unlock();
  3404         mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
  3406         mLock.lock();
  3410 void InputDispatcher::doNotifyANRLockedInterruptible(
  3411         CommandEntry* commandEntry) {
  3412     mLock.unlock();
  3414     nsecs_t newTimeout = mPolicy->notifyANR(
  3415             commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
  3417     mLock.lock();
  3419     resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
  3420             commandEntry->inputWindowHandle != NULL
  3421                     ? commandEntry->inputWindowHandle->getInputChannel() : NULL);
  3424 void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
  3425         CommandEntry* commandEntry) {
  3426     KeyEntry* entry = commandEntry->keyEntry;
  3428     KeyEvent event;
  3429     initializeKeyEvent(&event, entry);
  3431     mLock.unlock();
  3433     nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
  3434             &event, entry->policyFlags);
  3436     mLock.lock();
  3438     if (delay < 0) {
  3439         entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
  3440     } else if (!delay) {
  3441         entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
  3442     } else {
  3443         entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
  3444         entry->interceptKeyWakeupTime = now() + delay;
  3446     entry->release();
  3449 void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
  3450         CommandEntry* commandEntry) {
  3451     sp<Connection> connection = commandEntry->connection;
  3452     nsecs_t finishTime = commandEntry->eventTime;
  3453     uint32_t seq = commandEntry->seq;
  3454     bool handled = commandEntry->handled;
  3456     // Handle post-event policy actions.
  3457     DispatchEntry* dispatchEntry = connection->findWaitQueueEntry(seq);
  3458     if (dispatchEntry) {
  3459         nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
  3460         if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
  3461             String8 msg;
  3462             msg.appendFormat("Window '%s' spent %0.1fms processing the last input event: ",
  3463                     connection->getWindowName(), eventDuration * 0.000001f);
  3464             dispatchEntry->eventEntry->appendDescription(msg);
  3465             ALOGI("%s", msg.string());
  3468         bool restartEvent;
  3469         if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
  3470             KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
  3471             restartEvent = afterKeyEventLockedInterruptible(connection,
  3472                     dispatchEntry, keyEntry, handled);
  3473         } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
  3474             MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
  3475             restartEvent = afterMotionEventLockedInterruptible(connection,
  3476                     dispatchEntry, motionEntry, handled);
  3477         } else {
  3478             restartEvent = false;
  3481         // Dequeue the event and start the next cycle.
  3482         // Note that because the lock might have been released, it is possible that the
  3483         // contents of the wait queue to have been drained, so we need to double-check
  3484         // a few things.
  3485         if (dispatchEntry == connection->findWaitQueueEntry(seq)) {
  3486             connection->waitQueue.dequeue(dispatchEntry);
  3487             traceWaitQueueLengthLocked(connection);
  3488             if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
  3489                 connection->outboundQueue.enqueueAtHead(dispatchEntry);
  3490                 traceOutboundQueueLengthLocked(connection);
  3491             } else {
  3492                 releaseDispatchEntryLocked(dispatchEntry);
  3496         // Start the next dispatch cycle for this connection.
  3497         startDispatchCycleLocked(now(), connection);
  3501 bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
  3502         DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
  3503     if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
  3504         // Get the fallback key state.
  3505         // Clear it out after dispatching the UP.
  3506         int32_t originalKeyCode = keyEntry->keyCode;
  3507         int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
  3508         if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
  3509             connection->inputState.removeFallbackKey(originalKeyCode);
  3512         if (handled || !dispatchEntry->hasForegroundTarget()) {
  3513             // If the application handles the original key for which we previously
  3514             // generated a fallback or if the window is not a foreground window,
  3515             // then cancel the associated fallback key, if any.
  3516             if (fallbackKeyCode != -1) {
  3517                 // Dispatch the unhandled key to the policy with the cancel flag.
  3518 #if DEBUG_OUTBOUND_EVENT_DETAILS
  3519                 ALOGD("Unhandled key event: Asking policy to cancel fallback action.  "
  3520                         "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
  3521                         keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
  3522                         keyEntry->policyFlags);
  3523 #endif
  3524                 KeyEvent event;
  3525                 initializeKeyEvent(&event, keyEntry);
  3526                 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
  3528                 mLock.unlock();
  3530                 mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
  3531                         &event, keyEntry->policyFlags, &event);
  3533                 mLock.lock();
  3535                 // Cancel the fallback key.
  3536                 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
  3537                     CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
  3538                             "application handled the original non-fallback key "
  3539                             "or is no longer a foreground target, "
  3540                             "canceling previously dispatched fallback key");
  3541                     options.keyCode = fallbackKeyCode;
  3542                     synthesizeCancelationEventsForConnectionLocked(connection, options);
  3544                 connection->inputState.removeFallbackKey(originalKeyCode);
  3546         } else {
  3547             // If the application did not handle a non-fallback key, first check
  3548             // that we are in a good state to perform unhandled key event processing
  3549             // Then ask the policy what to do with it.
  3550             bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
  3551                     && keyEntry->repeatCount == 0;
  3552             if (fallbackKeyCode == -1 && !initialDown) {
  3553 #if DEBUG_OUTBOUND_EVENT_DETAILS
  3554                 ALOGD("Unhandled key event: Skipping unhandled key event processing "
  3555                         "since this is not an initial down.  "
  3556                         "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
  3557                         originalKeyCode, keyEntry->action, keyEntry->repeatCount,
  3558                         keyEntry->policyFlags);
  3559 #endif
  3560                 return false;
  3563             // Dispatch the unhandled key to the policy.
  3564 #if DEBUG_OUTBOUND_EVENT_DETAILS
  3565             ALOGD("Unhandled key event: Asking policy to perform fallback action.  "
  3566                     "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
  3567                     keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
  3568                     keyEntry->policyFlags);
  3569 #endif
  3570             KeyEvent event;
  3571             initializeKeyEvent(&event, keyEntry);
  3573             mLock.unlock();
  3575             bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
  3576                     &event, keyEntry->policyFlags, &event);
  3578             mLock.lock();
  3580             if (connection->status != Connection::STATUS_NORMAL) {
  3581                 connection->inputState.removeFallbackKey(originalKeyCode);
  3582                 return false;
  3585             // Latch the fallback keycode for this key on an initial down.
  3586             // The fallback keycode cannot change at any other point in the lifecycle.
  3587             if (initialDown) {
  3588                 if (fallback) {
  3589                     fallbackKeyCode = event.getKeyCode();
  3590                 } else {
  3591                     fallbackKeyCode = AKEYCODE_UNKNOWN;
  3593                 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
  3596             ALOG_ASSERT(fallbackKeyCode != -1);
  3598             // Cancel the fallback key if the policy decides not to send it anymore.
  3599             // We will continue to dispatch the key to the policy but we will no
  3600             // longer dispatch a fallback key to the application.
  3601             if (fallbackKeyCode != AKEYCODE_UNKNOWN
  3602                     && (!fallback || fallbackKeyCode != event.getKeyCode())) {
  3603 #if DEBUG_OUTBOUND_EVENT_DETAILS
  3604                 if (fallback) {
  3605                     ALOGD("Unhandled key event: Policy requested to send key %d"
  3606                             "as a fallback for %d, but on the DOWN it had requested "
  3607                             "to send %d instead.  Fallback canceled.",
  3608                             event.getKeyCode(), originalKeyCode, fallbackKeyCode);
  3609                 } else {
  3610                     ALOGD("Unhandled key event: Policy did not request fallback for %d, "
  3611                             "but on the DOWN it had requested to send %d.  "
  3612                             "Fallback canceled.",
  3613                             originalKeyCode, fallbackKeyCode);
  3615 #endif
  3617                 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
  3618                         "canceling fallback, policy no longer desires it");
  3619                 options.keyCode = fallbackKeyCode;
  3620                 synthesizeCancelationEventsForConnectionLocked(connection, options);
  3622                 fallback = false;
  3623                 fallbackKeyCode = AKEYCODE_UNKNOWN;
  3624                 if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
  3625                     connection->inputState.setFallbackKey(originalKeyCode,
  3626                             fallbackKeyCode);
  3630 #if DEBUG_OUTBOUND_EVENT_DETAILS
  3632                 String8 msg;
  3633                 const KeyedVector<int32_t, int32_t>& fallbackKeys =
  3634                         connection->inputState.getFallbackKeys();
  3635                 for (size_t i = 0; i < fallbackKeys.size(); i++) {
  3636                     msg.appendFormat(", %d->%d", fallbackKeys.keyAt(i),
  3637                             fallbackKeys.valueAt(i));
  3639                 ALOGD("Unhandled key event: %d currently tracked fallback keys%s.",
  3640                         fallbackKeys.size(), msg.string());
  3642 #endif
  3644             if (fallback) {
  3645                 // Restart the dispatch cycle using the fallback key.
  3646                 keyEntry->eventTime = event.getEventTime();
  3647                 keyEntry->deviceId = event.getDeviceId();
  3648                 keyEntry->source = event.getSource();
  3649                 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
  3650                 keyEntry->keyCode = fallbackKeyCode;
  3651                 keyEntry->scanCode = event.getScanCode();
  3652                 keyEntry->metaState = event.getMetaState();
  3653                 keyEntry->repeatCount = event.getRepeatCount();
  3654                 keyEntry->downTime = event.getDownTime();
  3655                 keyEntry->syntheticRepeat = false;
  3657 #if DEBUG_OUTBOUND_EVENT_DETAILS
  3658                 ALOGD("Unhandled key event: Dispatching fallback key.  "
  3659                         "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
  3660                         originalKeyCode, fallbackKeyCode, keyEntry->metaState);
  3661 #endif
  3662                 return true; // restart the event
  3663             } else {
  3664 #if DEBUG_OUTBOUND_EVENT_DETAILS
  3665                 ALOGD("Unhandled key event: No fallback key.");
  3666 #endif
  3670     return false;
  3673 bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
  3674         DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
  3675     return false;
  3678 void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
  3679     mLock.unlock();
  3681     mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
  3683     mLock.lock();
  3686 void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
  3687     event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
  3688             entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
  3689             entry->downTime, entry->eventTime);
  3692 void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
  3693         int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
  3694     // TODO Write some statistics about how long we spend waiting.
  3697 void InputDispatcher::traceInboundQueueLengthLocked() {
  3698 #ifdef HAVE_ANDROID_OS
  3699     if (ATRACE_ENABLED()) {
  3700         ATRACE_INT("iq", mInboundQueue.count());
  3702 #endif
  3705 void InputDispatcher::traceOutboundQueueLengthLocked(const sp<Connection>& connection) {
  3706 #ifdef HAVE_ANDROID_OS
  3707     if (ATRACE_ENABLED()) {
  3708         char counterName[40];
  3709         snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName());
  3710         ATRACE_INT(counterName, connection->outboundQueue.count());
  3712 #endif
  3715 void InputDispatcher::traceWaitQueueLengthLocked(const sp<Connection>& connection) {
  3716 #ifdef HAVE_ANDROID_OS
  3717     if (ATRACE_ENABLED()) {
  3718         char counterName[40];
  3719         snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName());
  3720         ATRACE_INT(counterName, connection->waitQueue.count());
  3722 #endif
  3725 void InputDispatcher::dump(String8& dump) {
  3726     AutoMutex _l(mLock);
  3728     dump.append("Input Dispatcher State:\n");
  3729     dumpDispatchStateLocked(dump);
  3731     if (!mLastANRState.isEmpty()) {
  3732         dump.append("\nInput Dispatcher State at time of last ANR:\n");
  3733         dump.append(mLastANRState);
  3737 void InputDispatcher::monitor() {
  3738     // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
  3739     mLock.lock();
  3740     mLooper->wake();
  3741     mDispatcherIsAliveCondition.wait(mLock);
  3742     mLock.unlock();
  3746 // --- InputDispatcher::Queue ---
  3748 template <typename T>
  3749 uint32_t InputDispatcher::Queue<T>::count() const {
  3750     uint32_t result = 0;
  3751     for (const T* entry = head; entry; entry = entry->next) {
  3752         result += 1;
  3754     return result;
  3758 // --- InputDispatcher::InjectionState ---
  3760 InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
  3761         refCount(1),
  3762         injectorPid(injectorPid), injectorUid(injectorUid),
  3763         injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
  3764         pendingForegroundDispatches(0) {
  3767 InputDispatcher::InjectionState::~InjectionState() {
  3770 void InputDispatcher::InjectionState::release() {
  3771     refCount -= 1;
  3772     if (refCount == 0) {
  3773         delete this;
  3774     } else {
  3775         ALOG_ASSERT(refCount > 0);
  3780 // --- InputDispatcher::EventEntry ---
  3782 InputDispatcher::EventEntry::EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags) :
  3783         refCount(1), type(type), eventTime(eventTime), policyFlags(policyFlags),
  3784         injectionState(NULL), dispatchInProgress(false) {
  3787 InputDispatcher::EventEntry::~EventEntry() {
  3788     releaseInjectionState();
  3791 void InputDispatcher::EventEntry::release() {
  3792     refCount -= 1;
  3793     if (refCount == 0) {
  3794         delete this;
  3795     } else {
  3796         ALOG_ASSERT(refCount > 0);
  3800 void InputDispatcher::EventEntry::releaseInjectionState() {
  3801     if (injectionState) {
  3802         injectionState->release();
  3803         injectionState = NULL;
  3808 // --- InputDispatcher::ConfigurationChangedEntry ---
  3810 InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(nsecs_t eventTime) :
  3811         EventEntry(TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
  3814 InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
  3817 void InputDispatcher::ConfigurationChangedEntry::appendDescription(String8& msg) const {
  3818     msg.append("ConfigurationChangedEvent()");
  3822 // --- InputDispatcher::DeviceResetEntry ---
  3824 InputDispatcher::DeviceResetEntry::DeviceResetEntry(nsecs_t eventTime, int32_t deviceId) :
  3825         EventEntry(TYPE_DEVICE_RESET, eventTime, 0),
  3826         deviceId(deviceId) {
  3829 InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
  3832 void InputDispatcher::DeviceResetEntry::appendDescription(String8& msg) const {
  3833     msg.appendFormat("DeviceResetEvent(deviceId=%d)", deviceId);
  3837 // --- InputDispatcher::KeyEntry ---
  3839 InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
  3840         int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
  3841         int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
  3842         int32_t repeatCount, nsecs_t downTime) :
  3843         EventEntry(TYPE_KEY, eventTime, policyFlags),
  3844         deviceId(deviceId), source(source), action(action), flags(flags),
  3845         keyCode(keyCode), scanCode(scanCode), metaState(metaState),
  3846         repeatCount(repeatCount), downTime(downTime),
  3847         syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
  3848         interceptKeyWakeupTime(0) {
  3851 InputDispatcher::KeyEntry::~KeyEntry() {
  3854 void InputDispatcher::KeyEntry::appendDescription(String8& msg) const {
  3855     msg.appendFormat("KeyEvent(action=%d, deviceId=%d, source=0x%08x)",
  3856             action, deviceId, source);
  3859 void InputDispatcher::KeyEntry::recycle() {
  3860     releaseInjectionState();
  3862     dispatchInProgress = false;
  3863     syntheticRepeat = false;
  3864     interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
  3865     interceptKeyWakeupTime = 0;
  3869 // --- InputDispatcher::MotionEntry ---
  3871 InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,
  3872         int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
  3873         int32_t metaState, int32_t buttonState,
  3874         int32_t edgeFlags, float xPrecision, float yPrecision,
  3875         nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
  3876         const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) :
  3877         EventEntry(TYPE_MOTION, eventTime, policyFlags),
  3878         eventTime(eventTime),
  3879         deviceId(deviceId), source(source), action(action), flags(flags),
  3880         metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
  3881         xPrecision(xPrecision), yPrecision(yPrecision),
  3882         downTime(downTime), displayId(displayId), pointerCount(pointerCount) {
  3883     for (uint32_t i = 0; i < pointerCount; i++) {
  3884         this->pointerProperties[i].copyFrom(pointerProperties[i]);
  3885         this->pointerCoords[i].copyFrom(pointerCoords[i]);
  3889 InputDispatcher::MotionEntry::~MotionEntry() {
  3892 void InputDispatcher::MotionEntry::appendDescription(String8& msg) const {
  3893     msg.appendFormat("MotionEvent(action=%d, deviceId=%d, source=0x%08x, displayId=%d)",
  3894             action, deviceId, source, displayId);
  3898 // --- InputDispatcher::DispatchEntry ---
  3900 volatile int32_t InputDispatcher::DispatchEntry::sNextSeqAtomic;
  3902 InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
  3903         int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) :
  3904         seq(nextSeq()),
  3905         eventEntry(eventEntry), targetFlags(targetFlags),
  3906         xOffset(xOffset), yOffset(yOffset), scaleFactor(scaleFactor),
  3907         deliveryTime(0), resolvedAction(0), resolvedFlags(0) {
  3908     eventEntry->refCount += 1;
  3911 InputDispatcher::DispatchEntry::~DispatchEntry() {
  3912     eventEntry->release();
  3915 uint32_t InputDispatcher::DispatchEntry::nextSeq() {
  3916     // Sequence number 0 is reserved and will never be returned.
  3917     uint32_t seq;
  3918     do {
  3919         seq = android_atomic_inc(&sNextSeqAtomic);
  3920     } while (!seq);
  3921     return seq;
  3925 // --- InputDispatcher::InputState ---
  3927 InputDispatcher::InputState::InputState() {
  3930 InputDispatcher::InputState::~InputState() {
  3933 bool InputDispatcher::InputState::isNeutral() const {
  3934     return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
  3937 bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
  3938         int32_t displayId) const {
  3939     for (size_t i = 0; i < mMotionMementos.size(); i++) {
  3940         const MotionMemento& memento = mMotionMementos.itemAt(i);
  3941         if (memento.deviceId == deviceId
  3942                 && memento.source == source
  3943                 && memento.displayId == displayId
  3944                 && memento.hovering) {
  3945             return true;
  3948     return false;
  3951 bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
  3952         int32_t action, int32_t flags) {
  3953     switch (action) {
  3954     case AKEY_EVENT_ACTION_UP: {
  3955         if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
  3956             for (size_t i = 0; i < mFallbackKeys.size(); ) {
  3957                 if (mFallbackKeys.valueAt(i) == entry->keyCode) {
  3958                     mFallbackKeys.removeItemsAt(i);
  3959                 } else {
  3960                     i += 1;
  3964         ssize_t index = findKeyMemento(entry);
  3965         if (index >= 0) {
  3966             mKeyMementos.removeAt(index);
  3967             return true;
  3969         /* FIXME: We can't just drop the key up event because that prevents creating
  3970          * popup windows that are automatically shown when a key is held and then
  3971          * dismissed when the key is released.  The problem is that the popup will
  3972          * not have received the original key down, so the key up will be considered
  3973          * to be inconsistent with its observed state.  We could perhaps handle this
  3974          * by synthesizing a key down but that will cause other problems.
  3976          * So for now, allow inconsistent key up events to be dispatched.
  3978 #if DEBUG_OUTBOUND_EVENT_DETAILS
  3979         ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
  3980                 "keyCode=%d, scanCode=%d",
  3981                 entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
  3982 #endif
  3983         return false;
  3984         */
  3985         return true;
  3988     case AKEY_EVENT_ACTION_DOWN: {
  3989         ssize_t index = findKeyMemento(entry);
  3990         if (index >= 0) {
  3991             mKeyMementos.removeAt(index);
  3993         addKeyMemento(entry, flags);
  3994         return true;
  3997     default:
  3998         return true;
  4002 bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
  4003         int32_t action, int32_t flags) {
  4004     int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
  4005     switch (actionMasked) {
  4006     case AMOTION_EVENT_ACTION_UP:
  4007     case AMOTION_EVENT_ACTION_CANCEL: {
  4008         ssize_t index = findMotionMemento(entry, false /*hovering*/);
  4009         if (index >= 0) {
  4010             mMotionMementos.removeAt(index);
  4011             return true;
  4013 #if DEBUG_OUTBOUND_EVENT_DETAILS
  4014         ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
  4015                 "actionMasked=%d",
  4016                 entry->deviceId, entry->source, actionMasked);
  4017 #endif
  4018         return false;
  4021     case AMOTION_EVENT_ACTION_DOWN: {
  4022         ssize_t index = findMotionMemento(entry, false /*hovering*/);
  4023         if (index >= 0) {
  4024             mMotionMementos.removeAt(index);
  4026         addMotionMemento(entry, flags, false /*hovering*/);
  4027         return true;
  4030     case AMOTION_EVENT_ACTION_POINTER_UP:
  4031     case AMOTION_EVENT_ACTION_POINTER_DOWN:
  4032     case AMOTION_EVENT_ACTION_MOVE: {
  4033         ssize_t index = findMotionMemento(entry, false /*hovering*/);
  4034         if (index >= 0) {
  4035             MotionMemento& memento = mMotionMementos.editItemAt(index);
  4036             memento.setPointers(entry);
  4037             return true;
  4039         if (actionMasked == AMOTION_EVENT_ACTION_MOVE
  4040                 && (entry->source & (AINPUT_SOURCE_CLASS_JOYSTICK
  4041                         | AINPUT_SOURCE_CLASS_NAVIGATION))) {
  4042             // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
  4043             return true;
  4045 #if DEBUG_OUTBOUND_EVENT_DETAILS
  4046         ALOGD("Dropping inconsistent motion pointer up/down or move event: "
  4047                 "deviceId=%d, source=%08x, actionMasked=%d",
  4048                 entry->deviceId, entry->source, actionMasked);
  4049 #endif
  4050         return false;
  4053     case AMOTION_EVENT_ACTION_HOVER_EXIT: {
  4054         ssize_t index = findMotionMemento(entry, true /*hovering*/);
  4055         if (index >= 0) {
  4056             mMotionMementos.removeAt(index);
  4057             return true;
  4059 #if DEBUG_OUTBOUND_EVENT_DETAILS
  4060         ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x",
  4061                 entry->deviceId, entry->source);
  4062 #endif
  4063         return false;
  4066     case AMOTION_EVENT_ACTION_HOVER_ENTER:
  4067     case AMOTION_EVENT_ACTION_HOVER_MOVE: {
  4068         ssize_t index = findMotionMemento(entry, true /*hovering*/);
  4069         if (index >= 0) {
  4070             mMotionMementos.removeAt(index);
  4072         addMotionMemento(entry, flags, true /*hovering*/);
  4073         return true;
  4076     default:
  4077         return true;
  4081 ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
  4082     for (size_t i = 0; i < mKeyMementos.size(); i++) {
  4083         const KeyMemento& memento = mKeyMementos.itemAt(i);
  4084         if (memento.deviceId == entry->deviceId
  4085                 && memento.source == entry->source
  4086                 && memento.keyCode == entry->keyCode
  4087                 && memento.scanCode == entry->scanCode) {
  4088             return i;
  4091     return -1;
  4094 ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
  4095         bool hovering) const {
  4096     for (size_t i = 0; i < mMotionMementos.size(); i++) {
  4097         const MotionMemento& memento = mMotionMementos.itemAt(i);
  4098         if (memento.deviceId == entry->deviceId
  4099                 && memento.source == entry->source
  4100                 && memento.displayId == entry->displayId
  4101                 && memento.hovering == hovering) {
  4102             return i;
  4105     return -1;
  4108 void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
  4109     mKeyMementos.push();
  4110     KeyMemento& memento = mKeyMementos.editTop();
  4111     memento.deviceId = entry->deviceId;
  4112     memento.source = entry->source;
  4113     memento.keyCode = entry->keyCode;
  4114     memento.scanCode = entry->scanCode;
  4115     memento.metaState = entry->metaState;
  4116     memento.flags = flags;
  4117     memento.downTime = entry->downTime;
  4118     memento.policyFlags = entry->policyFlags;
  4121 void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
  4122         int32_t flags, bool hovering) {
  4123     mMotionMementos.push();
  4124     MotionMemento& memento = mMotionMementos.editTop();
  4125     memento.deviceId = entry->deviceId;
  4126     memento.source = entry->source;
  4127     memento.flags = flags;
  4128     memento.xPrecision = entry->xPrecision;
  4129     memento.yPrecision = entry->yPrecision;
  4130     memento.downTime = entry->downTime;
  4131     memento.displayId = entry->displayId;
  4132     memento.setPointers(entry);
  4133     memento.hovering = hovering;
  4134     memento.policyFlags = entry->policyFlags;
  4137 void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
  4138     pointerCount = entry->pointerCount;
  4139     for (uint32_t i = 0; i < entry->pointerCount; i++) {
  4140         pointerProperties[i].copyFrom(entry->pointerProperties[i]);
  4141         pointerCoords[i].copyFrom(entry->pointerCoords[i]);
  4145 void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
  4146         Vector<EventEntry*>& outEvents, const CancelationOptions& options) {
  4147     for (size_t i = 0; i < mKeyMementos.size(); i++) {
  4148         const KeyMemento& memento = mKeyMementos.itemAt(i);
  4149         if (shouldCancelKey(memento, options)) {
  4150             outEvents.push(new KeyEntry(currentTime,
  4151                     memento.deviceId, memento.source, memento.policyFlags,
  4152                     AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
  4153                     memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
  4157     for (size_t i = 0; i < mMotionMementos.size(); i++) {
  4158         const MotionMemento& memento = mMotionMementos.itemAt(i);
  4159         if (shouldCancelMotion(memento, options)) {
  4160             outEvents.push(new MotionEntry(currentTime,
  4161                     memento.deviceId, memento.source, memento.policyFlags,
  4162                     memento.hovering
  4163                             ? AMOTION_EVENT_ACTION_HOVER_EXIT
  4164                             : AMOTION_EVENT_ACTION_CANCEL,
  4165                     memento.flags, 0, 0, 0,
  4166                     memento.xPrecision, memento.yPrecision, memento.downTime,
  4167                     memento.displayId,
  4168                     memento.pointerCount, memento.pointerProperties, memento.pointerCoords));
  4173 void InputDispatcher::InputState::clear() {
  4174     mKeyMementos.clear();
  4175     mMotionMementos.clear();
  4176     mFallbackKeys.clear();
  4179 void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
  4180     for (size_t i = 0; i < mMotionMementos.size(); i++) {
  4181         const MotionMemento& memento = mMotionMementos.itemAt(i);
  4182         if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
  4183             for (size_t j = 0; j < other.mMotionMementos.size(); ) {
  4184                 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
  4185                 if (memento.deviceId == otherMemento.deviceId
  4186                         && memento.source == otherMemento.source
  4187                         && memento.displayId == otherMemento.displayId) {
  4188                     other.mMotionMementos.removeAt(j);
  4189                 } else {
  4190                     j += 1;
  4193             other.mMotionMementos.push(memento);
  4198 int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
  4199     ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
  4200     return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
  4203 void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
  4204         int32_t fallbackKeyCode) {
  4205     ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
  4206     if (index >= 0) {
  4207         mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
  4208     } else {
  4209         mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
  4213 void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
  4214     mFallbackKeys.removeItem(originalKeyCode);
  4217 bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
  4218         const CancelationOptions& options) {
  4219     if (options.keyCode != -1 && memento.keyCode != options.keyCode) {
  4220         return false;
  4223     if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
  4224         return false;
  4227     switch (options.mode) {
  4228     case CancelationOptions::CANCEL_ALL_EVENTS:
  4229     case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
  4230         return true;
  4231     case CancelationOptions::CANCEL_FALLBACK_EVENTS:
  4232         return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
  4233     default:
  4234         return false;
  4238 bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
  4239         const CancelationOptions& options) {
  4240     if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
  4241         return false;
  4244     switch (options.mode) {
  4245     case CancelationOptions::CANCEL_ALL_EVENTS:
  4246         return true;
  4247     case CancelationOptions::CANCEL_POINTER_EVENTS:
  4248         return memento.source & AINPUT_SOURCE_CLASS_POINTER;
  4249     case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
  4250         return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
  4251     default:
  4252         return false;
  4257 // --- InputDispatcher::Connection ---
  4259 InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
  4260         const sp<InputWindowHandle>& inputWindowHandle, bool monitor) :
  4261         status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
  4262         monitor(monitor),
  4263         inputPublisher(inputChannel), inputPublisherBlocked(false) {
  4266 InputDispatcher::Connection::~Connection() {
  4269 const char* InputDispatcher::Connection::getWindowName() const {
  4270     if (inputWindowHandle != NULL) {
  4271         return inputWindowHandle->getName().string();
  4273     if (monitor) {
  4274         return "monitor";
  4276     return "?";
  4279 const char* InputDispatcher::Connection::getStatusLabel() const {
  4280     switch (status) {
  4281     case STATUS_NORMAL:
  4282         return "NORMAL";
  4284     case STATUS_BROKEN:
  4285         return "BROKEN";
  4287     case STATUS_ZOMBIE:
  4288         return "ZOMBIE";
  4290     default:
  4291         return "UNKNOWN";
  4295 InputDispatcher::DispatchEntry* InputDispatcher::Connection::findWaitQueueEntry(uint32_t seq) {
  4296     for (DispatchEntry* entry = waitQueue.head; entry != NULL; entry = entry->next) {
  4297         if (entry->seq == seq) {
  4298             return entry;
  4301     return NULL;
  4305 // --- InputDispatcher::CommandEntry ---
  4307 InputDispatcher::CommandEntry::CommandEntry(Command command) :
  4308     command(command), eventTime(0), keyEntry(NULL), userActivityEventType(0),
  4309     seq(0), handled(false) {
  4312 InputDispatcher::CommandEntry::~CommandEntry() {
  4316 // --- InputDispatcher::TouchState ---
  4318 InputDispatcher::TouchState::TouchState() :
  4319     down(false), split(false), deviceId(-1), source(0), displayId(-1) {
  4322 InputDispatcher::TouchState::~TouchState() {
  4325 void InputDispatcher::TouchState::reset() {
  4326     down = false;
  4327     split = false;
  4328     deviceId = -1;
  4329     source = 0;
  4330     displayId = -1;
  4331     windows.clear();
  4334 void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
  4335     down = other.down;
  4336     split = other.split;
  4337     deviceId = other.deviceId;
  4338     source = other.source;
  4339     displayId = other.displayId;
  4340     windows = other.windows;
  4343 void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
  4344         int32_t targetFlags, BitSet32 pointerIds) {
  4345     if (targetFlags & InputTarget::FLAG_SPLIT) {
  4346         split = true;
  4349     for (size_t i = 0; i < windows.size(); i++) {
  4350         TouchedWindow& touchedWindow = windows.editItemAt(i);
  4351         if (touchedWindow.windowHandle == windowHandle) {
  4352             touchedWindow.targetFlags |= targetFlags;
  4353             if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
  4354                 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
  4356             touchedWindow.pointerIds.value |= pointerIds.value;
  4357             return;
  4361     windows.push();
  4363     TouchedWindow& touchedWindow = windows.editTop();
  4364     touchedWindow.windowHandle = windowHandle;
  4365     touchedWindow.targetFlags = targetFlags;
  4366     touchedWindow.pointerIds = pointerIds;
  4369 void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
  4370     for (size_t i = 0; i < windows.size(); i++) {
  4371         if (windows.itemAt(i).windowHandle == windowHandle) {
  4372             windows.removeAt(i);
  4373             return;
  4378 void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
  4379     for (size_t i = 0 ; i < windows.size(); ) {
  4380         TouchedWindow& window = windows.editItemAt(i);
  4381         if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
  4382                 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
  4383             window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
  4384             window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
  4385             i += 1;
  4386         } else {
  4387             windows.removeAt(i);
  4392 sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
  4393     for (size_t i = 0; i < windows.size(); i++) {
  4394         const TouchedWindow& window = windows.itemAt(i);
  4395         if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
  4396             return window.windowHandle;
  4399     return NULL;
  4402 bool InputDispatcher::TouchState::isSlippery() const {
  4403     // Must have exactly one foreground window.
  4404     bool haveSlipperyForegroundWindow = false;
  4405     for (size_t i = 0; i < windows.size(); i++) {
  4406         const TouchedWindow& window = windows.itemAt(i);
  4407         if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
  4408             if (haveSlipperyForegroundWindow
  4409                     || !(window.windowHandle->getInfo()->layoutParamsFlags
  4410                             & InputWindowInfo::FLAG_SLIPPERY)) {
  4411                 return false;
  4413             haveSlipperyForegroundWindow = true;
  4416     return haveSlipperyForegroundWindow;
  4420 // --- InputDispatcherThread ---
  4422 InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
  4423         Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
  4426 InputDispatcherThread::~InputDispatcherThread() {
  4429 bool InputDispatcherThread::threadLoop() {
  4430     mDispatcher->dispatchOnce();
  4431     return true;
  4434 } // namespace android

mercurial