InputReader源码分析

本文深入分析了Android系统中InputReader组件的源码,包括线程创建与启动、线程函数执行、设备扫描、事件获取与处理等关键步骤,揭示了InputReader如何读取和处理来自设备的输入事件,以及如何将这些事件转化为可操作的MotionEvent传递给上层应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

InputReader源码分析

版本:android 13

一. 线程的创建及启动

接着InputManager的启动流程分析,在调用InManager的start方法后调用了NativeInputManager的start方法

    public void start() {
        Slog.i(TAG, "Starting input manager");
        // 调用start,启动线程
        mNative.start();
		// ... 省略
    }

这是一个native的方法,跟进去:com_*android_*server_input_InputManagerService.cpp

// java层mNative.start();调用到这里,这里很巧妙,这个nativeImplObj就是mNative,而这个mNative就是上面返回给java的地址im,通过调用native方法,自动的又传回来了,妙啊
static void nativeStart(JNIEnv* env, jobject nativeImplObj) {
    // 获取到NativeInputManager
    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
    // 获取InputManager,然后调用start方法启动线程
    status_t result = im->getInputManager()->start();
    if (result) {
        jniThrowRuntimeException(env, "Input manager could not be started.");
    }
}

代码的作用看上面的注释,很详细了,继续我们去看InputManager的start方法InputManager.cpp

status_t InputManager::start() {
	// ... 省略
    result = mReader->start();
    // ... 省略

    return OK;
}

继续看InputReader的start方法InputReader.cpp

status_t InputReader::start() {
    if (mThread) {
        return ALREADY_EXISTS;
    }
    mThread = std::make_unique<InputThread>(
            "InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
    return OK;
}

这里创建了一个线程,和9.0的代码不太一样,9.0的代码是在构造的时候就创建了,这里是启动的时候就创建了,而且是unique_ptr的独享智能指针

继续看它里面的参数: 这里看可能不是很好看,熟悉C++的都知道,unique_ptr是一个模板,所以我们直接去看这个InputThread的构造函数

class InputThread {
public:
    // explicit 作用,防止隐式类型转换的方式初始化对象
    explicit InputThread(std::string name, std::function<void()> loop,
                         std::function<void()> wake = nullptr);
    virtual ~InputThread();

    bool isCallingThread();

private:
    std::string mName;
    std::function<void()> mThreadWake;
    sp<Thread> mThread;
};

这里就比较好看出它的参数是什么了,第一个是线程名,第二个应该是线程执行的函数,第三个应该是唤醒用的函数,我们具体再看一下这个类的实现

// 构造函数的实现,我们可以看到,第一个name是赋值给了mName,第二个loop是通过new InputThreadImpl(loop),构造出来的,最后赋值给了mThread
// mThread是一个sp<Thread>,是一个线程,所以,loop我们可以确定是InputReaderThread的线程函数,而且在构造完成之后直接调用了mThread的run方法
// 第三个,也是一个函数,直接赋值给了mThreadWake,可以看到,在InputThread析构的时候调用了mThreadWake方法,有可能是为了自己唤醒自己的,这里暂时这么猜测。
InputThread::InputThread(std::string name, std::function<void()> loop, std::function<void()> wake)
      : mName(name), mThreadWake(wake) {
    mThread = new InputThreadImpl(loop);
    mThread->run(mName.c_str(), ANDROID_PRIORITY_URGENT_DISPLAY);
}

InputThread::~InputThread() {
    mThread->requestExit();
    if (mThreadWake) {
        mThreadWake();
    }
    mThread->requestExitAndWait();
}

bool InputThread::isCallingThread() {
    return gettid() == mThread->getTid();
}

下面就是线程的实现了

// Implementation of Thread from libutils.
class InputThreadImpl : public Thread {
public:
    explicit InputThreadImpl(std::function<void()> loop)
          : Thread(/* canCallJava */ true), mThreadLoop(loop) {}

    ~InputThreadImpl() {}

private:
    std::function<void()> mThreadLoop;

    bool threadLoop() override {
        mThreadLoop();
        return true;
    }
};

它继承了Thread类重写了threadLooper,当我们调用run的时候会执行字方法,ok,到此为止线程的创建及启动就完成了,接下来我们分析线程函数是如何工作的。

二. 线程函数的执行
// 这是InputReader的构造函数,因为线程函数有很多判断依赖这个里面的变量的值,方这里方便查看
InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
                         const sp<InputReaderPolicyInterface>& policy,
                         InputListenerInterface& listener)
      : mContext(this),
        mEventHub(eventHub),
        mPolicy(policy),
        mQueuedListener(listener),
        mGlobalMetaState(AMETA_NONE),
        mLedMetaState(AMETA_NONE),
        mGeneration(1),
        mNextInputDeviceId(END_RESERVED_ID),
        mDisableVirtualKeysTimeout(LLONG_MIN),
        mNextTimeout(LLONG_MAX),
        mConfigurationChangesToRefresh(0) {
    refreshConfigurationLocked(0);
    updateGlobalMetaStateLocked();
}

// 当make_unique<InputThread>执行完之后,这个函数就会被调用执行。
void InputReader::loopOnce() {
    int32_t oldGeneration;
    int32_t timeoutMillis;
    bool inputDevicesChanged = false;
    std::vector<InputDeviceInfo> inputDevices;
    { // acquire lock
        std::scoped_lock _l(mLock);

		// 这个值默认为1,暂时不知道干啥的,先放着
        oldGeneration = mGeneration;
        timeoutMillis = -1;
		// 这个值在构造里面被赋值为0所以下面的if不会进去,暂时不看
        uint32_t changes = mConfigurationChangesToRefresh;
        if (changes) {
            mConfigurationChangesToRefresh = 0;
            timeoutMillis = 0;
            refreshConfigurationLocked(changes);
		// mNextTimeout在构造函数中被赋值为LLONG_MAX,所以暂时不管
        } else if (mNextTimeout != LLONG_MAX) {
            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
            timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
        }
    } // release lock
	// 重点函数,看名字感觉像是获取事件的个数的,我们下面重点分析它
    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
	// ... 省略,先分析getEents然后再往下分析
}
2.1 EentHub的getEvents解析
// 前面在分析InputManager的启动流程的时候已经分析过在构建EventHub的时候都做了什么事,这里再回忆一下,构造函数也对很多成员变量赋上了默认值,在我们分析getevents的时候会用到,放到这里也方便下面查看。
EventHub::EventHub(void)
      : mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD),
        mNextDeviceId(1),
        mControllerNumbers(),
        mNeedToSendFinishedDeviceScan(false),
        mNeedToReopenDevices(false),
        mNeedToScanDevices(true),
        mPendingEventCount(0),
        mPendingEventIndex(0),
        mPendingINotify(false) {
    ensureProcessCanBlockSuspend();

 	// ... 代码省略
	// 主要就是创建了epoll和初始化了inotify,将/dev/input目录添加到inotify的监听,然后通过epoll监听inotify的fd进行处理/dev/input目录的文件变化,猜测是为了监听热插拔事件吧,先这么猜测。
}
     //The event queue.下面两行是EentHub的两个成员,mEventBuffer是一个容量为256,成员类型为RawEent的数组
    // static const int EVENT_BUFFER_SIZE = 256;
    // RawEvent mEventBuffer[EVENT_BUFFER_SIZE] GUARDED_BY(mLock);
// 下面就是getEents函数了,它有三个参数,是上面传进来的,分别是: -1, 一个容量256的RawEent的数组,256
size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
   	// ... 省略
	// 这里创建了一个input_event的数组,大小是buffersize具体为了干啥暂时不知道,先往后看
    struct input_event readBuffer[bufferSize];
	// 弄了一个局部的指针指向了传进来的buffer
    RawEvent* event = buffer;
	// 给传进来的buffersize保存一下
    size_t capacity = bufferSize;
    bool awoken = false;
    for (;;) {
		// 当前的时间
        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);

        // Reopen input devices if needed.
		// 看构造函数,默认为false,所以,这里进不去
        if (mNeedToReopenDevices) {
            mNeedToReopenDevices = false;

            ALOGI("Reopening all input devices due to a configuration change.");

            closeAllDevicesLocked();
            mNeedToScanDevices = true;
            break; // return to the caller before we actually rescan
        }
		// 这里好像也进不去,第一次进来没有关闭的设备
        // Report any devices that had last been added/removed.
        for (auto it = mClosingDevices.begin(); it != mClosingDevices.end();) {
            std::unique_ptr<Device> device = std::move(*it);
            ALOGV("Reporting device closed: id=%d, name=%s\n", device->id, device->path.c_str());
            event->when = now;
            event->deviceId = (device->id == mBuiltInKeyboardId)
                    ? ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID
                    : device->id;
            event->type = DEVICE_REMOVED;
            event += 1;
            it = mClosingDevices.erase(it);
            mNeedToSendFinishedDeviceScan = true;
            if (--capacity == 0) {
                break;
            }
        }
		// 看构造函数,这个为true,进去看
        if (mNeedToScanDevices) {
            mNeedToScanDevices = false;
			// 看名字应该是扫描设备的。
            scanDevicesLocked();
            mNeedToSendFinishedDeviceScan = true;
        }
		// ... 省略,先分析上面的scanDevicesLocked()
}

2.2 scanDevicesLocked
void EventHub::scanDevicesLocked() {
    status_t result;
    std::error_code errorCode;
	// 这里判断这个目录是否存在,如果存在则去扫描
    if (std::filesystem::exists(DEVICE_INPUT_PATH, errorCode)) {
		// 一般情况下,目录肯定存在的,所以走到这里
        result = scanDirLocked(DEVICE_INPUT_PATH);
        if (result < 0) {
            ALOGE("scan dir failed for %s", DEVICE_INPUT_PATH);
        }
    } else {
        if (errorCode) {
            ALOGW("Could not run filesystem::exists() due to error %d : %s.", errorCode.value(),
                  errorCode.message().c_str());
        }
    }
	// 视频相关,暂时不看
    if (isV4lScanningEnabled()) {
        result = scanVideoDirLocked(DEVICE_PATH);
        if (result != OK) {
            ALOGE("scan video dir failed for %s", DEVICE_PATH);
        }
    }
	// 虚拟按键?暂时不看
    if (mDevices.find(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID) == mDevices.end()) {
        createVirtualKeyboardLocked();
    }
}

