##启动服务
在系统启动时候,会启动多个服务,其中包括InputManagerService

inputManager = new InputManagerService(context);

看看InputManagerService构造方法

public InputManagerService(Context context) {        this.mContext = context;        this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());        ....        mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());  //mPtr是NativeInputManager的实例....}

构造方法中比较重要的是nativeInit,对应在com_android_server_input_InputManagerService.cpp中执行

static jlong nativeInit(JNIEnv* env, jclass /* clazz */,        jobject serviceObj, jobject contextObj, jobject messageQueueObj) {    sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);    if (messageQueue == NULL) {        jniThrowRuntimeException(env, "MessageQueue is not initialized.");        return 0;    }    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,            messageQueue->getLooper());    im->incStrong(0);    return reinterpret_cast(im);}

上述主要完成NativeInputManager初始化,并返回NativeInputManager实例对象,继续分析NativeInputManager构造函数,同样在com_android_server_input_InputManagerService.cpp文件中

NativeInputManager::NativeInputManager(jobject contextObj,        jobject serviceObj, const sp& looper) :        mLooper(looper), mInteractive(true) {    JNIEnv* env = jniEnv();    mContextObj = env->NewGlobalRef(contextObj);    mServiceObj = env->NewGlobalRef(serviceObj);    {        AutoMutex _l(mLock);        mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;        mLocked.pointerSpeed = 0;        mLocked.pointerGesturesEnabled = true;        mLocked.showTouches = false;        mLocked.pointerCapture = false;    }    mInteractive = true;    sp eventHub = new EventHub();  // A. 构造EventHub,EventHub用来监听/dev/input目录下文件节点的变化    mInputManager = new InputManager(eventHub, this, this);  // B. 构造InputManager对象}

上面分为两个主要步骤,A和B

##构造EventHub

static const char *DEVICE_PATH = "/dev/input";EventHub::EventHub(void) :        mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), mControllerNumbers(),        mOpeningDevices(0), mClosingDevices(0),        mNeedToSendFinishedDeviceScan(false),        mNeedToReopenDevices(false), mNeedToScanDevices(true),        mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) {    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);    mEpollFd = epoll_create(EPOLL_SIZE_HINT);   // ......    LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance.  errno=%d", errno);    mINotifyFd = inotify_init();  // ......    int result = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);   // ......    LOG_ALWAYS_FATAL_IF(result < 0, "Could not register INotify for %s.  errno=%d",            DEVICE_PATH, errno);    struct epoll_event eventItem;    memset(&eventItem, 0, sizeof(eventItem));    eventItem.events = EPOLLIN;    eventItem.data.u32 = EPOLL_ID_INOTIFY;    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);   // ......    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add INotify to epoll instance.  errno=%d", errno);    int wakeFds[2];    result = pipe(wakeFds);    LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe.  errno=%d", errno);    mWakeReadPipeFd = wakeFds[0];    mWakeWritePipeFd = wakeFds[1];    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking.  errno=%d",            errno);    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking.  errno=%d",            errno);    eventItem.data.u32 = EPOLL_ID_WAKE;    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance.  errno=%d",            errno);    int major, minor;    getLinuxRelease(&major, &minor);    // EPOLLWAKEUP was introduced in kernel 3.5    mUsingEpollWakeup = major > 3 || (major == 3 && minor >= 5);}

EventHub中有一个比较重要的方法,getEvents(),该方法会不断读取/dev/input目录下的文件节点的变化,如果没有发生变化,则该方法一直处于阻塞状态

