前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android中Input事件初始化、接收以及分发

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

作者头像
None_Ling
发布2020-09-24 10:31:56
1.9K0
发布2020-09-24 10:31:56
举报
文章被收录于专栏:Android相关Android相关

简述

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

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

初始化监听

  1. system_server初始化InputManagerService
  • 通过DisplayThreadLooper初始化InputManagerHandler
  • 调用nativeInit初始化Native层的InputManager
代码语言:javascript
复制
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对象
代码语言:javascript
复制
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文件的读取
代码语言:javascript
复制
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线程
代码语言:javascript
复制
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的构造函数
代码语言:javascript
复制
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开启子线程读取
代码语言:javascript
复制
SystemServer{
        public startOtherServices(){
            ...
            traceBeginAndSlog("StartInputManagerService");
            inputManager = new InputManagerService(context);
            traceEnd();
            ... 
            traceBeginAndSlog("StartInputManager");
            inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
            inputManager.start();
            traceEnd();
            ...
      }
}
  1. start()函数中最重要的就是nativeStart , 其余都是在注册和更新Settings中的值
代码语言:javascript
复制
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
代码语言:javascript
复制
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中开始处理事件
  • 如果设备有更新 , 则更新设备信息
代码语言:javascript
复制
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
代码语言:javascript
复制
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接收到设备文件的事件后 , 开始处理事件
代码语言:javascript
复制
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找到对应的设备 , 然后交予设备进行处理
代码语言:javascript
复制
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
代码语言:javascript
复制
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来处理事件
代码语言:javascript
复制
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
代码语言:javascript
复制
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
代码语言:javascript
复制
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的时候 , 会根据事件用途进行分发
代码语言:javascript
复制
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;
    }
}
代码语言:javascript
复制
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. 开始分发
代码语言:javascript
复制
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
代码语言:javascript
复制
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()
代码语言:javascript
复制
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
代码语言:javascript
复制
bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
    // 如果队列为空 , 则需要唤醒
    bool needWake = mInboundQueue.isEmpty();
    // 插入到mInboundQueue队列尾部
    mInboundQueue.enqueueAtTail(entry);
    ...
    return needWake;
}
  1. 同样 , 在InputDispatcher线程中 , 会调用dispatchOnce来处理事件
代码语言:javascript
复制
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开始查找、丢弃、分发策略
代码语言:javascript
复制
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
代码语言:javascript
复制
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
代码语言:javascript
复制
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
代码语言:javascript
复制
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);
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简述
  • 初始化监听
  • 接收Input事件
  • 分发Input事件
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档