继续分析scanDirLocked

status_t EventHub::scanDirLocked(const std::string& dirname) {
	// 遍历这个目录
    for (const auto& entry : std::filesystem::directory_iterator(dirname)) {
		// 打开这个设备
        openDeviceLocked(entry.path());
    }
    return 0;
}

继续看openDeviceLocked

// 这个结构体用来标识一个设备
struct InputDeviceIdentifier {
    inline InputDeviceIdentifier() :
            bus(0), vendor(0), product(0), version(0) {
    }

    // 内核提供的信息
    std::string name;
    std::string location;
    std::string uniqueId;
    uint16_t bus;
    uint16_t vendor;
    uint16_t product;
    uint16_t version;

   	// 唯一标识设备的复合输入设备描述符字符串,这个值一般不会变
    std::string descriptor;

    //如果没有id的时候用,应该是为了区分设备,暂时每弄明白,先放着
    uint16_t nonce;
	// 这大概是返回设备的名字?
    std::string getCanonicalName() const;
};
// 打开一个设备
void EventHub::openDeviceLocked(const std::string& devicePath) {
    // ... 容错信息,没看太懂,暂时先不看,先看主线

    char buffer[80];

    ALOGV("Opening device: %s", devicePath.c_str());
	// 调用open函数打开设备
    int fd = open(devicePath.c_str(), O_RDWR | O_CLOEXEC | O_NONBLOCK);
    if (fd < 0) {
        ALOGE("could not open %s, %s\n", devicePath.c_str(), strerror(errno));
        return;
    }

    InputDeviceIdentifier identifier;
	
	// 给驱动通信,获取名称
    // Get device name.
    if (ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) {
        ALOGE("Could not get device name for %s: %s", devicePath.c_str(), strerror(errno));
    } else {
        buffer[sizeof(buffer) - 1] = '\0';
        identifier.name = buffer;
    }
	// ... 省略容错信息

    // Get device driver version.
	// 依旧是给驱动通信,获取版本信息
    int driverVersion;
    if (ioctl(fd, EVIOCGVERSION, &driverVersion)) {
        ALOGE("could not get driver version for %s, %s\n", devicePath.c_str(), strerror(errno));
        close(fd);
        return;
    }
	
    // Get device identifier.
	// 同样是和驱动通信,获取标识符
    struct input_id inputId;
    if (ioctl(fd, EVIOCGID, &inputId)) {
        ALOGE("could not get device input id for %s, %s\n", devicePath.c_str(), strerror(errno));
        close(fd);
        return;
    }
    identifier.bus = inputId.bustype;             // 总线类型
    identifier.product = inputId.product;         // 产品
    identifier.vendor = inputId.vendor;           // 制造商
    identifier.version = inputId.version;         // 版本

    // Get device physical location.
	// 获取设备的物理位置?
    if (ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) {
        // fprintf(stderr, "could not get location for %s, %s\n", devicePath, strerror(errno));
    } else {
        buffer[sizeof(buffer) - 1] = '\0';
        identifier.location = buffer;
    }

    // Get device unique id.
	// 获取设备的唯一ID
    if (ioctl(fd, EVIOCGUNIQ(sizeof(buffer) - 1), &buffer) < 1) {
        // fprintf(stderr, "could not get idstring for %s, %s\n", devicePath, strerror(errno));
    } else {
        buffer[sizeof(buffer) - 1] = '\0';
        identifier.uniqueId = buffer;
    }
	
    // Fill in the descriptor.
	// 填充设备的描述符
    assignDescriptorLocked(identifier);

    // Allocate device.  (The device object takes ownership of the fd at this point.)
	// 创建一个设备对象
    int32_t deviceId = mNextDeviceId++;
    std::unique_ptr<Device> device = std::make_unique<Device>(fd, deviceId, devicePath, identifier);

    ALOGV("add device %d: %s\n", deviceId, devicePath.c_str());
    ALOGV("  bus:        %04x\n"
          "  vendor      %04x\n"
          "  product     %04x\n"
          "  version     %04x\n",
          identifier.bus, identifier.vendor, identifier.product, identifier.version);
    ALOGV("  name:       \"%s\"\n", identifier.name.c_str());
    ALOGV("  location:   \"%s\"\n", identifier.location.c_str());
    ALOGV("  unique id:  \"%s\"\n", identifier.uniqueId.c_str());
    ALOGV("  descriptor: \"%s\"\n", identifier.descriptor.c_str());
    ALOGV("  driver:     v%d.%d.%d\n", driverVersion >> 16, (driverVersion >> 8) & 0xff,
          driverVersion & 0xff);

    // Load the configuration file for the device.
	// 加载设备的配置文件
    device->loadConfigurationLocked();

    bool hasBattery = false;
    bool hasLights = false;
    // Check the sysfs root path
	// 检查sysfs的根路径
    std::optional<std::filesystem::path> sysfsRootPath = getSysfsRootPath(devicePath.c_str());
    if (sysfsRootPath.has_value()) {
        std::shared_ptr<AssociatedDevice> associatedDevice;
        for (const auto& [id, dev] : mDevices) {
            if (device->identifier.descriptor == dev->identifier.descriptor &&
                !dev->associatedDevice) {
                associatedDevice = dev->associatedDevice;
            }
        }
        if (!associatedDevice) {
            associatedDevice = std::make_shared<AssociatedDevice>(sysfsRootPath.value());
        }
        hasBattery = associatedDevice->configureBatteryLocked();
        hasLights = associatedDevice->configureLightsLocked();

        device->associatedDevice = associatedDevice;
    }

    // Figure out the kinds of events the device reports.
	// 确认一下设备是什么类型的,如果是某种类型的,那么这个掩码会被置位
    device->readDeviceBitMask(EVIOCGBIT(EV_KEY, 0), device->keyBitmask);
    device->readDeviceBitMask(EVIOCGBIT(EV_ABS, 0), device->absBitmask);
    device->readDeviceBitMask(EVIOCGBIT(EV_REL, 0), device->relBitmask);
    device->readDeviceBitMask(EVIOCGBIT(EV_SW, 0), device->swBitmask);
    device->readDeviceBitMask(EVIOCGBIT(EV_LED, 0), device->ledBitmask);
    device->readDeviceBitMask(EVIOCGBIT(EV_FF, 0), device->ffBitmask);
    device->readDeviceBitMask(EVIOCGBIT(EV_MSC, 0), device->mscBitmask);
    device->readDeviceBitMask(EVIOCGPROP(0), device->propBitmask);

   	// ... 忽略很多判断当前设备类型的代码

    // 判断是否是一个触摸板,判断是否是一个多点触控的设备,一般情况下,我们的手机或者车机都是这种类型,不支持多点触控的很早就不存在了。
    if (device->absBitmask.test(ABS_MT_POSITION_X) && device->absBitmask.test(ABS_MT_POSITION_Y)) {
        // Some joysticks such as the PS3 controller report axes that conflict
        // with the ABS_MT range.  Try to confirm that the device really is
        // a touch screen.
		// 确认当前设备的确是触摸屏
        if (device->keyBitmask.test(BTN_TOUCH) || !haveGamepadButtons) {
			// 满足条件,给classes或上touch和touch_mt
            device->classes |= (InputDeviceClass::TOUCH | InputDeviceClass::TOUCH_MT);
        }
    }

   	// ... 省略判断是否有操纵杆的代码,一般手机和车机都没有

    // ... 省略判断是否为加速计设备

    // ... 省略检查设备是否有开关的代码

    // ... 省略检查设备是否支持振动的代码

    // 判断是否支持虚拟按键,以前的手机屏幕下有虚拟按键,如果支持,则配置它
    if ((device->classes.test(InputDeviceClass::TOUCH))) {
        // Load the virtual keys for the touch screen, if any.
        // We do this now so that we can make sure to load the keymap if necessary.
        bool success = device->loadVirtualKeyMapLocked();
        if (success) {
            device->classes |= InputDeviceClass::KEYBOARD;
        }
    }

    // ... 省略判断是键盘,操纵杆,传感器时加载配置的代码

    // ... 省略配置键盘的代码

    // ... 省略容错代码

    // 检查输入设备是否带电池
    if (hasBattery) {
        device->classes |= InputDeviceClass::BATTERY;
    }

    // 检查这个设备是否有可控的灯
    if (hasLights) {
        device->classes |= InputDeviceClass::LIGHT;
    }

    // 检查这个设备是否有麦克风
    if (device->deviceHasMicLocked()) {
        device->classes |= InputDeviceClass::MIC;
    }

    // 确认这个设备是外部的还是内部的
    if (device->isExternalDeviceLocked()) {
        device->classes |= InputDeviceClass::EXTERNAL;
    }
	
    // ... 省略键盘,操作杆,传感器相关代码
	
	// 最重要的,将这个设备加入epoll
    if (registerDeviceForEpollLocked(*device) != OK) {
        return;
    }
	// 配置这个fd,好像不关触摸屏什么事
    device->configureFd();

    ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=%s, "
          "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, ",
          deviceId, fd, devicePath.c_str(), device->identifier.name.c_str(),
          device->classes.string().c_str(), device->configurationFile.c_str(),
          device->keyMap.keyLayoutFile.c_str(), device->keyMap.keyCharacterMapFile.c_str(),
          toString(mBuiltInKeyboardId == deviceId));
	
	// 将这个设备添加到已打开的向量中
    addDeviceLocked(std::move(device));
}
void EventHub::addDeviceLocked(std::unique_ptr<Device> device) {
    reportDeviceAddedForStatisticsLocked(device->identifier, device->classes);
    mOpeningDevices.push_back(std::move(device));
}

ok,至此,设备打开完成了

我们总结一下openDeviceLocked主要作了什么

  1. 首先打开设备
  2. 从驱动里面获取一些这个设备的信息
  3. 创建一个 Device的对象
  4. 将从驱动里面获取的信息保存到这个对象中
  5. 确认这个设备的类型,保存到Device中
  6. 再确认一下设备的其他信息也一并保存
  7. 然后将这个设备的fd添加到epoll中进行监听
  8. 最后将这个设备添加到用来保存已经打开的设备的向量中

这是打开一个设备的逻辑,在scanDirLocked函数中有一个for循环,它会循环打开/dev/input目录下的所有设备,同样的步骤,将他们添加到保存已打开设备的向量中,扫描设备逻辑就是这样的。