size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {    ALOG_ASSERT(bufferSize >= 1);    AutoMutex _l(mLock);    struct input_event readBuffer[bufferSize];    RawEvent* event = buffer;    size_t capacity = bufferSize;    bool awoken = false;    for (;;) {        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);        // Reopen input devices if needed.        if (mNeedToReopenDevices) {            mNeedToReopenDevices = false;            ALOGI("Reopening all input devices due to a configuration change.");            closeAllDevicesLocked();            mNeedToScanDevices = true;            break; // return to the caller before we actually rescan        }        // Report any devices that had last been added/removed.        while (mClosingDevices) {            Device* device = mClosingDevices;            ALOGV("Reporting device closed: id=%d, name=%s\n",                 device->id, device->path.string());            mClosingDevices = device->next;            event->when = now;            event->deviceId = device->id == mBuiltInKeyboardId ? BUILT_IN_KEYBOARD_ID : device->id;            event->type = DEVICE_REMOVED;            event += 1;            delete device;            mNeedToSendFinishedDeviceScan = true;            if (--capacity == 0) {                break;            }        }        if (mNeedToScanDevices) {            mNeedToScanDevices = false;            scanDevicesLocked();            mNeedToSendFinishedDeviceScan = true;        }        while (mOpeningDevices != NULL) {            Device* device = mOpeningDevices;            ALOGV("Reporting device opened: id=%d, name=%s\n",                 device->id, device->path.string());            mOpeningDevices = device->next;            event->when = now;            event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;            event->type = DEVICE_ADDED;            event += 1;            mNeedToSendFinishedDeviceScan = true;            if (--capacity == 0) {                break;            }        }        if (mNeedToSendFinishedDeviceScan) {            mNeedToSendFinishedDeviceScan = false;            event->when = now;            event->type = FINISHED_DEVICE_SCAN;            event += 1;            if (--capacity == 0) {                break;            }        }        // Grab the next input event.        bool deviceChanged = false;        while (mPendingEventIndex < mPendingEventCount) {            const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++];            if (eventItem.data.u32 == EPOLL_ID_INOTIFY) {                if (eventItem.events & EPOLLIN) {                    mPendingINotify = true;                } else {                    ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events);                }                continue;            }            if (eventItem.data.u32 == EPOLL_ID_WAKE) {                if (eventItem.events & EPOLLIN) {                    ALOGV("awoken after wake()");                    awoken = true;                    char buffer[16];                    ssize_t nRead;                    do {                        nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));                    } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));                } else {                    ALOGW("Received unexpected epoll event 0x%08x for wake read pipe.",                            eventItem.events);                }                continue;            }            ssize_t deviceIndex = mDevices.indexOfKey(eventItem.data.u32);            if (deviceIndex < 0) {                ALOGW("Received unexpected epoll event 0x%08x for unknown device id %d.",                        eventItem.events, eventItem.data.u32);                continue;            }            Device* device = mDevices.valueAt(deviceIndex);            if (eventItem.events & EPOLLIN) {                int32_t readSize = read(device->fd, readBuffer,                        sizeof(struct input_event) * capacity);     //.........                if (readSize == 0 || (readSize < 0 && errno == ENODEV)) {                    // Device was removed before INotify noticed.                    ALOGW("could not get event, removed? (fd: %d size: %" PRId32                            " bufferSize: %zu capacity: %zu errno: %d)\n",                            device->fd, readSize, bufferSize, capacity, errno);                    deviceChanged = true;                    closeDeviceLocked(device);                } else if (readSize < 0) {                    if (errno != EAGAIN && errno != EINTR) {                        ALOGW("could not get event (errno=%d)", errno);                    }                } else if ((readSize % sizeof(struct input_event)) != 0) {                    ALOGE("could not get event (wrong size: %d)", readSize);                } else {                    int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;                    size_t count = size_t(readSize) / sizeof(struct input_event);                    for (size_t i = 0; i < count; i++) {                        struct input_event& iev = readBuffer[i];                        ALOGV("%s got: time=%d.%06d, type=%d, code=%d, value=%d",                                device->path.string(),                                (int) iev.time.tv_sec, (int) iev.time.tv_usec,                                iev.type, iev.code, iev.value);                        // Some input devices may have a better concept of the time                        // when an input event was actually generated than the kernel                        // which simply timestamps all events on entry to evdev.                        // This is a custom Android extension of the input protocol                        // mainly intended for use with uinput based device drivers.                        if (iev.type == EV_MSC) {                            if (iev.code == MSC_ANDROID_TIME_SEC) {                                device->timestampOverrideSec = iev.value;                                continue;                            } else if (iev.code == MSC_ANDROID_TIME_USEC) {                                device->timestampOverrideUsec = iev.value;                                continue;                            }                        }                        if (device->timestampOverrideSec || device->timestampOverrideUsec) {                            iev.time.tv_sec = device->timestampOverrideSec;                            iev.time.tv_usec = device->timestampOverrideUsec;                            if (iev.type == EV_SYN && iev.code == SYN_REPORT) {                                device->timestampOverrideSec = 0;                                device->timestampOverrideUsec = 0;                            }                            ALOGV("applied override time %d.%06d",                                    int(iev.time.tv_sec), int(iev.time.tv_usec));                        }                        // Use the time specified in the event instead of the current time                        // so that downstream code can get more accurate estimates of                        // event dispatch latency from the time the event is enqueued onto                        // the evdev client buffer.                        //                        // The event's timestamp fortuitously uses the same monotonic clock                        // time base as the rest of Android.  The kernel event device driver                        // (drivers/input/evdev.c) obtains timestamps using ktime_get_ts().                        // The systemTime(SYSTEM_TIME_MONOTONIC) function we use everywhere                        // calls clock_gettime(CLOCK_MONOTONIC) which is implemented as a                        // system call that also queries ktime_get_ts().                        event->when = nsecs_t(iev.time.tv_sec) * 1000000000LL                                + nsecs_t(iev.time.tv_usec) * 1000LL;                        ALOGV("event time %" PRId64 ", now %" PRId64, event->when, now);                        // Bug 7291243: Add a guard in case the kernel generates timestamps                        // that appear to be far into the future because they were generated                        // using the wrong clock source.                        //                        // This can happen because when the input device is initially opened                        // it has a default clock source of CLOCK_REALTIME.  Any input events                        // enqueued right after the device is opened will have timestamps                        // generated using CLOCK_REALTIME.  We later set the clock source                        // to CLOCK_MONOTONIC but it is already too late.                        //                        // Invalid input event timestamps can result in ANRs, crashes and                        // and other issues that are hard to track down.  We must not let them                        // propagate through the system.                        //                        // Log a warning so that we notice the problem and recover gracefully.                        if (event->when >= now + 10 * 1000000000LL) {                            // Double-check.  Time may have moved on.                            nsecs_t time = systemTime(SYSTEM_TIME_MONOTONIC);                            if (event->when > time) {                                ALOGW("An input event from %s has a timestamp that appears to "                                        "have been generated using the wrong clock source "                                        "(expected CLOCK_MONOTONIC): "                                        "event time %" PRId64 ", current time %" PRId64                                        ", call time %" PRId64 ".  "                                        "Using current time instead.",                                        device->path.string(), event->when, time, now);                                event->when = time;                            } else {                                ALOGV("Event time is ok but failed the fast path and required "                                        "an extra call to systemTime: "                                        "event time %" PRId64 ", current time %" PRId64                                        ", call time %" PRId64 ".",                                        event->when, time, now);                            }                        }//.........                        event->deviceId = deviceId;                        event->type = iev.type;                        event->code = iev.code;                        event->value = iev.value;                        event += 1;                        capacity -= 1;                    }                    if (capacity == 0) {                        // The result buffer is full.  Reset the pending event index                        // so we will try to read the device again on the next iteration.                        mPendingEventIndex -= 1;                        break;                    }                }            } else if (eventItem.events & EPOLLHUP) {                ALOGI("Removing device %s due to epoll hang-up event.",                        device->identifier.name.string());                deviceChanged = true;                closeDeviceLocked(device);            } else {                ALOGW("Received unexpected epoll event 0x%08x for device %s.",                        eventItem.events, device->identifier.name.string());            }        }        // readNotify() will modify the list of devices so this must be done after        // processing all other events to ensure that we read all remaining events        // before closing the devices.        if (mPendingINotify && mPendingEventIndex >= mPendingEventCount) {            mPendingINotify = false;            readNotifyLocked();  //.........            deviceChanged = true;        }        // Report added or removed devices immediately.        if (deviceChanged) {            continue;        }        // Return now if we have collected any events or if we were explicitly awoken.        if (event != buffer || awoken) {            break;        }        // Poll for events.  Mind the wake lock dance!        // We hold a wake lock at all times except during epoll_wait().  This works due to some        // subtle choreography.  When a device driver has pending (unread) events, it acquires        // a kernel wake lock.  However, once the last pending event has been read, the device        // driver will release the kernel wake lock.  To prevent the system from going to sleep        // when this happens, the EventHub holds onto its own user wake lock while the client        // is processing events.  Thus the system can only sleep if there are no events        // pending or currently being processed.        //        // The timeout is advisory only.  If the device is asleep, it will not wake just to        // service the timeout.        mPendingEventIndex = 0;        mLock.unlock(); // release lock before poll, must be before release_wake_lock        release_wake_lock(WAKE_LOCK_ID);        int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis);   // 将会一直处于阻塞状态,直到/dev/input目录下有节点发生变化        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);        mLock.lock(); // reacquire lock after poll, must be after acquire_wake_lock        if (pollResult == 0) {            // Timed out.            mPendingEventCount = 0;            break;        }        if (pollResult < 0) {            // An error occurred.            mPendingEventCount = 0;            // Sleep after errors to avoid locking up the system.            // Hopefully the error is transient.            if (errno != EINTR) {                ALOGW("poll failed (errno=%d)\n", errno);                usleep(100000);            }        } else {            // Some events occurred.            mPendingEventCount = size_t(pollResult);        }    }    // All done, return the number of events we read.    return event - buffer;}

##InputReader和InputDispatcher读取和分发
InputReader类负责从上述EventHub的getEvent读取节点变化,并由InputDispatcher分发给上层,这里主要涉及到以下几个类:
InputDispatcher
InputReader
InputDispatcherThread
InputReaderThread
InputListener

###InputReader和InputDispatcher的启动
继续回到 InputManager.cpp 的构造方法

InputManager::InputManager(        const sp& eventHub,        const sp& readerPolicy,        const sp& dispatcherPolicy) {    mDispatcher = new InputDispatcher(dispatcherPolicy);    mReader = new InputReader(eventHub, readerPolicy, mDispatcher);    initialize();}void InputManager::initialize() {    mReaderThread = new InputReaderThread(mReader);    mDispatcherThread = new InputDispatcherThread(mDispatcher);}

上述初始化完成之后,回到SystemServer,此时程序会一直往下走

inputManager.setWindowManagerCallbacks(wm.getInputMonitor());inputManager.start();public void start() {        Slog.i(TAG, "Starting input manager");        nativeStart(mPtr);  // 上述构造方法中,已经直到mPtr是NativeInputManager的实例    ....}

上述nativeStart是com_android_server_input_InputManagerService.cpp中方法

static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {    NativeInputManager* im = reinterpret_cast(ptr);    status_t result = im->getInputManager()->start();   // InputManager.cpp start方法    if (result) {        jniThrowRuntimeException(env, "Input manager could not be started.");    }}

InputManager.cpp#start

status_t InputManager::start() {    status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);    if (result) {        ALOGE("Could not start InputDispatcher thread due to error %d.", result);        return result;    }    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);    if (result) {        ALOGE("Could not start InputReader thread due to error %d.", result);        mDispatcherThread->requestExit();        return result;    }    return OK;}

上述mDispatcherThread->run和mReaderThread->run会分别执行对应的threadLoop方法,这里涉及到android中的threadLoop知识点,后续做详细介绍
InputReader.cpp

bool InputReaderThread::threadLoop() {    mReader->loopOnce();    return true;}

loopOnce

void InputReader::loopOnce() {    int32_t oldGeneration;    int32_t timeoutMillis;    bool inputDevicesChanged = false;    Vector inputDevices;    { // acquire lock        AutoMutex _l(mLock);        oldGeneration = mGeneration;        timeoutMillis = -1;        uint32_t changes = mConfigurationChangesToRefresh;        if (changes) {            mConfigurationChangesToRefresh = 0;            timeoutMillis = 0;            refreshConfigurationLocked(changes);        } else if (mNextTimeout != LLONG_MAX) {            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);            timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);        }    } // release lock    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);   // getEvent获取节点的变化    { // acquire lock        AutoMutex _l(mLock);        mReaderIsAliveCondition.broadcast();        if (count) {            processEventsLocked(mEventBuffer, count);   // 到这里        }        if (mNextTimeout != LLONG_MAX) {            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);            if (now >= mNextTimeout) {#if DEBUG_RAW_EVENTS                ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);#endif                mNextTimeout = LLONG_MAX;                timeoutExpiredLocked(now);            }        }        if (oldGeneration != mGeneration) {            inputDevicesChanged = true;            getInputDevicesLocked(inputDevices);        }    } // release lock    // Send out a message that the describes the changed input devices.    if (inputDevicesChanged) {        mPolicy->notifyInputDevicesChanged(inputDevices);    }    // Flush queued events out to the listener.    // This must happen outside of the lock because the listener could potentially call    // back into the InputReader's methods, such as getScanCodeState, or become blocked    // on another thread similarly waiting to acquire the InputReader lock thereby    // resulting in a deadlock.  This situation is actually quite plausible because the    // listener is actually the input dispatcher, which calls into the window manager,    // which occasionally calls into the input reader.    mQueuedListener->flush();}

processEventsLocked

void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {    for (const RawEvent* rawEvent = rawEvents; count;) {        int32_t type = rawEvent->type;        size_t batchSize = 1;        if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {            int32_t deviceId = rawEvent->deviceId;            while (batchSize < count) {                if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT                        || rawEvent[batchSize].deviceId != deviceId) {                    break;                }                batchSize += 1;            }#if DEBUG_RAW_EVENTS            ALOGD("BatchSize: %d Count: %d", batchSize, count);#endif            processEventsForDeviceLocked(deviceId, rawEvent, batchSize);   // 到这里        } else {            switch (rawEvent->type) {            case EventHubInterface::DEVICE_ADDED:                addDeviceLocked(rawEvent->when, rawEvent->deviceId);  // 增加节点                break;            case EventHubInterface::DEVICE_REMOVED:                removeDeviceLocked(rawEvent->when, rawEvent->deviceId);  // 删除节点                break;            case EventHubInterface::FINISHED_DEVICE_SCAN:                handleConfigurationChangedLocked(rawEvent->when);  // 节点发生变化                break;            default:                ALOG_ASSERT(false); // can't happen                break;            }        }        count -= batchSize;        rawEvent += batchSize;    }}

processEventsForDeviceLocked

void InputReader::processEventsForDeviceLocked(int32_t deviceId,        const RawEvent* rawEvents, size_t count) {    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);    if (deviceIndex < 0) {        ALOGW("Discarding event for unknown deviceId %d.", deviceId);        return;    }    InputDevice* device = mDevices.valueAt(deviceIndex);    if (device->isIgnored()) {        //ALOGD("Discarding event for ignored deviceId %d.", deviceId);        return;    }    device->process(rawEvents, count);  // 到这里

InputDevice#process

void InputDevice::process(const RawEvent* rawEvents, size_t count) {    // Process all of the events in order for each mapper.    // We cannot simply ask each mapper to process them in bulk because mappers may    // have side-effects that must be interleaved.  For example, joystick movement events and    // gamepad button presses are handled by different mappers but they should be dispatched    // in the order received.    size_t numMappers = mMappers.size();    for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {#if DEBUG_RAW_EVENTS        ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%lld",                rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,                rawEvent->when);#endif        if (mDropUntilNextSync) {            if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {                mDropUntilNextSync = false;#if DEBUG_RAW_EVENTS                ALOGD("Recovered from input event buffer overrun.");#endif            } else {#if DEBUG_RAW_EVENTS                ALOGD("Dropped input event while waiting for next input sync.");#endif            }        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {            ALOGI("Detected input event buffer overrun for device %s.", getName().string());            mDropUntilNextSync = true;            reset(rawEvent->when);        } else {            for (size_t i = 0; i < numMappers; i++) {                InputMapper* mapper = mMappers[i];                mapper->process(rawEvent);   // 到这里            }        }        --count;    }}InputMapper根据具体的按键类型,会调用不同的InputMapper ,比如:SwitchInputMapper耳机拔插的switch类型,KeyboardInputMapper物理按键,电源键,音量键等void KeyboardInputMapper::process(const RawEvent* rawEvent) {    switch (rawEvent->type) {    case EV_KEY: {        int32_t scanCode = rawEvent->code;        int32_t usageCode = mCurrentHidUsage;        mCurrentHidUsage = 0;        if (isKeyboardOrGamepadKey(scanCode)) {            processKey(rawEvent->when, rawEvent->value != 0, scanCode, usageCode);   // 到这里,调用到processKey        }        break;    }    case EV_MSC: {        if (rawEvent->code == MSC_SCAN) {            mCurrentHidUsage = rawEvent->value;        }        break;    }    case EV_SYN: {        if (rawEvent->code == SYN_REPORT) {            mCurrentHidUsage = 0;        }    }    }}
void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t scanCode,        int32_t usageCode) {    int32_t keyCode;    int32_t keyMetaState;    uint32_t policyFlags;    if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, mMetaState,                              &keyCode, &keyMetaState, &policyFlags)) {        keyCode = AKEYCODE_UNKNOWN;        keyMetaState = mMetaState;        policyFlags = 0;    }    if (down) {        // Rotate key codes according to orientation if needed.        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {            keyCode = rotateKeyCode(keyCode, mOrientation);        }        // Add key down.        ssize_t keyDownIndex = findKeyDown(scanCode);        if (keyDownIndex >= 0) {            // key repeat, be sure to use same keycode as before in case of rotation            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;        } else {            // key down            if ((policyFlags & POLICY_FLAG_VIRTUAL)                    && mContext->shouldDropVirtualKey(when,                            getDevice(), keyCode, scanCode)) {                return;            }            if (policyFlags & POLICY_FLAG_GESTURE) {                mDevice->cancelTouch(when);            }            mKeyDowns.push();            KeyDown& keyDown = mKeyDowns.editTop();            keyDown.keyCode = keyCode;            keyDown.scanCode = scanCode;        }        mDownTime = when;    } else {        // Remove key down.        ssize_t keyDownIndex = findKeyDown(scanCode);        if (keyDownIndex >= 0) {            // key up, be sure to use same keycode as before in case of rotation            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;            mKeyDowns.removeAt(size_t(keyDownIndex));        } else {            // key was not actually down            ALOGI("Dropping key up from device %s because the key was not down.  "                    "keyCode=%d, scanCode=%d",                    getDeviceName().string(), keyCode, scanCode);            return;        }    }    if (updateMetaStateIfNeeded(keyCode, down)) {        // If global meta state changed send it along with the key.        // If it has not changed then we'll use what keymap gave us,        // since key replacement logic might temporarily reset a few        // meta bits for given key.        keyMetaState = mMetaState;    }    nsecs_t downTime = mDownTime;    // Key down on external an keyboard should wake the device.    // We don't do this for internal keyboards to prevent them from waking up in your pocket.    // For internal keyboards, the key layout file should specify the policy flags for    // each wake key individually.    // TODO: Use the input device configuration to control this behavior more finely.    if (down && getDevice()->isExternal() && !isMediaKey(keyCode)) {        policyFlags |= POLICY_FLAG_WAKE;    }    if (mParameters.handlesKeyRepeat) {        policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;    }    NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,            AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState, downTime);    getListener()->notifyKey(&args);  //最终将获取到的事件传递到getListener()->notifyKey方法中}

上面getListener()会返回InputListener.cpp类型对象,所以就到了InputListener.cpp#notifyKey方法中

void QueuedInputListener::notifyKey(const NotifyKeyArgs* args) {
mArgsQueue.push(new NotifyKeyArgs(*args));
}

可以看到,最终只是添加到了mArgsQueue集合中
Vector mArgsQueue;

mQueuedListener->flush();  这个就会将mArgsQueue集合中保存的事件传递给InputDispatcher.cpp中InputListener.cpp#flushvoid QueuedInputListener::flush() {    size_t count = mArgsQueue.size();    for (size_t i = 0; i < count; i++) {        NotifyArgs* args = mArgsQueue[i];        args->notify(mInnerListener);        delete args;    }    mArgsQueue.clear();}
void NotifyKeyArgs::notify(const sp& listener) const {    listener->notifyKey(this);}

这里的listener是什么? 重新看下InputReader.cpp的构造函数

InputReader::InputReader(const sp& eventHub,        const sp& policy,        const sp& listener) :        mContext(this), mEventHub(eventHub), mPolicy(policy),        mGlobalMetaState(0), mGeneration(1),        mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),        mConfigurationChangesToRefresh(0) {    mQueuedListener = new QueuedInputListener(listener);    { // acquire lock        AutoMutex _l(mLock);        refreshConfigurationLocked(0);        updateGlobalMetaStateLocked();    } // release lock}

上述构造InputReader是在InputManager.cpp中构造的

InputManager::InputManager(        const sp& eventHub,        const sp& readerPolicy,        const sp& dispatcherPolicy) {    mDispatcher = new InputDispatcher(dispatcherPolicy);    mReader = new InputReader(eventHub, readerPolicy, mDispatcher);    initialize();}

所以上述listener就是InputDispatcher.cpp实例对象

回到InputDispatcher.cpp中

void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {#if DEBUG_INBOUND_EVENT_DETAILS    ALOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "            "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",            args->eventTime, args->deviceId, args->source, args->policyFlags,            args->action, args->flags, args->keyCode, args->scanCode,            args->metaState, args->downTime);#endif    if (!validateKeyEvent(args->action)) {        return;    }    uint32_t policyFlags = args->policyFlags;    int32_t flags = args->flags;    int32_t metaState = args->metaState;    if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {        policyFlags |= POLICY_FLAG_VIRTUAL;        flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;    }    if (policyFlags & POLICY_FLAG_FUNCTION) {        metaState |= AMETA_FUNCTION_ON;    }    policyFlags |= POLICY_FLAG_TRUSTED;    int32_t keyCode = args->keyCode;    if (metaState & AMETA_META_ON && args->action == AKEY_EVENT_ACTION_DOWN) {        int32_t newKeyCode = AKEYCODE_UNKNOWN;        if (keyCode == AKEYCODE_DEL) {            newKeyCode = AKEYCODE_BACK;        } else if (keyCode == AKEYCODE_ENTER) {            newKeyCode = AKEYCODE_HOME;        }        if (newKeyCode != AKEYCODE_UNKNOWN) {            AutoMutex _l(mLock);            struct KeyReplacement replacement = {keyCode, args->deviceId};            mReplacedKeys.add(replacement, newKeyCode);            keyCode = newKeyCode;            metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);        }    } else if (args->action == AKEY_EVENT_ACTION_UP) {        // In order to maintain a consistent stream of up and down events, check to see if the key        // going up is one we've replaced in a down event and haven't yet replaced in an up event,        // even if the modifier was released between the down and the up events.        AutoMutex _l(mLock);        struct KeyReplacement replacement = {keyCode, args->deviceId};        ssize_t index = mReplacedKeys.indexOfKey(replacement);        if (index >= 0) {            keyCode = mReplacedKeys.valueAt(index);            mReplacedKeys.removeItemsAt(index);            metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);        }    }    KeyEvent event;    event.initialize(args->deviceId, args->source, args->action,            flags, keyCode, args->scanCode, metaState, 0,            args->downTime, args->eventTime);    mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);   // 此处会回调到InputMonitor中    bool needWake;    { // acquire lock        mLock.lock();        if (shouldSendKeyToInputFilterLocked(args)) {            mLock.unlock();            policyFlags |= POLICY_FLAG_FILTERED;            if (!mPolicy->filterInputEvent(&event, policyFlags)) {                return; // event was consumed by the filter            }            mLock.lock();        }        int32_t repeatCount = 0;        KeyEntry* newEntry = new KeyEntry(args->eventTime,                args->deviceId, args->source, policyFlags,                args->action, flags, keyCode, args->scanCode,                metaState, repeatCount, args->downTime);        needWake = enqueueInboundEventLocked(newEntry);        mLock.unlock();    } // release lock    if (needWake) {        mLooper->wake();    }}

InputMonitor#interceptKeyBeforeQueueing

@Override    public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {        return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags);    }

这里就到了PhoneWindowManager#interceptKeyBeforeQueueing中

专注技术分享,包括Java,python,AI人工智能,Android分享,不定期更新学习视频,欢迎关注

更多相关文章

  1. Android使用SDK方法详解
  2. Android 发送普通的post请求的方法
  3. android之通过URL来获取网络资源并下载资源简单实例
  4. 实例:在Android调用WCF服务
  5. Android中View绘制流程以及invalidate()等相关方法分析
  6. Android 获取Gmail邮箱地址方法
  7. ubuntu的android studio调试小米手机的方法
  8. android 布局之滑动探究 scrollTo 和 scrollBy 方法使用说明
  9. Android 自定义view 和 onMeasure方法介绍

随机推荐

  1. Android开发常用透明度alpha百分比转16进
  2. Android2.1读取进程流量
  3. Android(安卓)中LayoutInflater的使用
  4. Android(安卓)Room 框架学习
  5. 【Android】ImageButton的记录
  6. android-对话式聊天效果实现
  7. 关于android中alarm的使用
  8. Android(安卓)适配Q版本Beta2
  9. Android两行代码搞定ViewPager的过渡动画
  10. android P系统访问http请求最简单解决方