voidEventHub::openDeviceLocked(const std::string& devicePath){//如果目标路径是当前已存在的设备(之前扫描过的设备)的,就不再扫描这个路径了,避免出现重复设备for(constauto&[deviceId, device]: mDevices){if(device->path == devicePath){return;// device was already registered}}char buffer[80];ALOGV("Opening device: %s", devicePath.c_str());//通过open打开设备节点,返回该设备节点的fdint fd =open(devicePath.c_str(), O_RDWR | O_CLOEXEC | O_NONBLOCK);
InputDeviceIdentifier identifier;//一个硬件设备的结构体在用户空间中描述, 包括name、vendor、product、descriptor等// Get device name.//获取设备 device nameif(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;}// Check to see if the device is on our excluded list//通过device name检测下这个设备是不是在排除名单,如果是就忽略这个设备for(size_t i =0; i < mExcludedDevices.size(); i++){const std::string& item = mExcludedDevices[i];if(identifier.name == item){ALOGI("ignoring event id %s driver %s\n", devicePath.c_str(), item.c_str());close(fd);return;}}// Get device driver version.//获取设备驱动版本int driverVersion;if(ioctl(fd, EVIOCGVERSION,&driverVersion)){}// Get device identifier.//获取设备的identifier,是设备在内核空间的描述//内核描述为input_id结构体,内容为:bustype、product、product、versionstructinput_id inputId;if(ioctl(fd, EVIOCGID,&inputId)){}
identifier.bus = inputId.bustype;
identifier.product = inputId.product;
identifier.vendor = inputId.product;
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.//获取设备的unique 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.// 获取设备的descriptor,这个字段很重要,它是用于标识这个设备的标识符,无论重启、拔插、升级都不会变//根据unique_id、vendor_id、product_id、随机数组合后sha1转化生成,赋值给identifier.descriptorassignDescriptorLocked(identifier);// Allocate device. (The device object takes ownership of the fd at this point.)//创建Device结构体,用于描述当前从驱动获取到的这个输入设备,将前面获取的设备fd、设备节点路径devicePath、设备硬件描述identifier赋给这个Device,//同时还有deviceId,这个id并不是驱动传上来的,而是我们每次通过ioctl获取到新设备时计数 + 1int32_t deviceId = mNextDeviceId++;
std::unique_ptr<Device> device = std::make_unique<Device>(fd, deviceId, devicePath, identifier);//