扫描完设备之后我们就继续看getevents函数接下来的部分

size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
   	// ... 省略
	// 这里创建了一个input_event的数组,大小是buffersize具体为了干啥暂时不知道,先往后看
    struct input_event readBuffer[bufferSize];
	// 弄了一个局部的指针指向了传进来的buffer
    RawEvent* event = buffer;
	// 给传进来的buffersize保存一下
    size_t capacity = bufferSize;
    bool awoken = false;
    for (;;) {
		// 当前的时间
        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);

        // Reopen input devices if needed.
		// 看构造函数,默认为false,所以,这里进不去
        if (mNeedToReopenDevices) {
            mNeedToReopenDevices = false;

            ALOGI("Reopening all input devices due to a configuration change.");

            closeAllDevicesLocked();
            mNeedToScanDevices = true;
            break; // return to the caller before we actually rescan
        }
		// 这里好像也进不去,第一次进来没有关闭的设备
        // Report any devices that had last been added/removed.
        for (auto it = mClosingDevices.begin(); it != mClosingDevices.end();) {
            // ... 省略不执行的代码
        }
		// 看构造函数,这个为true,进去看
        if (mNeedToScanDevices) {
            mNeedToScanDevices = false;
			// 这里已经将扫描到的设备添加到mOpeningDevices中了
            scanDevicesLocked();
            mNeedToSendFinishedDeviceScan = true;
        }

		// ---------------------------设备扫描完成之后我们继续分析----------------------------
		// 刚扫描完设备,这里不是empty的,这个while能进去
		while (!mOpeningDevices.empty()) {
			// 获取最后一个设备
            std::unique_ptr<Device> device = std::move(*mOpeningDevices.rbegin());
			// 从向量中删除它
            mOpeningDevices.pop_back();
            ALOGV("Reporting device opened: id=%d, name=%s\n", device->id, device->path.c_str());
			// 还记得这个event吗?这个就是我们外面传进来的数组,我们在这将元素赋值
            event->when = now;
            event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
            event->type = DEVICE_ADDED;     // 新添加
            event += 1;   // 指针偏移

            // ... 省略视频设备相关代码

			// 将这个设备添加到mDevices这个map中,其中设备的id为key
            auto [dev_it, inserted] = mDevices.insert_or_assign(device->id, std::move(device));
            if (!inserted) {
                ALOGW("Device id %d exists, replaced.", device->id);
            }
            mNeedToSendFinishedDeviceScan = true;
            if (--capacity == 0) {    // 数组容量自减
                break;
            }
        }
		// 以上代码执行完,mOpeningDevices中就没有元素了,event中和mDevices中保存了这些设备的信息
		
		// 设备扫描完成之后将最后一个元素类型设置为FINISHED_DEVICE_SCAN
        if (mNeedToSendFinishedDeviceScan) {
            mNeedToSendFinishedDeviceScan = false;
            event->when = now;
            event->type = FINISHED_DEVICE_SCAN;
            event += 1;
            if (--capacity == 0) {
                break;
            }
        }

        // Grab the next input event.
        bool deviceChanged = false;
		// 第一次进来这两个值都是0所以这个while进步来
        while (mPendingEventIndex < mPendingEventCount) {
            // ... 省略不执行的代码
        }

        // ... 省略不执行的代码

        // 初始值event是等于buffer的,但后面event添加了设备,指针往后偏移了,所以这两个值是不相等的,所以这里break出去了。
        if (event != buffer || awoken) {
            break;
        }
		// ... 省略不执行的代码
    // All done, return the number of events we read.
	// 这里返回事件的个数,其实就是指针的偏移了几次,这里只是第一次进去的执行的逻辑
    return event - buffer;
}

我们现在总结一下第一次执行getEents这个函数主要做了什么

  1. 扫描/deve/input目录下的所有设备并打开
  2. 在打开后从驱动获取一些信息保存到Device对象中,然后将扫描到的设备保存到mOpeningDevices这个vector中
  3. 遍历mOpeningDevices这个vector将设备添加到buffer和EventHub的mDevices这个map中
  4. 然后返回个数
2.3 继续分析线程函数
void InputReader::loopOnce() {
    int32_t oldGeneration;
    int32_t timeoutMillis;
    bool inputDevicesChanged = false;
    std::vector<InputDeviceInfo> inputDevices;
    { // acquire lock
        std::scoped_lock _l(mLock);

		// 这个值默认为1,暂时不知道干啥的,先放着
        oldGeneration = mGeneration;
        timeoutMillis = -1;
		// 这个值在构造里面被赋值为0所以下面的if不会进去,暂时不看
        uint32_t changes = mConfigurationChangesToRefresh;
        if (changes) {
            mConfigurationChangesToRefresh = 0;
            timeoutMillis = 0;
            refreshConfigurationLocked(changes);
		// mNextTimeout在构造函数中被赋值为LLONG_MAX,所以暂时不管
        } else if (mNextTimeout != LLONG_MAX) {
            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
            timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
        }
    } // release lock
	// 重点函数,这里返回的是设备的个数,具体逻辑看2.2分析
    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
	// -------------------  接着分析 ------------------------
	
	    { // acquire lock
        std::scoped_lock _l(mLock);
		// 条件变量,暂时不管
        mReaderIsAliveCondition.notify_all();
		// 这里一般不太会为0,所以会进来
        if (count) {
            processEventsLocked(mEventBuffer, count);
        }

   		// ... 先分析processEventsLocked,下面的代码后面分析
}
// 处理events的函数
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
	// 这里遍历rawEvents,根据上面的分析,这个rawEents中保存了扫描到的设备
    for (const RawEvent* rawEvent = rawEvents; count;) {
		// 获取设备的类型
        int32_t type = rawEvent->type;
        size_t batchSize = 1;
		// FIRST_SYNTHETIC_EVENT 和 DEVICE_ADDED相等,我们之前扫描到的设备类型都是DEVICE_ADDED,所以这里不会走
        if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
            // ... 省略不会执行的代码
        } else {
			// 对于之前的设备,我们的类型都是DEVICE_ADDED所以我们只需要看DEVICE_ADDED的case
            switch (rawEvent->type) {
                case EventHubInterface::DEVICE_ADDED:
                    addDeviceLocked(rawEvent->when, rawEvent->deviceId);
                    break;
                	// ... 省略不执行的代码
                default:
                    ALOG_ASSERT(false); // can't happen
                    break;
            }
        }
        count -= batchSize;
        rawEvent += batchSize;
    }
}

继续看addDeviceLocked

void InputReader::addDeviceLocked(nsecs_t when, int32_t eventHubId) {
   	// ... 省略容错代码
	// 我们在打开设备的时候就保存设备的标识到Device中,所以这里可以直接获取到
    InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(eventHubId);
	// 根据id和identifiel创建InputDeice
    std::shared_ptr<InputDevice> device = createDeviceLocked(eventHubId, identifier);
    // ... 分析一下createDeviceLocked
}
std::shared_ptr<InputDevice> InputReader::createDeviceLocked(
        int32_t eventHubId, const InputDeviceIdentifier& identifier) {
	// 找到这个设备
    auto deviceIt = std::find_if(mDevices.begin(), mDevices.end(), [identifier](auto& devicePair) {
        return devicePair.second->getDescriptor().size() && identifier.descriptor.size() &&
                devicePair.second->getDescriptor() == identifier.descriptor;
    });

    std::shared_ptr<InputDevice> device;
	// 从map中获取这个设备,如果有则直接获取,没有就创建一个,第一次进来肯定是没有的,所以会走else
    if (deviceIt != mDevices.end()) {
        device = deviceIt->second;
    } else {
        int32_t deviceId = (eventHubId < END_RESERVED_ID) ? eventHubId : nextInputDeviceIdLocked();
        device = std::make_shared<InputDevice>(&mContext, deviceId, bumpGenerationLocked(),
                                               identifier);
    }
	// 然后调用addEventHubDevice,继续分析这个方法
    device->addEventHubDevice(eventHubId);
    return device;
}


// 添加EentHubDevice populateMappers默认为true
void InputDevice::addEventHubDevice(int32_t eventHubId, bool populateMappers) {
    // ... 省略容错代码
    std::unique_ptr<InputDeviceContext> contextPtr(new InputDeviceContext(*this, eventHubId));
    ftl::Flags<InputDeviceClass> classes = contextPtr->getDeviceClasses();
    std::vector<std::unique_ptr<InputMapper>> mappers;

    // ... 省略不会执行的代码

    // ... 省略其他设备类型的判断,我们暂时只分析触摸屏的。

    // 一般来讲我们都是多指触摸,所以是这个if,然后将这个
    if (classes.test(InputDeviceClass::TOUCH_MT)) {
        mappers.push_back(std::make_unique<MultiTouchInputMapper>(*contextPtr));
    } 
	// ... 省略其他设备的的代码
    // insert the context into the devices set
    // mDevices的定义: std::unordered_map<int32_t, DevicePair> mDevices   就是设备id和DevicePair,其中DevicePair包括了InputDeviceContext和mappers
	// 其中每一个InputDeviceContext对应一个类型的事件但看起来也只可能有一个InputDeviceContext,一个Input
    mDevices.insert({eventHubId, std::make_pair(std::move(contextPtr), std::move(mappers))});
    // Must change generation to flag this device as changed
	// 标记设备已更改
    bumpGeneration();
}

继续分析addDeviceLocked

