android input系统如何导入kl文件
16lz
2022-06-16
首先在size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize)里有个
if (mNeedToScanDevices) {
mNeedToScanDevices = false;
ALOGE("matt-mNeedToScanDevices");
scanDevicesLocked();
mNeedToSendFinishedDeviceScan = true;
}//每次新的input设备加入的时候就会调用这个函数
void EventHub::scanDevicesLocked() {
status_t res = scanDirLocked(DEVICE_PATH);
if(res < 0) {
ALOGE("scan dir failed for %s\n", DEVICE_PATH);
}
if (mDevices.indexOfKey(VIRTUAL_KEYBOARD_ID) < 0) {
createVirtualKeyboardLocked();
}
}
进入status_t EventHub::scanDirLocked(const char *dirname)
{
char devname[PATH_MAX];
char *filename;
DIR *dir;
struct dirent *de;
dir = opendir(dirname);
if(dir == NULL)
return -1;
strcpy(devname, dirname);
filename = devname + strlen(devname);
*filename++ = '/';
while((de = readdir(dir))) {
if(de->d_name[0] == '.' &&
(de->d_name[1] == '\0' ||
(de->d_name[1] == '.' && de->d_name[2] == '\0')))
continue;
strcpy(filename, de->d_name);
openDeviceLocked(devname);
}
closedir(dir);
return 0;
}
再进入
status_t EventHub::openDeviceLocked(const char *devicePath)
里头有一句话 loadConfigurationLocked(device);
status_t EventHub::openDeviceLocked(const char *devicePath) {
......
int32_t deviceId = mNextDeviceId++;
Device* device = new Device(fd, deviceId, String8(devicePath), identifier);
//先获取device
//对于touchscren来说device->identifier.name就是ft5x06_ts
// Load the configuration file for the device.
loadConfigurationLocked(device); //获取对应的idc文件
.....
if (device->classes & (INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_JOYSTICK)) {
// Load the keymap for the device.
ALOGE("matt-keyMapStatus = loadKeyMapLocked(device)");
keyMapStatus = loadKeyMapLocked(device); //获取对应的kl文件
}
}
接着到void EventHub::loadConfigurationLocked(Device* device) {
device->configurationFile = getInputDeviceConfigurationFilePathByDeviceIdentifier(
device->identifier, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION);
//INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION是个type类型
//这个类型的结构体在
//enum InputDeviceConfigurationFileType {
INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0, /* .idc file */
INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1, /* .kl file */
INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file */
};
// 所以一开始会尝试去找idc文件
status_t status = PropertyMap::load(device->configurationFile, //如果返回的路径不是空值则调用load
&device->configuration);
}
接着看String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
const InputDeviceIdentifier& deviceIdentifier,
InputDeviceConfigurationFileType type) {
.....
ALOGE("matt-getInputDeviceConfigurationFilePathByDeviceIdentifier");
if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) {
if (deviceIdentifier.version != 0) {
// Try vendor product version.
ALOGE("matt-1");
String8 versionPath(getInputDeviceConfigurationFilePathByName(
String8::format("Vendor_%04x_Product_%04x_Version_%04x",
deviceIdentifier.vendor, deviceIdentifier.product,
deviceIdentifier.version),
type));
if (!versionPath.isEmpty()) {
return versionPath;
}
}
ALOGE("matt-2");
// Try vendor product.
String8 productPath(getInputDeviceConfigurationFilePathByName(
String8::format("Vendor_%04x_Product_%04x",
deviceIdentifier.vendor, deviceIdentifier.product),
type));
if (!productPath.isEmpty()) {
return productPath;
}
}
ALOGE("matt-3=%s",deviceIdentifier.name.string());
// Try device name.
return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type);
//touchscreen直接走最下面的getInputDeviceConfigurationFilePathByName
}
到tring8 getInputDeviceConfigurationFilePathByName(
const String8& name, InputDeviceConfigurationFileType type) {
// Search system repository.
String8 path;
ALOGE("matt-getInputDeviceConfigurationFilePathByName");
path.setTo(getenv("ANDROID_ROOT"));
path.append("/usr/");
appendInputDeviceConfigurationFileRelativePath(path, name, type);
ALOGE("matt-path1=%s",path.string());
if (!access(path.string(), R_OK)) {
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);
ALOGE("matt-path2=%s",path.string());
if (!access(path.string(), R_OK)) {
return path;
}
return String8(); //如果拼凑出来的路径不可用则直接返回空值 由于第一次进来找的是idc文件而我们只放了kl文件所以返回为0
}
回头看keyMapStatus = loadKeyMapLocked(device)
status_t EventHub::loadKeyMapLocked(Device* device) {
return device->keyMap.load(device->identifier, device->configuration);
}
status_t KeyMap::load(const InputDeviceIdentifier& deviceIdenfifier,
const PropertyMap* deviceConfiguration) {
// Try searching by device identifier.
if (probeKeyMap(deviceIdenfifier, String8::empty())) { //获取kl文件
return OK;
}
if (!haveKeyCharacterMap()) {
loadKeyCharacterMap(deviceIdentifier, keyMapName); //获取kcm文件原理与上面相同
}
}
看bool KeyMap::probeKeyMap(const InputDeviceIdentifier& deviceIdentifier,
const String8& keyMapName) {
if (!haveKeyLayout()) {
loadKeyLayout(deviceIdentifier, keyMapName);
}
}
继续status_t KeyMap::loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier,
const String8& name) {
ALOGE("matt-loadKeyLayout 1");
String8 path(getPath(deviceIdentifier, name,INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT));
//这里的
}
继续String8 KeyMap::getPath(const InputDeviceIdentifier& deviceIdentifier,
const String8& name, InputDeviceConfigurationFileType type) {
return name.isEmpty()
? getInputDeviceConfigurationFilePathByDeviceIdentifier(deviceIdentifier, type)
: getInputDeviceConfigurationFilePathByName(name, type);
}
这里跑的是getInputDeviceConfigurationFilePathByName,之后
最后都是跑到了
status_t KeyLayoutMap::load(const String8& filename, sp* outMap) {
outMap->clear();
Tokenizer* tokenizer;
status_t status = Tokenizer::open(filename, &tokenizer);
if (status) {
ALOGE("Error %d opening key layout map file %s.", status, filename.string());
} else {
sp map = new KeyLayoutMap();
if (!map.get()) {
ALOGE("Error allocating key layout map.");
status = NO_MEMORY;
} else {
#if DEBUG_PARSER_PERFORMANCE
nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
#endif
Parser parser(map.get(), tokenizer);
status = parser.parse();
#if DEBUG_PARSER_PERFORMANCE
nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
ALOGD("Parsed key layout map file '%s' %d lines in %0.3fms.",
tokenizer->getFilename().string(), tokenizer->getLineNumber(),
elapsedTime / 1000000.0);
#endif
if (!status) {
*outMap = map;
}
}
delete tokenizer;
}
return status;
if (mNeedToScanDevices) {
mNeedToScanDevices = false;
ALOGE("matt-mNeedToScanDevices");
scanDevicesLocked();
mNeedToSendFinishedDeviceScan = true;
}//每次新的input设备加入的时候就会调用这个函数
void EventHub::scanDevicesLocked() {
status_t res = scanDirLocked(DEVICE_PATH);
if(res < 0) {
ALOGE("scan dir failed for %s\n", DEVICE_PATH);
}
if (mDevices.indexOfKey(VIRTUAL_KEYBOARD_ID) < 0) {
createVirtualKeyboardLocked();
}
}
进入status_t EventHub::scanDirLocked(const char *dirname)
{
char devname[PATH_MAX];
char *filename;
DIR *dir;
struct dirent *de;
dir = opendir(dirname);
if(dir == NULL)
return -1;
strcpy(devname, dirname);
filename = devname + strlen(devname);
*filename++ = '/';
while((de = readdir(dir))) {
if(de->d_name[0] == '.' &&
(de->d_name[1] == '\0' ||
(de->d_name[1] == '.' && de->d_name[2] == '\0')))
continue;
strcpy(filename, de->d_name);
openDeviceLocked(devname);
}
closedir(dir);
return 0;
}
再进入
status_t EventHub::openDeviceLocked(const char *devicePath)
里头有一句话 loadConfigurationLocked(device);
status_t EventHub::openDeviceLocked(const char *devicePath) {
......
int32_t deviceId = mNextDeviceId++;
Device* device = new Device(fd, deviceId, String8(devicePath), identifier);
//先获取device
//对于touchscren来说device->identifier.name就是ft5x06_ts
// Load the configuration file for the device.
loadConfigurationLocked(device); //获取对应的idc文件
.....
if (device->classes & (INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_JOYSTICK)) {
// Load the keymap for the device.
ALOGE("matt-keyMapStatus = loadKeyMapLocked(device)");
keyMapStatus = loadKeyMapLocked(device); //获取对应的kl文件
}
}
接着到void EventHub::loadConfigurationLocked(Device* device) {
device->configurationFile = getInputDeviceConfigurationFilePathByDeviceIdentifier(
device->identifier, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION);
//INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION是个type类型
//这个类型的结构体在
//enum InputDeviceConfigurationFileType {
INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0, /* .idc file */
INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1, /* .kl file */
INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file */
};
// 所以一开始会尝试去找idc文件
status_t status = PropertyMap::load(device->configurationFile, //如果返回的路径不是空值则调用load
&device->configuration);
}
接着看String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
const InputDeviceIdentifier& deviceIdentifier,
InputDeviceConfigurationFileType type) {
.....
ALOGE("matt-getInputDeviceConfigurationFilePathByDeviceIdentifier");
if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) {
if (deviceIdentifier.version != 0) {
// Try vendor product version.
ALOGE("matt-1");
String8 versionPath(getInputDeviceConfigurationFilePathByName(
String8::format("Vendor_%04x_Product_%04x_Version_%04x",
deviceIdentifier.vendor, deviceIdentifier.product,
deviceIdentifier.version),
type));
if (!versionPath.isEmpty()) {
return versionPath;
}
}
ALOGE("matt-2");
// Try vendor product.
String8 productPath(getInputDeviceConfigurationFilePathByName(
String8::format("Vendor_%04x_Product_%04x",
deviceIdentifier.vendor, deviceIdentifier.product),
type));
if (!productPath.isEmpty()) {
return productPath;
}
}
ALOGE("matt-3=%s",deviceIdentifier.name.string());
// Try device name.
return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type);
//touchscreen直接走最下面的getInputDeviceConfigurationFilePathByName
}
到tring8 getInputDeviceConfigurationFilePathByName(
const String8& name, InputDeviceConfigurationFileType type) {
// Search system repository.
String8 path;
ALOGE("matt-getInputDeviceConfigurationFilePathByName");
path.setTo(getenv("ANDROID_ROOT"));
path.append("/usr/");
appendInputDeviceConfigurationFileRelativePath(path, name, type);
ALOGE("matt-path1=%s",path.string());
if (!access(path.string(), R_OK)) {
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);
ALOGE("matt-path2=%s",path.string());
if (!access(path.string(), R_OK)) {
return path;
}
return String8(); //如果拼凑出来的路径不可用则直接返回空值 由于第一次进来找的是idc文件而我们只放了kl文件所以返回为0
}
回头看keyMapStatus = loadKeyMapLocked(device)
status_t EventHub::loadKeyMapLocked(Device* device) {
return device->keyMap.load(device->identifier, device->configuration);
}
status_t KeyMap::load(const InputDeviceIdentifier& deviceIdenfifier,
const PropertyMap* deviceConfiguration) {
// Try searching by device identifier.
if (probeKeyMap(deviceIdenfifier, String8::empty())) { //获取kl文件
return OK;
}
if (!haveKeyCharacterMap()) {
loadKeyCharacterMap(deviceIdentifier, keyMapName); //获取kcm文件原理与上面相同
}
}
看bool KeyMap::probeKeyMap(const InputDeviceIdentifier& deviceIdentifier,
const String8& keyMapName) {
if (!haveKeyLayout()) {
loadKeyLayout(deviceIdentifier, keyMapName);
}
}
继续status_t KeyMap::loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier,
const String8& name) {
ALOGE("matt-loadKeyLayout 1");
String8 path(getPath(deviceIdentifier, name,INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT));
//这里的
}
继续String8 KeyMap::getPath(const InputDeviceIdentifier& deviceIdentifier,
const String8& name, InputDeviceConfigurationFileType type) {
return name.isEmpty()
? getInputDeviceConfigurationFilePathByDeviceIdentifier(deviceIdentifier, type)
: getInputDeviceConfigurationFilePathByName(name, type);
}
这里跑的是getInputDeviceConfigurationFilePathByName,之后
最后都是跑到了
status_t KeyLayoutMap::load(const String8& filename, sp
outMap->clear();
Tokenizer* tokenizer;
status_t status = Tokenizer::open(filename, &tokenizer);
if (status) {
ALOGE("Error %d opening key layout map file %s.", status, filename.string());
} else {
sp
if (!map.get()) {
ALOGE("Error allocating key layout map.");
status = NO_MEMORY;
} else {
#if DEBUG_PARSER_PERFORMANCE
nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
#endif
Parser parser(map.get(), tokenizer);
status = parser.parse();
#if DEBUG_PARSER_PERFORMANCE
nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
ALOGD("Parsed key layout map file '%s' %d lines in %0.3fms.",
tokenizer->getFilename().string(), tokenizer->getLineNumber(),
elapsedTime / 1000000.0);
#endif
if (!status) {
*outMap = map;
}
}
delete tokenizer;
}
return status;
}
static void appendInputDeviceConfigurationFileRelativePath(String8& path, //这里组成了path
const String8& name, InputDeviceConfigurationFileType type) {
path.append(CONFIGURATION_FILE_DIR[type]); //这里选了文件夹"idc/", "keylayout/", "keychars/",
for (size_t i = 0; i < name.length(); i++) {
char ch = name[i];
if (!isValidNameChar(ch)) {
ch = '_';
}
path.append(&ch, 1); //把ft5x06_ts加到/system/usr/keylayout/之后
}
path.append(CONFIGURATION_FILE_EXTENSION[type]);//根据type加kl或者kcm或者idc
}
更多相关文章
- Android(安卓)调用相册或相机选择图片
- android 返回键 退出
- Android创建XMl文件
- android获取google邮箱
- android各种图片获取路径的方式
- Android获取、设置Wifi状态
- 【Android】【基础】获取屏幕宽高
- NPM 和webpack 的基础使用
- 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程