void EventHub::loadConfigurationLocked(Device* device) {
device->configurationFile = getInputDeviceConfigurationFilePathByDeviceIdentifier(
device->identifier, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION);//get IDC文件
if (device->configurationFile.isEmpty()) {
ALOGD("No input device configuration file found for device '%s'.",
device->identifier.name.string());
} else {
status_t status = PropertyMap::load(device->configurationFile,
&device->configuration);//找到配置文件,解析出来保存到device->configuration中
if (status) {//解析出错,
ALOGE("Error loading input device configuration file for device '%s'. "
"Using default configuration.",
device->identifier.name.string());
}
}
}
String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
const InputDeviceIdentifier& deviceIdentifier,
InputDeviceConfigurationFileType type) {
if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) {
if (deviceIdentifier.version != 0) {
// Try vendor product version.
String8 versionPath(getInputDeviceConfigurationFilePathByName(
String8::format("Vendor_%04x_Product_%04x_Version_%04x",
deviceIdentifier.vendor, deviceIdentifier.product,
deviceIdentifier.version),
type));
if (!versionPath.isEmpty()) {
return versionPath;
}
}
// Try vendor product.
String8 productPath(getInputDeviceConfigurationFilePathByName(
String8::format("Vendor_%04x_Product_%04x",
deviceIdentifier.vendor, deviceIdentifier.product),
type));
if (!productPath.isEmpty()) {
return productPath;
}
}
// Try device name.
return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type);
}
String8 getInputDeviceConfigurationFilePathByName(
const String8& name, InputDeviceConfigurationFileType type) {
// Search system repository.
String8 path;
path.setTo(getenv("ANDROID_ROOT"));
path.append("/usr/");
appendInputDeviceConfigurationFileRelativePath(path, name, type);
#if DEBUG_PROBE
ALOGD("Probing for system provided input device configuration file: path='%s'", path.string());
#endif
if (!access(path.string(), R_OK)) {
#if DEBUG_PROBE
ALOGD("Found");
#endif
return path;
}
// Search user repository.
// TODO Should only look here if not in safe mode.
path.setTo(getenv("ANDROID_DATA"));
path.append("/system/devices/");
appendInputDeviceConfigurationFileRelativePath(path, name, type);
#if DEBUG_PROBE
ALOGD("Probing for system user input device configuration file: path='%s'", path.string());
#endif
if (!access(path.string(), R_OK)) {
#if DEBUG_PROBE
ALOGD("Found");
#endif
return path;
}
// Not found.
#if DEBUG_PROBE
ALOGD("Probe failed to find input device configuration file: name='%s', type=%d",
name.string(), type);
#endif
return String8();
}
这里出现了两个环境变量:
echo $ANDROID_ROOT /system
echo $ANDROID_DATA /data
识别和匹配配置文件的顺序为:
/system/usr/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc
/data/system/devices/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc
/system/usr/idc/Vendor_XXXX_Product_XXXX.idc
/data/system/devices/idc/Vendor_XXXX_Product_XXXX.idc
/system/usr/idc/DEVICE_NAME.idc
/data/system/devices/idc/DEVICE_NAME.idc
需要注意的是文件名中的数字需要小写。例如
input_dev>id.vendor = 0xDEAD;
input_dev>id.product = 0xBEEF;
input_dev>id.version = 0x0102;
对应的配置文件名应该是Vendor_dead_Product_beef_Version_0102.idc或者Vendor_dead_Product_beef.idc。
获取配置文件名的时候,如果发现文件名中含有不是ascii(<=0x7f)的字符;或者是ascii,但不是数字,不是希腊字母,也不是“-”和“_”,比如说空格、tab等,就要转成字符'_'。所以dumpsys input看到的ConfigurationFile: /system/usr/idc/Vendor_dead_Product_beef.idc,也许和我们定义的有点不一样,那就是定义了非法字符,被转了。只要找到ConfigurationFile就可以了。