void InputReader::addDeviceLocked(nsecs_t when, int32_t eventHubId) {
   	// ... 省略容错代码
	// 我们在打开设备的时候就保存设备的标识到Device中,所以这里可以直接获取到
    InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(eventHubId);
	// 根据id和identifiel创建InputDeice
    std::shared_ptr<InputDevice> device = createDeviceLocked(eventHubId, identifier);
	// 上面这句代码执行完成InputDevice就创建完成了,也将mapper和eventHubId关联起来了
    device->configure(when, &mConfig, 0);
	device->reset(when);
	// 这里返回false,只要这个设备里面有mapper,就返回false,所以一般走else,就是打印,也没啥用
	 if (device->isIgnored()) {
        ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s' "
              "(ignored non-input device)",
              device->getId(), eventHubId, identifier.name.c_str(), identifier.descriptor.c_str());
    } else {
        ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s',sources=0x%08x",
              device->getId(), eventHubId, identifier.name.c_str(), identifier.descriptor.c_str(),
              device->getSources());
    }
	// 没看懂
    mDevices.emplace(eventHubId, device);
    // Add device to device to EventHub ids map.
	// 将InputDevice和eventHubId 的向量联系到一起,为什么又保存了一次
    const auto mapIt = mDeviceToEventHubIdsMap.find(device);
    if (mapIt == mDeviceToEventHubIdsMap.end()) {
        std::vector<int32_t> ids = {eventHubId};
        mDeviceToEventHubIdsMap.emplace(device, ids);
    } else {
        mapIt->second.push_back(eventHubId);
    }
    // Sensor input device is noisy, to save power disable it by default.
    // Input device is classified as SENSOR when any sub device is a SENSOR device, check Eventhub
    // device class to disable SENSOR sub device only.
	// 默认将sensor关闭
    if (mEventHub->getDeviceClasses(eventHubId).test(InputDeviceClass::SENSOR)) {
        mEventHub->disableDevice(eventHubId);
    }
}
void InputReader::loopOnce() {
    int32_t oldGeneration;
    int32_t timeoutMillis;
    bool inputDevicesChanged = false;
    std::vector<InputDeviceInfo> inputDevices;
    { // acquire lock
        std::scoped_lock _l(mLock);

		// 这个值默认为1,暂时不知道干啥的,先放着
        oldGeneration = mGeneration;
        timeoutMillis = -1;
		// 这个值在构造里面被赋值为0所以下面的if不会进去,暂时不看
        uint32_t changes = mConfigurationChangesToRefresh;
        if (changes) {
            mConfigurationChangesToRefresh = 0;
            timeoutMillis = 0;
            refreshConfigurationLocked(changes);
		// mNextTimeout在构造函数中被赋值为LLONG_MAX,所以暂时不管
        } else if (mNextTimeout != LLONG_MAX) {
            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
            timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
        }
    } // release lock
	// 重点函数,这里返回的是设备的个数,具体逻辑看2.2分析
    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
	
	    { // acquire lock
        std::scoped_lock _l(mLock);
		// 条件变量,暂时不管
        mReaderIsAliveCondition.notify_all();
		// 这里一般不太会为0,所以会进来
        if (count) {
            processEventsLocked(mEventBuffer, count);
        }
		// ... 省略不执行的代码
		// 这里能进来,在添加设备时,这个mGeneration就改变了
		if (oldGeneration != mGeneration) {
            inputDevicesChanged = true;
            inputDevices = getInputDevicesLocked();
        }
    } // release lock

    // Send out a message that the describes the changed input devices.
    if (inputDevicesChanged) {
		// 发出一条消息,设备已更改,这个mPolicy是InputReader
        mPolicy->notifyInputDevicesChanged(inputDevices);
    }

    // 这个是InputDispatcher
    mQueuedListener.flush();
}

所以,第一次调用loopOnce都做了哪些事我们总结一下:

  1. 扫描设备,保存起来
  2. 获取设备信息,将mapper和设备关联起来
  3. 通知InputReader设备更改了
  4. 通知InputDispatcher刷新设备

由于这个是线程函数,threadLoop返回了true,所以这个函数会持续被调用

bool threadLoop() override {
        mThreadLoop();
        return true;
    }


// 所以我们继续分析第二次进来的情况
void InputReader::loopOnce() {
    int32_t oldGeneration;
    int32_t timeoutMillis;
    bool inputDevicesChanged = false;
    std::vector<InputDeviceInfo> inputDevices;
    { // acquire lock
        std::scoped_lock _l(mLock);

		// 当设备没有改变时,这两个是相等的。
        oldGeneration = mGeneration;
        timeoutMillis = -1;
		// 这个值在构造里面被赋值为0所以下面的if不会进去,暂时不看
        uint32_t changes = mConfigurationChangesToRefresh;
        if (changes) {
            mConfigurationChangesToRefresh = 0;
            timeoutMillis = 0;
            refreshConfigurationLocked(changes);
		// mNextTimeout在构造函数中被赋值为LLONG_MAX,所以暂时不管
        } else if (mNextTimeout != LLONG_MAX) {
            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
            timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
        }
    } // release lock
	// 重点函数,这里返回的是事件的个数,继续进去分析
    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
	// ... 省略,先分析第二次进去的情况
}
size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
	
    struct input_event readBuffer[bufferSize];

    RawEvent* event = buffer;
    size_t capacity = bufferSize;
    bool awoken = false;
    for (;;) {
        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
		// 第二次进来也不需要扫描设备了。
		// ... 省略不执行的代码
	
		
        // Grab the next input event.
        bool deviceChanged = false;
		// epoll_wait执行完之后,一般这里就能进去了
        while (mPendingEventIndex < mPendingEventCount) {
			// 获取事件
            const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++];
			// 如果是inotify则给mPendingINotify设置为true,后面肯定会通知的。
            if (eventItem.data.fd == mINotifyFd) {
                if (eventItem.events & EPOLLIN) {
                    mPendingINotify = true;
                } else {
                    ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events);
                }
                continue;
            }

            // ... 省略不是触摸屏的代码,我们暂时只分析触摸屏相关的。
            // This must be an input event
			// 判断这是否是一个可读的,也就是EPOLLIN,一般来讲,肯定是的。
            if (eventItem.events & EPOLLIN) {
				// 获取事件的个数
                int32_t readSize =
                        read(device->fd, readBuffer, sizeof(struct input_event) * capacity);
                // ... 省略容错代码一般走这个
				else {
					// 获取设备ID
                    int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
					
                    size_t count = size_t(readSize) / sizeof(struct input_event);
					// 保存事件信息
                    for (size_t i = 0; i < count; i++) {
                        struct input_event& iev = readBuffer[i];
                        event->when = processEventTimestamp(iev);
                        event->readTime = systemTime(SYSTEM_TIME_MONOTONIC);
                        event->deviceId = deviceId;
                        event->type = iev.type;
                        event->code = iev.code;
                        event->value = iev.value;
                        event += 1;
                        capacity -= 1;
                        // ALOGE("jiangc event->when = %ld   event->readTime = %ld   event->deviceId = %d  event->type = %d   event->code = %d   event->value = %d\n",  
                        // (long)event->when, (long)event->readTime, event->deviceId, event->type, event->code, event->value);
                    }
                }
            } 
			// ... 省略容错代码
        }

        // 当处理完事件转化后,这两个数组又不一样了。
        if (event != buffer || awoken) {
            break;
        }

		// 赋值0
        mPendingEventIndex = 0;
		// 这里就是等待事件的发生,将发生的事件保存到mPendingEventItems中
        int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis);

        mLock.lock(); // reacquire lock after poll
		// 如果是0则没有事情发生
        if (pollResult == 0) {
            // Timed out.
            mPendingEventCount = 0;
            break;
        }
		// 小于0说明出错了
        if (pollResult < 0) {
            // An error occurred.
            mPendingEventCount = 0;

            // Sleep after errors to avoid locking up the system.
            // Hopefully the error is transient.
            if (errno != EINTR) {
                ALOGW("poll failed (errno=%d)\n", errno);
                usleep(100000);
            }
        } else {
            // Some events occurred.
			// 所以一般情况下,会走这里获取一下事件的个数,所以继续for循环,这里就不为0了
            mPendingEventCount = size_t(pollResult);
        }
    }

    // 读取到事件后,这里返回的是事件的个数
    return event - buffer;
}
// 所以我们继续分析第二次进来的情况
void InputReader::loopOnce() {
    int32_t oldGeneration;
    int32_t timeoutMillis;
    bool inputDevicesChanged = false;
    std::vector<InputDeviceInfo> inputDevices;
    { // acquire lock
        std::scoped_lock _l(mLock);

		// 当设备没有改变时,这两个是相等的。
        oldGeneration = mGeneration;
        timeoutMillis = -1;
		// 这个值在构造里面被赋值为0所以下面的if不会进去,暂时不看
        uint32_t changes = mConfigurationChangesToRefresh;
        if (changes) {
            mConfigurationChangesToRefresh = 0;
            timeoutMillis = 0;
            refreshConfigurationLocked(changes);
		// mNextTimeout在构造函数中被赋值为LLONG_MAX,所以暂时不管
        } else if (mNextTimeout != LLONG_MAX) {
            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
            timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
        }
    } // release lock
	// 重点函数,这里返回的是发生事件的个数
    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
	   { // acquire lock
        std::scoped_lock _l(mLock);
        mReaderIsAliveCondition.notify_all();

        if (count) {
			// 这次继续分析其他事件的处理逻辑
            processEventsLocked(mEventBuffer, count);
        }
		
}
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
	// 循环处理所有事件
    for (const RawEvent* rawEvent = rawEvents; count;) {
        int32_t type = rawEvent->type;
        size_t batchSize = 1;
		// 正常的输入类型很小,所以肯定小于它,能进去
        if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
			// 获取设备id
            int32_t deviceId = rawEvent->deviceId;
			// 死循环获取一个设备的事件
            while (batchSize < count) {
				// 这里判断如果事件的deviceid变了,或者type大于FIRST_SYNTHETIC_EVENT,则说明不是一个device的事件要分开处理
                if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT ||
                    rawEvent[batchSize].deviceId != deviceId) {
					// 所以这里跳出while循环,先处理这个device的事件,之后再处理后续的事件
                    break;
                }
                batchSize += 1;
            }
            if (DEBUG_RAW_EVENTS) {
                ALOGD("BatchSize: %zu Count: %zu", batchSize, count);
            }
            processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
        } 
		// ... 省略,因为我们这次不是添加删除事件,所以这里不执行
        count -= batchSize;
        rawEvent += batchSize;
    }
}
void InputReader::processEventsForDeviceLocked(int32_t eventHubId, const RawEvent* rawEvents,
                                               size_t count) {
	// 查找这个设备
    auto deviceIt = mDevices.find(eventHubId);
    if (deviceIt == mDevices.end()) {
        ALOGW("Discarding event for unknown eventHubId %d.", eventHubId);
        return;
    }

    std::shared_ptr<InputDevice>& device = deviceIt->second;
    if (device->isIgnored()) {
        // ALOGD("Discarding event for ignored deviceId %d.", deviceId);
        return;
    }
	// 去处理
    device->process(rawEvents, count);
}
void InputDevice::process(const RawEvent* rawEvents, size_t count) {
    for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
        if (DEBUG_RAW_EVENTS) {
            ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%" PRId64,
                  rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,
                  rawEvent->when);
        }
		// 这个mDropUntilNextSync默认为false,构造函数中初始化的
        if (mDropUntilNextSync) {
            if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
                mDropUntilNextSync = false;
                if (DEBUG_RAW_EVENTS) {
                    ALOGD("Recovered from input event buffer overrun.");
                }
            } else {
                if (DEBUG_RAW_EVENTS) {
                    ALOGD("Dropped input event while waiting for next input sync.");
                }
            }
		// 我们一般也不是SYN_DROPPED而是SYN_REPORT,所以这里也不会进
        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
            ALOGI("Detected input event buffer overrun for device %s.", getName().c_str());
            mDropUntilNextSync = true;
            reset(rawEvent->when);
        } else {
			// 这里遍历这个设备的所有mapper去处理,我们暂时只看触摸的MultiTouchInputMapper
            for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper) {
                mapper.process(rawEvent);
            });
		// 到这里,所有的mapper中都保存了相应的事件了。
        }
        --count;
    }
}
// 以下是多指触控的日志
[    1026.632366] /dev/input/event1: EV_SYN       0004                 00000402       --同步头(其实理论上可以省略)       
[    1026.632366] /dev/input/event1: EV_SYN       0005                 2576d0ba            
[    1026.632366] /dev/input/event1: EV_ABS       ABS_MT_SLOT          00000000        代表第一个手指,其实第一个也可以没有,有的机器就第一次0是没有这个slot    
[    1026.632366] /dev/input/event1: EV_ABS       ABS_MT_TRACKING_ID   00000016         第一个手指对应的TRACKING_ID       
[    1026.632366] /dev/input/event1: EV_ABS       ABS_MT_POSITION_X    0000011a        按下X轴坐标    
[    1026.632366] /dev/input/event1: EV_ABS       ABS_MT_POSITION_Y    00000475        按下Y轴坐标    
[    1026.632366] /dev/input/event1: EV_ABS       ABS_MT_TOUCH_MAJOR   00000003        按下的椭圆长轴    
[    1026.632366] /dev/input/event1: EV_SYN       SYN_REPORT           00000000     --同步尾(不省略)              
[    1027.937528] /dev/input/event1: EV_SYN       0004                 00000403            
[    1027.937528] /dev/input/event1: EV_SYN       0005                 37b18cde            
[    1027.937528] /dev/input/event1: EV_ABS       ABS_MT_POSITION_X    0000011b        这里代表第一个手指移动后坐标     
[    1027.937528] /dev/input/event1: EV_ABS       ABS_MT_POSITION_Y    00000476            
[    1027.937528] /dev/input/event1: EV_SYN       SYN_REPORT           00000000          

