您的位置:首页 > 移动开发 > Android开发

android input系统如何导入kl文件

2015-10-19 16:20 429 查看
首先在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<KeyLayoutMap>* 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<KeyLayoutMap> 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;

}

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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: