美文网首页
Android中Input事件初始化、接收以及分发

Android中Input事件初始化、接收以及分发

作者: None_Ling | 来源:发表于2020-09-21 15:58 被阅读0次

    简述

    Input子系统中主要分为三个步骤 :

    • 初始化监听
    • 接收Input事件
    • 分发Input事件给Focus窗口

    初始化监听

    1. system_server初始化InputManagerService
    • 通过DisplayThreadLooper初始化InputManagerHandler
    • 调用nativeInit初始化Native层的InputManager
    public InputManagerService(Context context) {
            this.mContext = context;
            //  通过`DisplayThread`的`Looper`初始化`InputManagerHandler `
            this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
            ...
            // 调用`nativeInit`初始化Native层的`InputManager`
            mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
            ...
            //  将InputManager加到Servicemanager中
            LocalServices.addService(InputManagerInternal.class, new LocalService());
        }
    
    1. 调用nativeInit
    • 从DisplayThread中获取MessageQueue
    • 创建NativeInputManager对象
    • 初始化EventHub对象 , 用来监听/dev/input对应事件的
    • 初始化InputManager对象
    static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
            jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
        // 从DisplayThread中获取MessageQueue
        sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
        ...
        // 创建NativeInputManager对象
        NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
                messageQueue->getLooper());
        im->incStrong(0);
        return reinterpret_cast<jlong>(im);
    }
    
    NativeInputManager::NativeInputManager(jobject contextObj,
            jobject serviceObj, const sp<Looper>& looper) :
            mLooper(looper), mInteractive(true) {
        ...
        // 初始化EventHub对象
        sp<EventHub> eventHub = new EventHub();
        // 创建Native层的InputManager对象
        mInputManager = new InputManager(eventHub, this, this);
    }
    
    1. EventHub的初始化 , 用来监听/dev/input设备文件的事件
    • 通过epoll_create创建一个文件描述符用于监听事件
    • 通过inotify_init初始化文件监听的FD
    • 通过inotify_add_watch监听/dev/input/目录下文件的增加与删除
    • 通过epoll_ctrl监听INofity FD的读取
    • 通过fcntl设置Pipe为非阻塞读写
    • 通过epoll_ctrl监听Pipe文件的读取
    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) {
        // 通过epoll_create创建tmpfs的文件 , 用于监听文件
        // EPOLL_SIZE_HINT为8 , 代表最多监听8个设备文件
        mEpollFd = epoll_create(EPOLL_SIZE_HINT);
        LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance.  errno=%d", errno);
        // 通过inotify_init初始化文件变化的FD
        mINotifyFd = inotify_init();
        // 通过inotify_add_watch监听/dev/input目录下的创建与删除
        int result = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
        // 创建要监听的epoll事件
        struct epoll_event eventItem;
        memset(&eventItem, 0, sizeof(eventItem));
        eventItem.events = EPOLLIN;
        // 监听文件变化
        eventItem.data.u32 = EPOLL_ID_INOTIFY;
        // 通过epoll来监听/dev/input文件事件变化
        result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);
        // 创建一个pipe管道
        int wakeFds[2];
        result = pipe(wakeFds);
        // 得到readPipe
        mWakeReadPipeFd = wakeFds[0];
        // 得到writePipe
        mWakeWritePipeFd = wakeFds[1];
        // 通过fcntl设置readPipe不阻塞
        result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
       // 通过fcntl设置writePipe不阻塞
        result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
        eventItem.data.u32 = EPOLL_ID_WAKE;
        // 通过`epoll_ctl`监听readPipe文件
        result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);
         ... 
    }
    
    1. 初始化InputManager
    • 初始化InputDispathcer进行事件分发
    • 初始化InputReader/dev/input设备文件中通过epoll_wait来等待事件到来
    • 初始化InputReaderThread线程
    • 初始化InputRDispatcherThread线程
    InputManager::InputManager(
            const sp<EventHubInterface>& eventHub,
            const sp<InputReaderPolicyInterface>& readerPolicy,
            const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
        // 初始化`InputDispathcer`进行事件分发,内部会初始化一个Looper用于子线程
        mDispatcher = new InputDispatcher(dispatcherPolicy);
        // 初始化`InputReader`从`/dev/input`设备文件中通过`epoll_wait`来等待事件到来
        mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
        initialize();
    }
    
    void InputManager::initialize() {
        // 初始化`InputReaderThread`线程
        mReaderThread = new InputReaderThread(mReader);
        // 初始化`InputRDispatcherThread`线程
        mDispatcherThread = new InputDispatcherThread(mDispatcher);
    }
    
    1. InputReader的构造函数
    InputReader::InputReader(const sp<EventHubInterface>& eventHub,
            const sp<InputReaderPolicyInterface>& policy,
            const sp<InputListenerInterface>& 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);
            // 会从InputManagerService中读取配置参数 , 例如单击的超时事件、双击的超时事件等等
            refreshConfigurationLocked(0);
            updateGlobalMetaStateLocked();
        } // release lock
    }
    
    1. 在SystemServer启动的时候会调用InputManagerstart开启子线程读取
    SystemServer{
            public startOtherServices(){
                ...
                traceBeginAndSlog("StartInputManagerService");
                inputManager = new InputManagerService(context);
                traceEnd();
                ... 
                traceBeginAndSlog("StartInputManager");
                inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
                inputManager.start();
                traceEnd();
                ...
          }
    }
    
    1. start()函数中最重要的就是nativeStart , 其余都是在注册和更新Settings中的值
    public void start() {
            Slog.i(TAG, "Starting input manager");
            // 调用native方法
            nativeStart(mPtr);
            // Add ourself to the Watchdog monitors.
            Watchdog.getInstance().addMonitor(this);
            registerPointerSpeedSettingObserver();
            registerShowTouchesSettingObserver();
            registerAccessibilityLargePointerSettingObserver();
    
            mContext.registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    updatePointerSpeedFromSettings();
                    updateShowTouchesFromSettings();
                    updateAccessibilityLargePointerFromSettings();
                }
            }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
    
            updatePointerSpeedFromSettings();
            updateShowTouchesFromSettings();
            updateAccessibilityLargePointerFromSettings();
        }
    

    8.在InputManager.cpp中 , 找到start函数

    • 启动DispatcherThread
    • 启动ReaderThread
    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;
    }
    

    至此 , InputManager完成初始化. 接下来就等待/dev/input中添加设备文件.

    接收Input事件

    1. InputReaderThread启动后 , 会在threadLoop中通过loopOnce获取事件
    • EventHub中获取PendingEvents
    • 通过processEventsLockedmEventBuffer中开始处理事件
    • 如果设备有更新 , 则更新设备信息
    void InputReader::loopOnce() {
        ...
        // 通过EventHub获取Events , 将Event放到mEventBuffer中
        size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
    
        { // acquire lock
            AutoMutex _l(mLock);
            mReaderIsAliveCondition.broadcast();
            // 如果count >0 , 则调用processEventsLocked开始处理Events
            if (count) {
                processEventsLocked(mEventBuffer, count);
            }
            ...
            // 如果input设备有更新 , 则更新设备
            if (oldGeneration != mGeneration) {
                inputDevicesChanged = true;
                getInputDevicesLocked(inputDevices);
            }
        } // release lock
        if (inputDevicesChanged) {
            // 发送设备更新的消息给InputManagerService
            mPolicy->notifyInputDevicesChanged(inputDevices);
        }
        ...
    }
    
    1. EventHub.getEvents()函数中获取到新增的设备以及/dev/input下的各类事件
    • 判断是否要重新打开设备 , 如果是的话 , 则重新关闭设备重新打开
    • 如果有关闭的设备 , 则构建DEVICE_REMOVED消息
    • 判断是否需要扫描设备 , 如果需要 , 则开始扫描设备
    • 如果有打开了的设备 , 则通过DEVICE_ADDED消息通知设备添加
    • 如果是inode_notify消息对话 , 则设置mPendingINotify代表设备节点有消息
    • 如果是EPOLL_WAKE消息的话 , 则总ReadPipe中读取消息
    • 接着从该设备的硬件缓冲区中读取消息 , 最后将数据填充到buffer
    size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
        // 加锁
        AutoMutex _l(mLock);
        // Input Event的Buffer
        struct input_event readBuffer[bufferSize];
    
        RawEvent* event = buffer;
        size_t capacity = bufferSize;
        bool awoken = false;
        for (;;) {
            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
            // 判断是否要重新打开设备
            if (mNeedToReopenDevices) {
                mNeedToReopenDevices = false;
                // 如果配置文件修改了的话 , 就要重新打开设备
                closeAllDevicesLocked();
                mNeedToScanDevices = true;
                break;
            }
            while (mClosingDevices) {
                // 如果有已经关闭的设备 , 则把设备ID以及DEVICE_REMOVED事件发送
                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_ADDED事件添加设备
                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;
                }
            }
            // 获取Epoll的事件的未决事件
            bool deviceChanged = false;
            while (mPendingEventIndex < mPendingEventCount) {
                const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++];
                if (eventItem.data.u32 == EPOLL_ID_INOTIFY) {
                    // 接收到了INOFITY的FD消息 , 会将mPendingINotify设置成true
                    // 代表当前有未决的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) {
                    // 如果是从readPipe接收到的消息
                    if (eventItem.events & EPOLLIN) {
                        ALOGV("awoken after wake()");
                        awoken = true;
                        char buffer[16];
                        ssize_t nRead;
                        do {
                            // 则会从ReadPipe中读取Buffer
                            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;
                }
                // 获取到此次Event的设备Index
                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;
                }
                // 根据Index获取device
                Device* device = mDevices.valueAt(deviceIndex);
                if (eventItem.events & EPOLLIN) {
                    // 如果是EPOLLIN类型消息 , 则会从该设备的硬件缓冲区中读取Buffer
                    int32_t readSize = read(device->fd, readBuffer,
                            sizeof(struct input_event) * capacity);
                    if (readSize == 0 || (readSize < 0 && errno == ENODEV)) {
                        // 如果没找到该设备 , 则删除设备
                        deviceChanged = true;
                        closeDeviceLocked(device);
                    } else if (readSize < 0) {
                        // 从设备中读取字节小于0 , 则打印错误
                        if (errno != EAGAIN && errno != EINTR) {
                            ALOGW("could not get event (errno=%d)", errno);
                        }
                    } else if ((readSize % sizeof(struct input_event)) != 0) {
                        // 如果读到的Size不是input_event结构体的整数倍,代表数据错误
                        ALOGE("could not get event (wrong size: %d)", readSize);
                    } else {
                        // 得到设备id
                        int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; 
                        // 得到此次Event的input_event
                        size_t count = size_t(readSize) / sizeof(struct input_event);
                        for (size_t i = 0; i < count; i++) {
                            // 遍历读取input_event
                            struct input_event& iev = readBuffer[i];
                            ...
                            // 省去一堆校验
                            event->deviceId = deviceId;
                            event->type = iev.type;
                            event->code = iev.code;
                            event->value = iev.value;
                            // event+1 , 移动到下一个Buffer slot
                            event += 1;
                            capacity -= 1;
                        }
                        if (capacity == 0) {
                            // 如果capacity==0 , 则代表此次读取到Buffer已经满了 , 下次再读取
                            mPendingEventIndex -= 1;
                            break;
                        }
                    }
                } else if (eventItem.events & EPOLLHUP) {
                    // 如果是EPOLLHUP消息 , 则删除设备
                    deviceChanged = true;
                    closeDeviceLocked(device);
                } else {
                    ALOGW("Received unexpected epoll event 0x%08x for device %s.",
                            eventItem.events, device->identifier.name.string());
                }
            }
            // 如果之前读的mPendingINotify消息海没有读取的话 , 那么就开始读取
            // inotify的设备
            if (mPendingINotify && mPendingEventIndex >= mPendingEventCount) {
                mPendingINotify = false;
                // 读取/dev/input/下的设备文件
                readNotifyLocked();
                deviceChanged = true;
            }
    
            // 如果发现设备改变了 , 那么立刻重新进入循环 , 重新加载设备
            if (deviceChanged) {
                continue;
            }
            // 检查Event与唤醒
            if (event != buffer || awoken) {
                break;
            }
            mPendingEventIndex = 0;
            // 释放锁
            mLock.unlock(); // release lock before poll, must be before release_wake_lock
            release_wake_lock(WAKE_LOCK_ID);
            // 通过epoll_wait等待下一次事件的到来
            int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis);
            // 当epoll被唤醒后 , 请求wake lock
            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
            mLock.lock(); // reacquire lock after poll, must be after acquire_wake_lock
            // 如果是timeout , 则重新读取数据
            if (pollResult == 0) {
                // Timed out.
                mPendingEventCount = 0;
                break;
            }
            
            if (pollResult < 0) {
                // 如果pollResult结果小于0 , 则返回错误
                mPendingEventCount = 0;
               // 打印错误
                if (errno != EINTR) {
                    ALOGW("poll failed (errno=%d)\n", errno);
                    usleep(100000);
                }
            } else {
                // 如果大于0 , 则认为有pendingEvent
                mPendingEventCount = size_t(pollResult);
            }
        }
        // 返回EventCounts
        return event - buffer;
    }
    
    1. 在通过epoll接收到设备文件的事件后 , 开始处理事件
    void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
        for (const RawEvent* rawEvent = rawEvents; count;) {
            // 开始遍历缓冲区的rawEvent
            int32_t type = rawEvent->type;
            size_t batchSize = 1;
            if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
                // 如果非DEVICE_ADD\DEVICE_REMOVED的消息 
                int32_t deviceId = rawEvent->deviceId;
                while (batchSize < count) {
                    if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT
                            || rawEvent[batchSize].deviceId != deviceId) {
                        // 找到可以批量处理Device的Events
                        break;
                    }
                    batchSize += 1;
                }
                // 开始批量处理rawEvents
                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;
        }
    }
    
    1. 根据设备ID找到对应的设备 , 然后交予设备进行处理
    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;
        }
        // 根据deviceindex找到设备
        InputDevice* device = mDevices.valueAt(deviceIndex);
        if (device->isIgnored()) {
            //ALOGD("Discarding event for ignored deviceId %d.", deviceId);
            return;
        }
        // 找到对应设备进行处理
        device->process(rawEvents, count);
    }
    
    1. 在接收到DEVICE_ADD消息到时候 , 会创建相应的DEVICE
    • 通过createDeviceLocked添加设备
    • 根据InputDevices.classes来匹配对应的Mapper
    InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
            const InputDeviceIdentifier& identifier, uint32_t classes) {
        // 创建InputDevice
        InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
                controllerNumber, identifier, classes);
        // 根据classes来设置参数
        if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
            device->setExternal(true);
        }
    
        // Devices with mics.
        if (classes & INPUT_DEVICE_CLASS_MIC) {
            device->setMic(true);
        }
    
        // Switch-like devices.
        if (classes & INPUT_DEVICE_CLASS_SWITCH) {
            device->addMapper(new SwitchInputMapper(device));
        }
    
        // Scroll wheel-like devices.
        if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) {
            device->addMapper(new RotaryEncoderInputMapper(device));
        }
    
        // Vibrator-like devices.
        if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
            device->addMapper(new VibratorInputMapper(device));
        }
    
        // Keyboard-like devices.
        uint32_t keyboardSource = 0;
        int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
        if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
            keyboardSource |= AINPUT_SOURCE_KEYBOARD;
        }
        if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
            keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
        }
        if (classes & INPUT_DEVICE_CLASS_DPAD) {
            keyboardSource |= AINPUT_SOURCE_DPAD;
        }
        if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
            keyboardSource |= AINPUT_SOURCE_GAMEPAD;
        }
    
        if (keyboardSource != 0) {
            device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
        }
    
        // Cursor-like devices.
        if (classes & INPUT_DEVICE_CLASS_CURSOR) {
            device->addMapper(new CursorInputMapper(device));
        }
    
        // 看classes添加单指、多指触碰的Mapper
        if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
            device->addMapper(new MultiTouchInputMapper(device));
        } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
            device->addMapper(new SingleTouchInputMapper(device));
        }
    
        // Joystick-like devices.
        if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
            device->addMapper(new JoystickInputMapper(device));
        }
    
        // External stylus-like devices.
        if (classes & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
            device->addMapper(new ExternalStylusInputMapper(device));
        }
    
        return device;
    }
    
    1. InputDevices::process中会根据Mapper来处理事件
    void InputDevice::process(const RawEvent* rawEvents, size_t count) {
        size_t numMappers = mMappers.size();
        for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
            // 是否需要丢弃该事件
            if (mDropUntilNextSync) {
                if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
                    mDropUntilNextSync = false;
                } 
            } 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遍历处理Events
                    mapper->process(rawEvent);
                }
            }
        }
    
    1. 例如单指触碰事件的Mapper
    void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
        // 调用TouchInputManager的process函数
        TouchInputMapper::process(rawEvent);
        mSingleTouchMotionAccumulator.process(rawEvent);
    }
    
    void TouchInputMapper::process(const RawEvent* rawEvent) {
        ...
        if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
            // 开始同步rawEvent
            sync(rawEvent->when);
        }
    }
    
    void TouchInputMapper::sync(nsecs_t when) {
        // 调用syncTouch开始处理TouchEvent
        syncTouch(when, next);
        ...
        // 处理RawTouchEvents
        processRawTouches(false /*timeout*/);
    }
    
    void TouchInputMapper::processRawTouches(bool timeout) {
        // 如果设备不可用了 , 则清除掉所有的等待事件
        if (mDeviceMode == DEVICE_MODE_DISABLED) {
            mCurrentRawState.clear();
            mRawStatesPending.clear();
            return;
        }
        // 开始遍历所有的pendingState
        const size_t N = mRawStatesPending.size();
        size_t count;
        for(count = 0; count < N; count++) {
            const RawState& next = mRawStatesPending[count];
             ...
             mCurrentRawState.copyFrom(next);
             // 开始分发
            cookAndDispatch(mCurrentRawState.when);
        }
        // 清理掉已经分发的事件
        if (count != 0) {
            mRawStatesPending.removeItemsAt(0, count);
        }
        ...
    }
    
    1. cookAndDispatch
    void TouchInputMapper::cookAndDispatch(nsecs_t when) {
       // 优先处理掉虚拟事件(Virtual Touch)
        if (consumeRawTouches(when, policyFlags)) {
            mCurrentRawState.rawPointerData.clear();
        }
        ...
        // 处理单指触碰
        if (mDeviceMode == DEVICE_MODE_POINTER) {
           ...
            // Stylus takes precedence over all tools, then mouse, then finger.
            PointerUsage pointerUsage = mPointerUsage;
            if (!mCurrentCookedState.stylusIdBits.isEmpty()) {
                mCurrentCookedState.mouseIdBits.clear();
                mCurrentCookedState.fingerIdBits.clear();
                pointerUsage = POINTER_USAGE_STYLUS;
            } else if (!mCurrentCookedState.mouseIdBits.isEmpty()) {
                mCurrentCookedState.fingerIdBits.clear();
                pointerUsage = POINTER_USAGE_MOUSE;
            } else if (!mCurrentCookedState.fingerIdBits.isEmpty() ||
                    isPointerDown(mCurrentRawState.buttonState)) {
                pointerUsage = POINTER_USAGE_GESTURES;
            }
             // 开始分发Pointer
            dispatchPointerUsage(when, policyFlags, pointerUsage);
        } else {
            ...
         }
    }
    
    1. dispatchPointerUsage的时候 , 会根据事件用途进行分发
    void TouchInputMapper::dispatchPointerUsage(nsecs_t when, uint32_t policyFlags,
            PointerUsage pointerUsage) {
        ... 
        switch (mPointerUsage) {
        case POINTER_USAGE_GESTURES:
            // 如果是手势事件
            dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
            break;
        case POINTER_USAGE_STYLUS:
            // 如果是触摸笔事件
            dispatchPointerStylus(when, policyFlags);
            break;
        case POINTER_USAGE_MOUSE:
            // 如果是鼠标事件
            dispatchPointerMouse(when, policyFlags);
            break;
        default:
            break;
        }
    }
    
    void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags,
            bool isTimeout) {
        ... 
        // 开始发送Events
        int32_t metaState = getContext()->getGlobalMetaState();
        int32_t buttonState = mCurrentCookedState.buttonState;
    
         // 判断当前是否为DOWN事件
        bool down = mPointerGesture.currentGestureMode == PointerGesture::TAP
                || mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG
                || mPointerGesture.currentGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
                || mPointerGesture.currentGestureMode == PointerGesture::PRESS
                || mPointerGesture.currentGestureMode == PointerGesture::SWIPE
                || mPointerGesture.currentGestureMode == PointerGesture::FREEFORM;
        bool moveNeeded = false;
        if (down && !cancelPreviousGesture && !finishPreviousGesture
                && !mPointerGesture.lastGestureIdBits.isEmpty()
                && !mPointerGesture.currentGestureIdBits.isEmpty()) {
            BitSet32 movedGestureIdBits(mPointerGesture.currentGestureIdBits.value
                    & mPointerGesture.lastGestureIdBits.value);
            // 判断是否需要更新MOVE事件的位置
            moveNeeded = updateMovedPointers(mPointerGesture.currentGestureProperties,
                    mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
                    mPointerGesture.lastGestureProperties,
                    mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
                    movedGestureIdBits);
            if (buttonState != mLastCookedState.buttonState) {
                moveNeeded = true;
            }
        }
         ... 
     //  开始分发CANCEL事件与ACTION_UP事件
        BitSet32 dispatchedGestureIdBits(mPointerGesture.lastGestureIdBits);
        if (!dispatchedGestureIdBits.isEmpty()) {
            if (cancelPreviousGesture) {
                dispatchMotion(when, policyFlags, mSource,
                        AMOTION_EVENT_ACTION_CANCEL, 0, 0, metaState, buttonState,
                        AMOTION_EVENT_EDGE_FLAG_NONE,
                        mPointerGesture.lastGestureProperties,
                        mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
                        dispatchedGestureIdBits, -1, 0,
                        0, mPointerGesture.downTime);
    
                dispatchedGestureIdBits.clear();
            } else {
                BitSet32 upGestureIdBits;
                if (finishPreviousGesture) {
                    upGestureIdBits = dispatchedGestureIdBits;
                } else {
                    upGestureIdBits.value = dispatchedGestureIdBits.value
                            & ~mPointerGesture.currentGestureIdBits.value;
                }
                while (!upGestureIdBits.isEmpty()) {
                    uint32_t id = upGestureIdBits.clearFirstMarkedBit();
    
                    dispatchMotion(when, policyFlags, mSource,
                            AMOTION_EVENT_ACTION_POINTER_UP, 0, 0,
                            metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
                            mPointerGesture.lastGestureProperties,
                            mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
                            dispatchedGestureIdBits, id,
                            0, 0, mPointerGesture.downTime);
    
                    dispatchedGestureIdBits.clearBit(id);
                }
            }
        }
        // 如果MOVE事件有修改 , 则开始分发ACTION_MOVE
        if (moveNeeded) {
            dispatchMotion(when, policyFlags, mSource,
                    AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState,
                    AMOTION_EVENT_EDGE_FLAG_NONE,
                    mPointerGesture.currentGestureProperties,
                    mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
                    dispatchedGestureIdBits, -1,
                    0, 0, mPointerGesture.downTime);
        }
    
        // 如果是DOWN事件 , 则分发down事件
        if (down) {
                 ...
                dispatchMotion(when, policyFlags, mSource,
                        AMOTION_EVENT_ACTION_POINTER_DOWN, 0, 0, metaState, buttonState, 0,
                        mPointerGesture.currentGestureProperties,
                        mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
                        dispatchedGestureIdBits, id,
                        0, 0, mPointerGesture.downTime);
        }
    
        // Send motion events for hover.
        if (mPointerGesture.currentGestureMode == PointerGesture::HOVER) {
            dispatchMotion(when, policyFlags, mSource,
                    AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
                    metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
                    mPointerGesture.currentGestureProperties,
                    mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
                    mPointerGesture.currentGestureIdBits, -1,
                    0, 0, mPointerGesture.downTime);
        } else if (dispatchedGestureIdBits.isEmpty()
              ...
        }
        ...
    }
    
    1. 开始分发
    void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
            int32_t action, int32_t actionButton, int32_t flags,
            int32_t metaState, int32_t buttonState, int32_t edgeFlags,
            const PointerProperties* properties, const PointerCoords* coords,
            const uint32_t* idToIndex, BitSet32 idBits, int32_t changedId,
            float xPrecision, float yPrecision, nsecs_t downTime) {
        ...
        if (changedId >= 0 && pointerCount == 1) {
           // 替换ACTION为上层的ACTION
            if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
                action = AMOTION_EVENT_ACTION_DOWN;
            } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
                action = AMOTION_EVENT_ACTION_UP;
            }  
        }
         // 构造参数
        NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
                action, actionButton, flags, metaState, buttonState, edgeFlags,
                mViewport.displayId, pointerCount, pointerProperties, pointerCoords,
                xPrecision, yPrecision, downTime);
        // 通过InputListener通知事件发生
        getListener()->notifyMotion(&args);
    }
    

    分发Input事件

    1. 从最开始的InputReader的构造函数可以知道 , getListener()得到的就是InputDispatcher
    InputManager::InputManager(
            const sp<EventHubInterface>& eventHub,
            const sp<InputReaderPolicyInterface>& readerPolicy,
            const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
        // 初始化`InputDispathcer`进行事件分发,内部会初始化一个Looper用于子线程
        mDispatcher = new InputDispatcher(dispatcherPolicy);
        // 初始化`InputReader`从`/dev/input`设备文件中通过`epoll_wait`来等待事件到来
        mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
        initialize();
    }
    InputReader::InputReader(const sp<EventHubInterface>& eventHub,
            const sp<InputReaderPolicyInterface>& policy,
            const sp<InputListenerInterface>& listener) :
            mContext(this), mEventHub(eventHub), mPolicy(policy),
            mGlobalMetaState(0), mGeneration(1),
            mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
            mConfigurationChangesToRefresh(0) {
        mQueuedListener = new QueuedInputListener(listener);
        ...
    }
    
    1. InputDispatcher::notifyMotion()
    void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
         // 校验MotionEvent的参数
        if (!validateMotionEvent(args->action, args->actionButton,
                    args->pointerCount, args->pointerProperties)) {
            return;
        }
       ...
        // 是否需要唤醒
        bool needWake;
        { // acquire lock
            mLock.lock();
            ...
            // 构建MotionEntry
            MotionEntry* newEntry = new MotionEntry(args->eventTime,
                    args->deviceId, args->source, policyFlags,
                    args->action, args->actionButton, args->flags,
                    args->metaState, args->buttonState,
                    args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
                    args->displayId,
                    args->pointerCount, args->pointerProperties, args->pointerCoords, 0, 0);
            // 插入到Event队列中
            needWake = enqueueInboundEventLocked(newEntry);
            mLock.unlock();
        } // release lock
        // 如果需要唤醒InputDispatcher线程, 则调用Looper的唤醒方法
        if (needWake) {
            mLooper->wake();
        }
    }
    
    1. InputDispatcher::enqueueInboundEventLocked
    bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
        // 如果队列为空 , 则需要唤醒
        bool needWake = mInboundQueue.isEmpty();
        // 插入到mInboundQueue队列尾部
        mInboundQueue.enqueueAtTail(entry);
        ...
        return needWake;
    }
    
    1. 同样 , 在InputDispatcher线程中 , 会调用dispatchOnce来处理事件
    void InputDispatcher::dispatchOnce() {
        nsecs_t nextWakeupTime = LONG_LONG_MAX;
        { // acquire lock
            AutoMutex _l(mLock);
            mDispatcherIsAliveCondition.broadcast();
            // 判断是否CommandQueue是否为空 
            if (!haveCommandsLocked()) {
                // 为空则开始处理事件
                dispatchOnceInnerLocked(&nextWakeupTime);
            }
            if (runCommandsLockedInterruptible()) {
                nextWakeupTime = LONG_LONG_MIN;
            }
        } // release lock
        // 继续poll等待
        mLooper->pollOnce(timeoutMillis);
    }
    
    1. dispatchOnceInnerLocked开始查找、丢弃、分发策略
    void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
        nsecs_t currentTime = now();
        ...
        // 开始获取PendingEvent
        if (! mPendingEvent) {
            // 如果Event队列为空的话
            if (mInboundQueue.isEmpty()) {
                if (isAppSwitchDue) {
                    resetPendingAppSwitchLocked(false);
                    isAppSwitchDue = false;
                }
                if (mKeyRepeatState.lastKeyEntry) {
                    if (currentTime >= mKeyRepeatState.nextRepeatTime) {
                        // 则从触笔队列中尝试获取
                        mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
                    } else {
                        if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
                            *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
                        }
                    }
                }
                if (!mPendingEvent) {
                    // 如果没有要处理的事件 , 则返回
                    return;
                }
            } else {
                //  如果Event队列不为空 , 则从队列中获取Header
                mPendingEvent = mInboundQueue.dequeueAtHead();
            }
            ....
            // 重置ANR超时的时间
            resetANRTimeoutsLocked();
        }
    
        // 正式开始分发事件
        bool done = false;
        DropReason dropReason = DROP_REASON_NOT_DROPPED;
        if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
            dropReason = DROP_REASON_POLICY;
        } else if (!mDispatchEnabled) {
            dropReason = DROP_REASON_DISABLED;
        }
        // 根据PendingEvent的type开始处理
        switch (mPendingEvent->type) {
        // 处理Configuration Change消息 , 即屏幕旋转等等
        case EventEntry::TYPE_CONFIGURATION_CHANGED: {
            ConfigurationChangedEntry* typedEntry =
                    static_cast<ConfigurationChangedEntry*>(mPendingEvent);
            done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
            dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
            break;
        }
       // 处理设备重置消息 
        case EventEntry::TYPE_DEVICE_RESET: {
            DeviceResetEntry* typedEntry =
                    static_cast<DeviceResetEntry*>(mPendingEvent);
            done = dispatchDeviceResetLocked(currentTime, typedEntry);
            dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
            break;
        }
        // 处理Key按键消息
        case EventEntry::TYPE_KEY: {
            KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
            if (isAppSwitchDue) {
                if (isAppSwitchKeyEventLocked(typedEntry)) {
                    resetPendingAppSwitchLocked(true);
                    isAppSwitchDue = false;
                } else if (dropReason == DROP_REASON_NOT_DROPPED) {
                    dropReason = DROP_REASON_APP_SWITCH;
                }
            }
            if (dropReason == DROP_REASON_NOT_DROPPED
                    && isStaleEventLocked(currentTime, typedEntry)) {
                dropReason = DROP_REASON_STALE;
            }
            if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
                dropReason = DROP_REASON_BLOCKED;
            }
            done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
            break;
        }
        // 处理触屏消息
        case EventEntry::TYPE_MOTION: {
            MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
            if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
                dropReason = DROP_REASON_APP_SWITCH;
            }
            if (dropReason == DROP_REASON_NOT_DROPPED
                    && isStaleEventLocked(currentTime, typedEntry)) {
                dropReason = DROP_REASON_STALE;
            }
            if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
                dropReason = DROP_REASON_BLOCKED;
            }
            done = dispatchMotionLocked(currentTime, typedEntry,
                    &dropReason, nextWakeupTime);
            break;
        }
        default:
            ALOG_ASSERT(false);
            break;
        }
        if (done) {
            if (dropReason != DROP_REASON_NOT_DROPPED) {
                dropInboundEventLocked(mPendingEvent, dropReason);
            }
            mLastDropReason = dropReason;
            releasePendingEventLocked();
            *nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately
        }
    }
    
    1. 开始分发MotionEvent
    bool InputDispatcher::dispatchMotionLocked(
            nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
        bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
        // 找到目标窗口
        Vector<InputTarget> inputTargets;
    
        bool conflictingPointerActions = false;
        int32_t injectionResult;
        if (isPointerEvent) {
            // 如果是手指事件的话 ,则找到Touch窗口
            injectionResult = findTouchedWindowTargetsLocked(currentTime,
                    entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
        } else {
            // 如果不是手指触摸事件 , 比如轨迹球事件的话 , 则找到Focus窗口
            injectionResult = findFocusedWindowTargetsLocked(currentTime,
                    entry, inputTargets, nextWakeupTime);
        }
        // 如果找到窗口失败, 返回
        if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
            return false;
        }
        // 开始向窗口分发事件
        dispatchEventLocked(currentTime, entry, inputTargets);
        return true;
    }
    
    1. dispatchEventLocked
    void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
            EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
        // 
        pokeUserActivityLocked(eventEntry);
    
        for (size_t i = 0; i < inputTargets.size(); i++) {
            const InputTarget& inputTarget = inputTargets.itemAt(i);
            // 遍历当前的窗口
            ssize_t connectionIndex =   getConnectionIndexLocked(inputTarget.inputChannel);
            if (connectionIndex >= 0) {
                // 获取FD与窗口对应的连接
                sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
                // 开始分发给相应窗口
                prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
            } else {
    #if DEBUG_FOCUS
                ALOGD("Dropping event delivery to target with channel '%s' because it "
                        "is no longer registered with the input dispatcher.",
                        inputTarget.inputChannel->getName().string());
    #endif
            }
        }
    }
    
    1. prepareDispatchCycleLocked中 , 最终调用的是startDispatchCycleLocked
    void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
            const sp<Connection>& connection) {
         // 如果connection的状态正常
        while (connection->status == Connection::STATUS_NORMAL
                && !connection->outboundQueue.isEmpty()) {
            DispatchEntry* dispatchEntry = connection->outboundQueue.head;
            dispatchEntry->deliveryTime = currentTime;
            status_t status;
            EventEntry* eventEntry = dispatchEntry->eventEntry;
            // 根据type开始分发相应的事件
            switch (eventEntry->type) {
            case EventEntry::TYPE_KEY: {
                KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
    
                // Publish the key event.
                status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
                        keyEntry->deviceId, keyEntry->source,
                        dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
                        keyEntry->keyCode, keyEntry->scanCode,
                        keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
                        keyEntry->eventTime);
                break;
            }
    
            case EventEntry::TYPE_MOTION: {
                MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
                PointerCoords scaledCoords[MAX_POINTERS];
                const PointerCoords* usingCoords = motionEntry->pointerCoords;
    
                // Set the X and Y offset depending on the input source.
                float xOffset, yOffset, scaleFactor;
                if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
                        && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
                    scaleFactor = dispatchEntry->scaleFactor;
                    xOffset = dispatchEntry->xOffset * scaleFactor;
                    yOffset = dispatchEntry->yOffset * scaleFactor;
                    if (scaleFactor != 1.0f) {
                        for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
                            scaledCoords[i] = motionEntry->pointerCoords[i];
                            scaledCoords[i].scale(scaleFactor);
                        }
                        usingCoords = scaledCoords;
                    }
                } else {
                    xOffset = 0.0f;
                    yOffset = 0.0f;
                    scaleFactor = 1.0f;
    
                    // We don't want the dispatch target to know.
                    if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
                        for (uint32_t i = 0; i < motionEntry->pointerCount; i++) {
                            scaledCoords[i].clear();
                        }
                        usingCoords = scaledCoords;
                    }
                }
    
                // 最后 , 通过connection->inputPublisher来发布MotionEvent给窗口
                status = connection->inputPublisher.publishMotionEvent(dispatchEntry->seq,
                        motionEntry->deviceId, motionEntry->source,
                        dispatchEntry->resolvedAction, motionEntry->actionButton,
                        dispatchEntry->resolvedFlags, motionEntry->edgeFlags,
                        motionEntry->metaState, motionEntry->buttonState,
                        xOffset, yOffset, motionEntry->xPrecision, motionEntry->yPrecision,
                        motionEntry->downTime, motionEntry->eventTime,
                        motionEntry->pointerCount, motionEntry->pointerProperties,
                        usingCoords);
                break;
            }
    
            default:
                ALOG_ASSERT(false);
                return;
            }
    
            // Check the result.
            if (status) {
                if (status == WOULD_BLOCK) {
                    if (connection->waitQueue.isEmpty()) {
                        ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
                                "This is unexpected because the wait queue is empty, so the pipe "
                                "should be empty and we shouldn't have any problems writing an "
                                "event to it, status=%d", connection->getInputChannelName(), status);
                        abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
                    } else {
                        // Pipe is full and we are waiting for the app to finish process some events
                        // before sending more events to it.
    #if DEBUG_DISPATCH_CYCLE
                        ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
                                "waiting for the application to catch up",
                                connection->getInputChannelName());
    #endif
                        connection->inputPublisherBlocked = true;
                    }
                } else {
                    ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
                            "status=%d", connection->getInputChannelName(), status);
                    abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
                }
                return;
            }
    
            // Re-enqueue the event on the wait queue.
            connection->outboundQueue.dequeue(dispatchEntry);
            traceOutboundQueueLengthLocked(connection);
            connection->waitQueue.enqueueAtTail(dispatchEntry);
            traceWaitQueueLengthLocked(connection);
        }
    }
    

    相关文章

      网友评论

          本文标题:Android中Input事件初始化、接收以及分发

          本文链接:https://www.haomeiwen.com/subject/vpvjyktx.html