[    1028.917333] /dev/input/event1: EV_SYN       0004                 00000404            
[    1028.917333] /dev/input/event1: EV_SYN       0005                 367d836c            
[    1028.917333] /dev/input/event1: EV_ABS       ABS_MT_TOUCH_MINOR   00000003         这里是第一个手指的短轴,因为之前一直是slot为0   
[    1028.917333] /dev/input/event1: EV_ABS       ABS_MT_SLOT          00000001        代表第二手指出来了    
[    1028.917333] /dev/input/event1: EV_ABS       ABS_MT_TRACKING_ID   00000017        第二个手指对应TRACKING_ID
[    1028.917333] /dev/input/event1: EV_ABS       ABS_MT_POSITION_X    00000324          第二手指坐标  
[    1028.917333] /dev/input/event1: EV_ABS       ABS_MT_POSITION_Y    00000165            
[    1028.917333] /dev/input/event1: EV_ABS       ABS_MT_TOUCH_MAJOR   00000002            
[    1028.917333] /dev/input/event1: EV_ABS       ABS_MT_TOUCH_MINOR   00000002            第二个手指短轴
[    1028.917333] /dev/input/event1: EV_SYN       SYN_REPORT           00000000             
[    1029.047446] /dev/input/event1: EV_SYN       0004                 00000405            
[    1029.047446] /dev/input/event1: EV_SYN       0005                 02afd368            
[    1029.047446] /dev/input/event1: EV_ABS       ABS_MT_POSITION_Y    00000166            第二个手指坐标
[    1029.047446] /dev/input/event1: EV_ABS       ABS_MT_TOUCH_MAJOR   00000004            
[    1029.047446] /dev/input/event1: EV_ABS       ABS_MT_TOUCH_MINOR   00000003            
[    1029.047446] /dev/input/event1: EV_SYN       SYN_REPORT           00000000            


void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
	// EV_ABS为触控类型,所以我们可以进来
    if (rawEvent->type == EV_ABS) {
		// 标记是否是新的触点,开始肯定是false
        bool newSlot = false;
		// 是否是B版本的协议,一般是
        if (mUsingSlotsProtocol) {
			// 代表一个新的手指,这里更新值
            if (rawEvent->code == ABS_MT_SLOT) {
                mCurrentSlot = rawEvent->value;
                newSlot = true;
            }
        } else if (mCurrentSlot < 0) {
            mCurrentSlot = 0;
        }
		
        if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) {
            if (DEBUG_POINTERS) {
                if (newSlot) {
                    ALOGW("MultiTouch device emitted invalid slot index %d but it "
                          "should be between 0 and %zd; ignoring this slot.",
                          mCurrentSlot, mSlotCount - 1);
                }
            }
        } else {
            Slot* slot = &mSlots[mCurrentSlot];
            // If mUsingSlotsProtocol is true, it means the raw pointer has axis info of
            // ABS_MT_TRACKING_ID and ABS_MT_SLOT, so driver should send a valid trackingId while
            // updating the slot.
            if (!mUsingSlotsProtocol) {
                slot->mInUse = true;
            }

            switch (rawEvent->code) {
                case ABS_MT_POSITION_X:    // X轴的位置
                    slot->mAbsMTPositionX = rawEvent->value;
                    warnIfNotInUse(*rawEvent, *slot);
                    break;
                case ABS_MT_POSITION_Y:    // Y轴的位置
                    slot->mAbsMTPositionY = rawEvent->value;
                    warnIfNotInUse(*rawEvent, *slot);
                    break;
                case ABS_MT_TOUCH_MAJOR:    // 按下的椭圆长轴
                    slot->mAbsMTTouchMajor = rawEvent->value;
                    break;
                case ABS_MT_TOUCH_MINOR:     // 按下的椭圆短轴
                    slot->mAbsMTTouchMinor = rawEvent->value;
                    slot->mHaveAbsMTTouchMinor = true;
                    break;
                case ABS_MT_WIDTH_MAJOR:
                    slot->mAbsMTWidthMajor = rawEvent->value;
                    break;
                case ABS_MT_WIDTH_MINOR:
                    slot->mAbsMTWidthMinor = rawEvent->value;
                    slot->mHaveAbsMTWidthMinor = true;
                    break;
                case ABS_MT_ORIENTATION:
                    slot->mAbsMTOrientation = rawEvent->value;
                    break;
                case ABS_MT_TRACKING_ID:     这里就是上面日至中的,tracking_id ,value,一般不会为0,0说明不使用了,
                    if (mUsingSlotsProtocol && rawEvent->value < 0) {
                        // The slot is no longer in use but it retains its previous contents,
                        // which may be reused for subsequent touches.
                        slot->mInUse = false;
                    } else {
                        slot->mInUse = true;
                        slot->mAbsMTTrackingId = rawEvent->value;
                    }
                    break;
                case ABS_MT_PRESSURE:
                    slot->mAbsMTPressure = rawEvent->value;
                    break;
                case ABS_MT_DISTANCE:
                    slot->mAbsMTDistance = rawEvent->value;
                    break;
                case ABS_MT_TOOL_TYPE:
                    slot->mAbsMTToolType = rawEvent->value;
                    slot->mHaveAbsMTToolType = true;
                    break;
            }
        }
    } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
        // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
        mCurrentSlot += 1;
    }
}
// 当所有的手指触摸事件都采集完成之后,就开始同步所有的事件状态
void TouchInputMapper::process(const RawEvent* rawEvent) {
    mCursorButtonAccumulator.process(rawEvent);
    mCursorScrollAccumulator.process(rawEvent);
    mTouchButtonAccumulator.process(rawEvent);
	// 这里代表一个手指的结束事件
    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
        sync(rawEvent->when, rawEvent->readTime);
    }
}

void TouchInputMapper::sync(nsecs_t when, nsecs_t readTime) {
    // 在末尾插入一个RawState
    mRawStatesPending.emplace_back();
	// 然后取出来最后一个,就是上面插入的。
    RawState& next = mRawStatesPending.back();
	// 清理
    next.clear();
	// 赋值时间
    next.when = when;
    next.readTime = readTime;

    // ... 省略暂时不分析的。

    // Sync touch
    syncTouch(when, &next);
	// ... 省略
}


void MultiTouchInputMapper::syncTouch(nsecs_t when, RawState* outState) {
    // 获取总共几个slot
    size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
    // 当前从第0个开始
    size_t outCount = 0;
    // 描述哪些位是被标记的,也就u是说当前这个地方有手指
    BitSet32 newPointerIdBits;
    mHavePointerIds = true;
    // 遍历当前所有的slot
    for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
        // 获取第一个slot
        const MultiTouchMotionAccumulator::Slot* inSlot =
                mMultiTouchMotionAccumulator.getSlot(inIndex);
        // 检查是否被使用,如果没有被使用则直接continue
        if (!inSlot->isInUse()) {
            continue;
        }
        // 获取触摸工具的类型,我们只讨论手指的,这个是手掌的,暂不考虑
        if (inSlot->getToolType() == AMOTION_EVENT_TOOL_TYPE_PALM) {
            std::optional<int32_t> id = getActiveBitId(*inSlot);
            if (id) {
                outState->rawPointerData.canceledIdBits.markBit(id.value());
            }
            if (DEBUG_POINTERS) {
                ALOGI("Stop processing slot %zu for it received a palm event from device %s",
                      inIndex, getDeviceName().c_str());
            }
            continue;
        }
        // 容错,如果大于最大支持的多点触控,则报错
        if (outCount >= MAX_POINTERS) {
            if (DEBUG_POINTERS) {
                ALOGD("MultiTouch device %s emitted more than maximum of %zu pointers; "
                      "ignoring the rest.",
                      getDeviceName().c_str(), MAX_POINTERS);
            }
            break; // too many fingers!
        }

        // 将slot转换成RawPointerData
        RawPointerData::Pointer& outPointer = outState->rawPointerData.pointers[outCount];
        outPointer.x = inSlot->getX();
        outPointer.y = inSlot->getY();
        outPointer.pressure = inSlot->getPressure();
        outPointer.touchMajor = inSlot->getTouchMajor();
        outPointer.touchMinor = inSlot->getTouchMinor();
        outPointer.toolMajor = inSlot->getToolMajor();
        outPointer.toolMinor = inSlot->getToolMinor();
        outPointer.orientation = inSlot->getOrientation();
        outPointer.distance = inSlot->getDistance();
        outPointer.tiltX = 0;
        outPointer.tiltY = 0;

        // 判断当前是什么类型的输入工具类型
        outPointer.toolType = inSlot->getToolType();
        if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
            outPointer.toolType = mTouchButtonAccumulator.getToolType();
            if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
                outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
            }
        }
        // 判断是否支持电容笔,如果支持则返回true,暂时不关心
        if (shouldSimulateStylusWithTouch() &&
            outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER) {
            outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
        }   
        // 不知道干啥的,估计是鼠标相关的。暂时不管
        bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE &&
                (mTouchButtonAccumulator.isHovering() ||
                 (mRawPointerAxes.pressure.valid && inSlot->getPressure() <= 0));
        outPointer.isHovering = isHovering;

        // Assign pointer id using tracking id if available.
        // 这个变量前面直接初始化为true了,所以这里能进去
        if (mHavePointerIds) {
            // 获取trackingId
            int32_t trackingId = inSlot->getTrackingId();
            int32_t id = -1;
            // 都大于0
            if (trackingId >= 0) {
                // 这个变量开始应该是空的 !idBits.isEmpty()如果返回true,则for循环就无法进去
                for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty();) {
                    // 找到第一个1,并将它置位成0
                    uint32_t n = idBits.clearFirstMarkedBit();
                    if (mPointerTrackingIdMap[n] == trackingId) {
                        id = n;
                    }
                }
                // !mPointerIdBits.isFull()这个函数的意思是如果不包含任何未被标记的位则返回true,开始mPointerIdBits全0,所以进入这个if
                if (id < 0 && !mPointerIdBits.isFull()) {
                    // 将第一个非1的位标记为1,并返回位置,比如说第一次肯定是第0位,id也就等于0,以次类推
                    id = mPointerIdBits.markFirstUnmarkedBit();
                    // 将trackingId保存到mPointerTrackingIdMap数组的id位置上
                    mPointerTrackingIdMap[id] = trackingId;
                }
            }
            // 前面id已经被赋值了,这里就进不去了。
            if (id < 0) {
                mHavePointerIds = false;
                outState->rawPointerData.clearIdBits();
                newPointerIdBits.clear();
            } else {   // 走else
                outPointer.id = id;   // 这里就代表了mPointerTrackingIdMap的下标
                outState->rawPointerData.idToIndex[id] = outCount;   // 表示它保存在这个数组中的下标
                outState->rawPointerData.markIdBit(id, isHovering);  
                newPointerIdBits.markBit(id);   // 这里将newPointerIdBits的第id位mark成1
            }
        }
        outCount += 1;
    }

    outState->rawPointerData.pointerCount = outCount;
    mPointerIdBits = newPointerIdBits;

    mMultiTouchMotionAccumulator.finishSync();
}

到此为止,已经将slot保存为RawState了

void TouchInputMapper::sync(nsecs_t when, nsecs_t readTime) {
    // 在末尾插入一个RawState
    mRawStatesPending.emplace_back();
	// 然后取出来最后一个,就是上面插入的。
    RawState& next = mRawStatesPending.back();
	// 清理
    next.clear();
	// 赋值时间
    next.when = when;
    next.readTime = readTime;

    // ... 省略暂时不分析的。

    // Sync touch
    syncTouch(when, &next);
	    // The last RawState is the actually second to last, since we just added a new state
    // rebegin()获取一个反向的迭代器,这里的index是1,所以是获取的倒数第二个.
    const RawState& last =
            mRawStatesPending.size() == 1 ? mCurrentRawState : mRawStatesPending.rbegin()[1];

	// ... 省略不执行的。

    // 开始处理Raw
    processRawTouches(false /*timeout*/);
}

继续分析

void TouchInputMapper::processRawTouches(bool timeout) {
    // 是否关闭了,一般不会出现这个
    if (mDeviceMode == DeviceMode::DISABLED) {
        // Drop all input if the device is disabled.
        cancelTouch(mCurrentRawState.when, mCurrentRawState.readTime);
        mCurrentCookedState.clear();
        updateTouchSpots();
        return;
    }

    // Drain any pending touch states. The invariant here is that the mCurrentRawState is always
    // valid and must go through the full cook and dispatch cycle. This ensures that anything
    // touching the current state will only observe the events that have been dispatched to the
    // rest of the pipeline.
    // 获取RawState的数量
    const size_t N = mRawStatesPending.size();
    size_t count;
    // 遍历所有的RawState
    for (count = 0; count < N; count++) {
        const RawState& next = mRawStatesPending[count];

        // A failure to assign the stylus id means that we're waiting on stylus data
        // and so should defer the rest of the pipeline.
        if (assignExternalStylusId(next, timeout)) {
            break;
        }

        // 将next的值拷贝到mCurrentRawState
        mCurrentRawState.copyFrom(next);
        if (mCurrentRawState.when < mLastRawState.when) {
            mCurrentRawState.when = mLastRawState.when;
            mCurrentRawState.readTime = mLastRawState.readTime;
        }
        // 加工事件和分发事件
        cookAndDispatch(mCurrentRawState.when, mCurrentRawState.readTime);
    }
	// ... 暂时省略
}
// 对原始数据进行加工和分发
void TouchInputMapper::cookAndDispatch(nsecs_t when, nsecs_t readTime) {
    // Always start with a clean state.
    // 这个对象就是保存加工过的事件的,在开始加工之前先清理
    mCurrentCookedState.clear();

    // Apply stylus buttons to current raw state.
    applyExternalStylusButtonState(when);

    // Handle policy on initial down or hover events.
    bool initialDown = mLastRawState.rawPointerData.pointerCount == 0 &&
            mCurrentRawState.rawPointerData.pointerCount != 0;

    uint32_t policyFlags = 0;
    // 检测当前是否被按下
    bool buttonsPressed = mCurrentRawState.buttonState & ~mLastRawState.buttonState;
    // ... 省略非触摸的代码
    // 加工pointerdata
    cookPointerData();

	// ... 省略,先分析cookPointerData()
}
// 代码很多,主要是用于处理缩放,矫正等,最后保存为mCurrentCookedState
void TouchInputMapper::cookPointerData() {
    uint32_t currentPointerCount = mCurrentRawState.rawPointerData.pointerCount;

    mCurrentCookedState.cookedPointerData.clear();
    mCurrentCookedState.cookedPointerData.pointerCount = currentPointerCount;
    mCurrentCookedState.cookedPointerData.hoveringIdBits =
            mCurrentRawState.rawPointerData.hoveringIdBits;
    mCurrentCookedState.cookedPointerData.touchingIdBits =
            mCurrentRawState.rawPointerData.touchingIdBits;
    mCurrentCookedState.cookedPointerData.canceledIdBits =
            mCurrentRawState.rawPointerData.canceledIdBits;

    if (mCurrentCookedState.cookedPointerData.pointerCount == 0) {
        mCurrentCookedState.buttonState = 0;
    } else {
        mCurrentCookedState.buttonState = mCurrentRawState.buttonState;
    }

    // Walk through the the active pointers and map device coordinates onto
    // display coordinates and adjust for display orientation.
    for (uint32_t i = 0; i < currentPointerCount; i++) {
        const RawPointerData::Pointer& in = mCurrentRawState.rawPointerData.pointers[i];

        // Size
        float touchMajor, touchMinor, toolMajor, toolMinor, size;
        switch (mCalibration.sizeCalibration) {
            case Calibration::SizeCalibration::GEOMETRIC:
            case Calibration::SizeCalibration::DIAMETER:
            case Calibration::SizeCalibration::BOX:
            case Calibration::SizeCalibration::AREA:
                if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.toolMajor.valid) {
                    touchMajor = in.touchMajor;
                    touchMinor = mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
                    toolMajor = in.toolMajor;
                    toolMinor = mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
                    size = mRawPointerAxes.touchMinor.valid ? avg(in.touchMajor, in.touchMinor)
                                                            : in.touchMajor;
                } else if (mRawPointerAxes.touchMajor.valid) {
                    toolMajor = touchMajor = in.touchMajor;
                    toolMinor = touchMinor =
                            mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
                    size = mRawPointerAxes.touchMinor.valid ? avg(in.touchMajor, in.touchMinor)
                                                            : in.touchMajor;
                } else if (mRawPointerAxes.toolMajor.valid) {
                    touchMajor = toolMajor = in.toolMajor;
                    touchMinor = toolMinor =
                            mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
                    size = mRawPointerAxes.toolMinor.valid ? avg(in.toolMajor, in.toolMinor)
                                                           : in.toolMajor;
                } else {
                    ALOG_ASSERT(false,
                                "No touch or tool axes.  "
                                "Size calibration should have been resolved to NONE.");
                    touchMajor = 0;
                    touchMinor = 0;
                    toolMajor = 0;
                    toolMinor = 0;
                    size = 0;
                }

                if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) {
                    uint32_t touchingCount = mCurrentRawState.rawPointerData.touchingIdBits.count();
                    if (touchingCount > 1) {
                        touchMajor /= touchingCount;
                        touchMinor /= touchingCount;
                        toolMajor /= touchingCount;
                        toolMinor /= touchingCount;
                        size /= touchingCount;
                    }
                }

                if (mCalibration.sizeCalibration == Calibration::SizeCalibration::GEOMETRIC) {
                    touchMajor *= mGeometricScale;
                    touchMinor *= mGeometricScale;
                    toolMajor *= mGeometricScale;
                    toolMinor *= mGeometricScale;
                } else if (mCalibration.sizeCalibration == Calibration::SizeCalibration::AREA) {
                    touchMajor = touchMajor > 0 ? sqrtf(touchMajor) : 0;
                    touchMinor = touchMajor;
                    toolMajor = toolMajor > 0 ? sqrtf(toolMajor) : 0;
                    toolMinor = toolMajor;
                } else if (mCalibration.sizeCalibration == Calibration::SizeCalibration::DIAMETER) {
                    touchMinor = touchMajor;
                    toolMinor = toolMajor;
                }

                mCalibration.applySizeScaleAndBias(&touchMajor);
                mCalibration.applySizeScaleAndBias(&touchMinor);
                mCalibration.applySizeScaleAndBias(&toolMajor);
                mCalibration.applySizeScaleAndBias(&toolMinor);
                size *= mSizeScale;
                break;
            default:
                touchMajor = 0;
                touchMinor = 0;
                toolMajor = 0;
                toolMinor = 0;
                size = 0;
                break;
        }

        // Pressure
        float pressure;
        switch (mCalibration.pressureCalibration) {
            case Calibration::PressureCalibration::PHYSICAL:
            case Calibration::PressureCalibration::AMPLITUDE:
                pressure = in.pressure * mPressureScale;
                break;
            default:
                pressure = in.isHovering ? 0 : 1;
                break;
        }

        // Tilt and Orientation
        float tilt;
        float orientation;
        if (mHaveTilt) {
            float tiltXAngle = (in.tiltX - mTiltXCenter) * mTiltXScale;
            float tiltYAngle = (in.tiltY - mTiltYCenter) * mTiltYScale;
            orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
            tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
        } else {
            tilt = 0;

            switch (mCalibration.orientationCalibration) {
                case Calibration::OrientationCalibration::INTERPOLATED:
                    orientation = in.orientation * mOrientationScale;
                    break;
                case Calibration::OrientationCalibration::VECTOR: {
                    int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
                    int32_t c2 = signExtendNybble(in.orientation & 0x0f);
                    if (c1 != 0 || c2 != 0) {
                        orientation = atan2f(c1, c2) * 0.5f;
                        float confidence = hypotf(c1, c2);
                        float scale = 1.0f + confidence / 16.0f;
                        touchMajor *= scale;
                        touchMinor /= scale;
                        toolMajor *= scale;
                        toolMinor /= scale;
                    } else {
                        orientation = 0;
                    }
                    break;
                }
                default:
                    orientation = 0;
            }
        }

        // Distance
        float distance;
        switch (mCalibration.distanceCalibration) {
            case Calibration::DistanceCalibration::SCALED:
                distance = in.distance * mDistanceScale;
                break;
            default:
                distance = 0;
        }

        // Coverage
        int32_t rawLeft, rawTop, rawRight, rawBottom;
        switch (mCalibration.coverageCalibration) {
            case Calibration::CoverageCalibration::BOX:
                rawLeft = (in.toolMinor & 0xffff0000) >> 16;
                rawRight = in.toolMinor & 0x0000ffff;
                rawBottom = in.toolMajor & 0x0000ffff;
                rawTop = (in.toolMajor & 0xffff0000) >> 16;
                break;
            default:
                rawLeft = rawTop = rawRight = rawBottom = 0;
                break;
        }

        // Adjust X,Y coords for device calibration
        // TODO: Adjust coverage coords?
        float xTransformed = in.x, yTransformed = in.y;
        mAffineTransform.applyTo(xTransformed, yTransformed);
        rotateAndScale(xTransformed, yTransformed);

        // Adjust X, Y, and coverage coords for input device orientation.
        float left, top, right, bottom;

        switch (mInputDeviceOrientation) {
            case DISPLAY_ORIENTATION_90:
                left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale;
                right = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale;
                bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale;
                top = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale;
                orientation -= M_PI_2;
                if (mOrientedRanges.haveOrientation &&
                    orientation < mOrientedRanges.orientation.min) {
                    orientation +=
                            (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
                }
                break;
            case DISPLAY_ORIENTATION_180:
                left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale;
                right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale;
                bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale;
                top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale;
                orientation -= M_PI;
                if (mOrientedRanges.haveOrientation &&
                    orientation < mOrientedRanges.orientation.min) {
                    orientation +=
                            (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
                }
                break;
            case DISPLAY_ORIENTATION_270:
                left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale;
                right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale;
                bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale;
                top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale;
                orientation += M_PI_2;
                if (mOrientedRanges.haveOrientation &&
                    orientation > mOrientedRanges.orientation.max) {
                    orientation -=
                            (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
                }
                break;
            default:
                left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale;
                right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale;
                bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale;
                top = float(rawTop - mRawPointerAxes.y.minValue) * mYScale;
                break;
        }

        // Write output coords.
        PointerCoords& out = mCurrentCookedState.cookedPointerData.pointerCoords[i];
        out.clear();
        out.setAxisValue(AMOTION_EVENT_AXIS_X, xTransformed);
        out.setAxisValue(AMOTION_EVENT_AXIS_Y, yTransformed);
        out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
        out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
        out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
        out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);
        out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
        if (mCalibration.coverageCalibration == Calibration::CoverageCalibration::BOX) {
            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_1, left);
            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_2, top);
            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_3, right);
            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_4, bottom);
        } else {
            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
        }

        // Write output relative fields if applicable.
        uint32_t id = in.id;
        if (mSource == AINPUT_SOURCE_TOUCHPAD &&
            mLastCookedState.cookedPointerData.hasPointerCoordsForId(id)) {
            const PointerCoords& p = mLastCookedState.cookedPointerData.pointerCoordsForId(id);
            float dx = xTransformed - p.getAxisValue(AMOTION_EVENT_AXIS_X);
            float dy = yTransformed - p.getAxisValue(AMOTION_EVENT_AXIS_Y);
            out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, dx);
            out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, dy);
        }

        // Write output properties.
        PointerProperties& properties = mCurrentCookedState.cookedPointerData.pointerProperties[i];
        properties.clear();
        properties.id = id;
        properties.toolType = in.toolType;

        // Write id index and mark id as valid.
        mCurrentCookedState.cookedPointerData.idToIndex[id] = i;
        mCurrentCookedState.cookedPointerData.validIdBits.markBit(id);
    }
}
void TouchInputMapper::cookAndDispatch(nsecs_t when, nsecs_t readTime) {
    // Always start with a clean state.
    // 这个对象就是保存加工过的事件的,在开始加工之前先清理
    mCurrentCookedState.clear();

    // Apply stylus buttons to current raw state.
    applyExternalStylusButtonState(when);

    // Handle policy on initial down or hover events.
    bool initialDown = mLastRawState.rawPointerData.pointerCount == 0 &&
            mCurrentRawState.rawPointerData.pointerCount != 0;

    uint32_t policyFlags = 0;
    // 检测当前是否被按下
    bool buttonsPressed = mCurrentRawState.buttonState & ~mLastRawState.buttonState;
    // 下面和辅助显示当前坐标相关,暂时不分析
    if (initialDown || buttonsPressed) {
        // If this is a touch screen, hide the pointer on an initial down.
        if (mDeviceMode == DeviceMode::DIRECT) {
            getContext()->fadePointer();
        }

        if (mParameters.wake) {
            policyFlags |= POLICY_FLAG_WAKE;
        }
    }

	// ... 省略

    // 加工pointerdata
    cookPointerData();

	// ... 省略

    // Dispatch the touches either directly or by translation through a pointer on screen.
    if (mDeviceMode == DeviceMode::POINTER) {
   		// ... 省略
    } else {
        if (!mCurrentMotionAborted) {
			// ... 省略非触摸事件分发
            dispatchTouches(when, readTime, policyFlags);

        }
		// ... 省略,后面分析
}
// touch事件分发的主要函数
void TouchInputMapper::dispatchTouches(nsecs_t when, nsecs_t readTime, uint32_t policyFlags) {
    BitSet32 currentIdBits = mCurrentCookedState.cookedPointerData.touchingIdBits;
    BitSet32 lastIdBits = mLastCookedState.cookedPointerData.touchingIdBits;
    int32_t metaState = getContext()->getGlobalMetaState();
    int32_t buttonState = mCurrentCookedState.buttonState;
	
	// 如果,上一次和当前的一样,但是又有事件发生,那说明是move
    if (currentIdBits == lastIdBits) {
        if (!currentIdBits.isEmpty()) {
            // No pointer id changes so this is a move event.
            // The listener takes care of batching moves so we don't have to deal with that here.
            dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_MOVE, 0, 0,
                           metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
                           mCurrentCookedState.cookedPointerData.pointerProperties,
                           mCurrentCookedState.cookedPointerData.pointerCoords,
                           mCurrentCookedState.cookedPointerData.idToIndex, currentIdBits, -1,
                           mOrientedXPrecision, mOrientedYPrecision, mDownTime);
        }
    } else {   // 如果不一样,则判断一下是那些事件发生。
        // There may be pointers going up and pointers going down and pointers moving
        // all at the same time.
		//         1100 0000 0000 0000 0000 0000 0000 0000   last
		//         0100 0000 0000 0000 0000 0000 0000 0000   current
		// 取反    1011 1111 1111 1111 1111 1111 1111 1111
        // 按位于  1100 0000 0000 0000 0000 0000 0000 0000   last
        //         1000 0000 0000 0000 0000 0000 0000 0000  可以看到第一位是1,也就找到哪个trackingId是up事件了,其他类似
        BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value);        
        BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
        BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
        BitSet32 dispatchedIdBits(lastIdBits.value);

        // Update last coordinates of pointers that have moved so that we observe the new
        // pointer positions at the same time as other pointers that have just gone up.
        bool moveNeeded =
                updateMovedPointers(mCurrentCookedState.cookedPointerData.pointerProperties,
                                    mCurrentCookedState.cookedPointerData.pointerCoords,
                                    mCurrentCookedState.cookedPointerData.idToIndex,
                                    mLastCookedState.cookedPointerData.pointerProperties,
                                    mLastCookedState.cookedPointerData.pointerCoords,
                                    mLastCookedState.cookedPointerData.idToIndex, moveIdBits);
        if (buttonState != mLastCookedState.buttonState) {
            moveNeeded = true;
        }

        // Dispatch pointer up events.
        while (!upIdBits.isEmpty()) {
            uint32_t upId = upIdBits.clearFirstMarkedBit();
            bool isCanceled = mCurrentCookedState.cookedPointerData.canceledIdBits.hasBit(upId);
            if (isCanceled) {
                ALOGI("Canceling pointer %d for the palm event was detected.", upId);
            }
            dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_POINTER_UP, 0,
                           isCanceled ? AMOTION_EVENT_FLAG_CANCELED : 0, metaState, buttonState, 0,
                           mLastCookedState.cookedPointerData.pointerProperties,
                           mLastCookedState.cookedPointerData.pointerCoords,
                           mLastCookedState.cookedPointerData.idToIndex, dispatchedIdBits, upId,
                           mOrientedXPrecision, mOrientedYPrecision, mDownTime);
            dispatchedIdBits.clearBit(upId);
            mCurrentCookedState.cookedPointerData.canceledIdBits.clearBit(upId);
        }

        // Dispatch move events if any of the remaining pointers moved from their old locations.
        // Although applications receive new locations as part of individual pointer up
        // events, they do not generally handle them except when presented in a move event.
        if (moveNeeded && !moveIdBits.isEmpty()) {
            ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
            dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_MOVE, 0, 0,
                           metaState, buttonState, 0,
                           mCurrentCookedState.cookedPointerData.pointerProperties,
                           mCurrentCookedState.cookedPointerData.pointerCoords,
                           mCurrentCookedState.cookedPointerData.idToIndex, dispatchedIdBits, -1,
                           mOrientedXPrecision, mOrientedYPrecision, mDownTime);
        }

        // Dispatch pointer down events using the new pointer locations.
        while (!downIdBits.isEmpty()) {
            uint32_t downId = downIdBits.clearFirstMarkedBit();
            dispatchedIdBits.markBit(downId);

            if (dispatchedIdBits.count() == 1) {
                // First pointer is going down.  Set down time.
                mDownTime = when;
            }
			// 事件分发
            dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_POINTER_DOWN,
                           0, 0, metaState, buttonState, 0,
                           mCurrentCookedState.cookedPointerData.pointerProperties,
                           mCurrentCookedState.cookedPointerData.pointerCoords,
                           mCurrentCookedState.cookedPointerData.idToIndex, dispatchedIdBits,
                           downId, mOrientedXPrecision, mOrientedYPrecision, mDownTime);
        }
    }
}
// 事件分发的关键方法
void TouchInputMapper::dispatchMotion(nsecs_t when, nsecs_t readTime, 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) {
    PointerCoords pointerCoords[MAX_POINTERS];
    PointerProperties pointerProperties[MAX_POINTERS];
    uint32_t pointerCount = 0;
    while (!idBits.isEmpty()) {
        uint32_t id = idBits.clearFirstMarkedBit();
        uint32_t index = idToIndex[id];
        pointerProperties[pointerCount].copyFrom(properties[index]);
        pointerCoords[pointerCount].copyFrom(coords[index]);

        if (changedId >= 0 && id == uint32_t(changedId)) {
            action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
        }

        pointerCount += 1;
    }

    ALOG_ASSERT(pointerCount != 0);

    if (changedId >= 0 && pointerCount == 1) {
        // Replace initial down and final up action.
        // We can compare the action without masking off the changed pointer index
        // because we know the index is 0.
        if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
            action = AMOTION_EVENT_ACTION_DOWN;
        } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
            if ((flags & AMOTION_EVENT_FLAG_CANCELED) != 0) {
                action = AMOTION_EVENT_ACTION_CANCEL;
            } else {
                action = AMOTION_EVENT_ACTION_UP;
            }
        } else {
            // Can't happen.
            ALOG_ASSERT(false);
        }
    }
    float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
    float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
    if (mDeviceMode == DeviceMode::POINTER) {
        mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
    }
    const int32_t displayId = getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE);
    const int32_t deviceId = getDeviceId();
    std::vector<TouchVideoFrame> frames = getDeviceContext().getVideoFrames();
    std::for_each(frames.begin(), frames.end(),
                  [this](TouchVideoFrame& frame) { frame.rotate(this->mInputDeviceOrientation); });
	// 关键参数构建,这个就是可以认为是MotionEent了
    NotifyMotionArgs args(getContext()->getNextId(), when, readTime, deviceId, source, displayId,
                          policyFlags, action, actionButton, flags, metaState, buttonState,
                          MotionClassification::NONE, edgeFlags, pointerCount, pointerProperties,
                          pointerCoords, xPrecision, yPrecision, xCursorPosition, yCursorPosition,
                          downTime, std::move(frames));
	// getListener返回的其实是InputDispater的包装类
    getListener().notifyMotion(&args);
}
InputListenerInterface& InputReader::ContextImpl::getListener() {
    return mReader->mQueuedListener;
}

// 可以看到这个mQueuedListener就是在构建InputReader的时候传进来的,再看调用构造函数的地方
InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
                         const sp<InputReaderPolicyInterface>& policy,
                         InputListenerInterface& listener)
      : mContext(this),
        mEventHub(eventHub),
        mPolicy(policy),
        mQueuedListener(listener),
        mGlobalMetaState(AMETA_NONE),
        mLedMetaState(AMETA_NONE),
        mGeneration(1),
        mNextInputDeviceId(END_RESERVED_ID),
        mDisableVirtualKeysTimeout(LLONG_MIN),
        mNextTimeout(LLONG_MAX),
        mConfigurationChangesToRefresh(0) {
    refreshConfigurationLocked(0);
    updateGlobalMetaStateLocked();
}

// 调用构造函数的地方,第二个参数就是listener
std::unique_ptr<InputReaderInterface> createInputReader(
        const sp<InputReaderPolicyInterface>& policy, InputListenerInterface& listener) {
            // 同样的,这里也是创建了一个InputReader,并且传入了一个EentHub,和NativeInputManager以及InputDispatcher
    return std::make_unique<InputReader>(std::make_unique<EventHub>(), policy, listener);
}

InputManager::InputManager(
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
    // 创建一个inputDispatcher
    mDispatcher = createInputDispatcher(dispatcherPolicy);
    // 这下面又包装了两次,暂时不管
    mClassifier = std::make_unique<InputClassifier>(*mDispatcher);
    mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mClassifier);
    // 创建一个inputReader,把readerPolicy和inputdispatcher传进去,这里第二个参数传的是dispatcherPolicy的包装类,我们去看包装类的notifyMotion
    mReader = createInputReader(readerPolicy, *mBlocker);
}
// 包装类的notifymotion函数,调用了notifyMotionLocked
void UnwantedInteractionBlocker::notifyMotion(const NotifyMotionArgs* args) {
    { // acquire lock
        std::scoped_lock lock(mLock);
        const std::vector<NotifyMotionArgs> processedArgs =
                mPreferStylusOverTouchBlocker.processMotion(*args);
        for (const NotifyMotionArgs& loopArgs : processedArgs) {
            notifyMotionLocked(&loopArgs);
        }
    } // release lock

    // Call out to the next stage without holding the lock
    mQueuedListener.flush();
}
// 最终都调用了mQueuedListener的notifyMotion方法,我们看一下mQueuedListener是啥
void UnwantedInteractionBlocker::notifyMotionLocked(const NotifyMotionArgs* args) {
    auto it = mPalmRejectors.find(args->deviceId);
    const bool sendToPalmRejector = it != mPalmRejectors.end() && isFromTouchscreen(args->source);
    if (!sendToPalmRejector) {
        mQueuedListener.notifyMotion(args);
        return;
    }
    std::vector<NotifyMotionArgs> processedArgs = it->second.processMotion(*args);
    for (const NotifyMotionArgs& loopArgs : processedArgs) {
        mQueuedListener.notifyMotion(&loopArgs);
    }
}

UnwantedInteractionBlocker::UnwantedInteractionBlocker(InputListenerInterface& listener)
      : UnwantedInteractionBlocker(listener, isPalmRejectionEnabled()){};

UnwantedInteractionBlocker::UnwantedInteractionBlocker(InputListenerInterface& listener,
                                                       bool enablePalmRejection)
      : mQueuedListener(listener), mEnablePalmRejection(enablePalmRejection) {}

// 是构造函数,再去看构造调用,UnwantedInteractionBlocker的构造函数传的是mClassifier,那就是说实际上调用了mClassifier的notify,继续看
    mDispatcher = createInputDispatcher(dispatcherPolicy);
    mClassifier = std::make_unique<InputClassifier>(*mDispatcher);
    mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mClassifier);
// mClassifier的构造方法其实就是mDispatcher
InputClassifier::InputClassifier(InputListenerInterface& listener) : mQueuedListener(listener) {}
// 接着看InputClassifier的notify,到这就明白了,一层调一层,最后调到InputDispatcher
void InputClassifier::notifyMotion(const NotifyMotionArgs* args) {
    { // acquire lock
        std::scoped_lock lock(mLock);
        // MotionClassifier is only used for touch events, for now
        const bool sendToMotionClassifier = mMotionClassifier && isTouchEvent(*args);
        if (!sendToMotionClassifier) {
            mQueuedListener.notifyMotion(args);
        } else {
            NotifyMotionArgs newArgs(*args);
            newArgs.classification = mMotionClassifier->classify(newArgs);
            mQueuedListener.notifyMotion(&newArgs);
        }
    } // release lock
    mQueuedListener.flush();
}
// 我们在看flush
void QueuedInputListener::flush() {
    for (const std::unique_ptr<NotifyArgs>& args : mArgsQueue) {
        args->notify(mInnerListener);
    }
    mArgsQueue.clear();
}

void NotifyPointerCaptureChangedArgs::notify(InputListenerInterface& listener) const {
    listener.notifyPointerCaptureChanged(this);
}

// 也就是说,flush调用之后会回调到设置的listener的notifyPointerCaptureChanged
// 不用看代码我们也可以猜到,应该是InputDispatcher的notifyPointerCaptureChanged
// 去看看,果然有,这里就不分析了,后面在分析InputDispatcher的时候再分析
void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
    if (DEBUG_INBOUND_EVENT_DETAILS) {
        ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
    }

    bool needWake = false;
    { // acquire lock
        std::scoped_lock _l(mLock);

        std::unique_ptr<ConfigurationChangedEntry> newEntry =
                std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
        needWake = enqueueInboundEventLocked(std::move(newEntry));
    } // release lock

    if (needWake) {
        mLooper->wake();
    }
}

到此为止,InputReader分析完成了

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无敌的娃哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值