函数首先根据文件名来打开这个设备文件:

  1. fd=open(deviceName,O_RDWR);

系统中所有输入设备文件信息都保存在成员变量mDevicesById中,因此,先在mDevicesById找到一个空位置来保存当前打开的设备文件信息:

  1. mDevicesById[devid].seq=(mDevicesById[devid].seq+(1<<SEQ_SHIFT))&SEQ_MASK;
  2. if(mDevicesById[devid].seq==0){
  3. mDevicesById[devid].seq=1<<SEQ_SHIFT;
  4. }

找到了空闲位置后,就为这个输入设备文件创建相应的device_t信息:

  1. mDevicesById[devid].seq=(mDevicesById[devid].seq+(1<<SEQ_SHIFT))&SEQ_MASK;
  2. if(mDevicesById[devid].seq==0){
  3. mDevicesById[devid].seq=1<<SEQ_SHIFT;
  4. }
  5. new_mFDs=(pollfd*)realloc(mFDs,sizeof(mFDs[0])*(mFDCount+1));
  6. new_devices=(device_t**)realloc(mDevices,sizeof(mDevices[0])*(mFDCount+1));
  7. if(new_mFDs==NULL||new_devices==NULL){
  8. LOGE("outofmemory");
  9. return-1;
  10. }
  11. mFDs=new_mFDs;
  12. mDevices=new_devices;
  13. ......
  14. device_t*device=newdevice_t(devid|mDevicesById[devid].seq,deviceName,name);
  15. if(device==NULL){
  16. LOGE("outofmemory");
  17. return-1;
  18. }
  19. device->fd=fd;

同时,这个设备文件还会保存在数组mFDs中:

  1. mFDs[mFDCount].fd=fd;
  2. mFDs[mFDCount].events=POLLIN;
  3. mFDs[mFDCount].revents=0;

接下来查看这个设备是不是键盘:

  1. //Figureoutthekindsofeventsthedevicereports.
  2. uint8_tkey_bitmask[sizeof_bit_array(KEY_MAX+1)];
  3. memset(key_bitmask,0,sizeof(key_bitmask));
  4. LOGV("Gettingkeys...");
  5. if(ioctl(fd,EVIOCGBIT(EV_KEY,sizeof(key_bitmask)),key_bitmask)>=0){
  6. //Seeifthisisakeyboard.Ignoreeverythinginthebuttonrangeexceptfor
  7. //gamepadswhicharealsoconsideredkeyboards.
  8. if(containsNonZeroByte(key_bitmask,0,sizeof_bit_array(BTN_MISC))
  9. ||containsNonZeroByte(key_bitmask,sizeof_bit_array(BTN_GAMEPAD),
  10. sizeof_bit_array(BTN_DIGI))
  11. ||containsNonZeroByte(key_bitmask,sizeof_bit_array(KEY_OK),
  12. sizeof_bit_array(KEY_MAX+1))){
  13. device->classes|=INPUT_DEVICE_CLASS_KEYBOARD;
  14. device->keyBitmask=newuint8_t[sizeof(key_bitmask)];
  15. if(device->keyBitmask!=NULL){
  16. memcpy(device->keyBitmask,key_bitmask,sizeof(key_bitmask));
  17. }else{
  18. deletedevice;
  19. LOGE("outofmemoryallocatingkeybitmask");
  20. return-1;
  21. }
  22. }
  23. }

如果是的话,还要继续进一步初始化前面为这个设备文件所创建的device_t结构体,主要就是把结构体device的classes成员变量的INPUT_DEVICE_CLASS_KEYBOARD位置为1了,以表明这是一个键盘。
如果是键盘设备,初始化工作还未完成,还要继续设置键盘的布局等信息:

  1. if((device->classes&INPUT_DEVICE_CLASS_KEYBOARD)!=0){
  2. chartmpfn[sizeof(name)];
  3. charkeylayoutFilename[300];
  4. //amoredescriptivename
  5. device->name=name;
  6. //replaceallthespaceswithunderscores
  7. strcpy(tmpfn,name);
  8. for(char*p=strchr(tmpfn,'');p&&*p;p=strchr(tmpfn,''))
  9. *p='_';
  10. //findthe.klfileweneedforthisdevice
  11. constchar*root=getenv("ANDROID_ROOT");
  12. snprintf(keylayoutFilename,sizeof(keylayoutFilename),
  13. "%s/usr/keylayout/%s.kl",root,tmpfn);
  14. booldefaultKeymap=false;
  15. if(access(keylayoutFilename,R_OK)){
  16. snprintf(keylayoutFilename,sizeof(keylayoutFilename),
  17. "%s/usr/keylayout/%s",root,"qwerty.kl");
  18. defaultKeymap=true;
  19. }
  20. status_tstatus=device->layoutMap->load(keylayoutFilename);
  21. if(status){
  22. LOGE("Error%dloadingkeylayout.",status);
  23. }
  24. //telltheworldaboutthedevname(thedescriptivename)
  25. if(!mHaveFirstKeyboard&&!defaultKeymap&&strstr(name,"-keypad")){
  26. //thebuilt-inkeyboardhasawell-knowndeviceIDof0,
  27. //thisdevicebetternotgoaway.
  28. mHaveFirstKeyboard=true;
  29. mFirstKeyboardId=device->id;
  30. property_set("hw.keyboards.0.devname",name);
  31. }else{
  32. //ensuremFirstKeyboardIdissetto-something-.
  33. if(mFirstKeyboardId==0){
  34. mFirstKeyboardId=device->id;
  35. }
  36. }
  37. charpropName[100];
  38. sprintf(propName,"hw.keyboards.%u.devname",device->id);
  39. property_set(propName,name);
  40. //'Q'keysupport=cheaptestofwhetherthisisanalpha-capablekbd
  41. if(hasKeycodeLocked(device,AKEYCODE_Q)){
  42. device->classes|=INPUT_DEVICE_CLASS_ALPHAKEY;
  43. }
  44. //SeeifthisdevicehasaDPAD.
  45. if(hasKeycodeLocked(device,AKEYCODE_DPAD_UP)&&
  46. hasKeycodeLocked(device,AKEYCODE_DPAD_DOWN)&&
  47. hasKeycodeLocked(device,AKEYCODE_DPAD_LEFT)&&
  48. hasKeycodeLocked(device,AKEYCODE_DPAD_RIGHT)&&
  49. hasKeycodeLocked(device,AKEYCODE_DPAD_CENTER)){
  50. device->classes|=INPUT_DEVICE_CLASS_DPAD;
  51. }
  52. //Seeifthisdevicehasagamepad.
  53. for(size_ti=0;i<sizeof(GAMEPAD_KEYCODES)/sizeof(GAMEPAD_KEYCODES[0]);i++){
  54. if(hasKeycodeLocked(device,GAMEPAD_KEYCODES[i])){
  55. device->classes|=INPUT_DEVICE_CLASS_GAMEPAD;
  56. break;
  57. }
  58. }
  59. LOGI("Newkeyboard:device->id=0x%xdevname='%s'propName='%s'keylayout='%s'\n",
  60. device->id,name,propName,keylayoutFilename);
  61. }

到这里,系统中的输入设备文件就打开了。

更多相关文章

  1. Android(安卓)Studio基础:USB联调App
  2. 电脑导出文件到手机 adb push
  3. Android(安卓)NDK r5 windows系统上安装与使用
  4. Doze和App Standby的优化(API23)
  5. cocos2dx3.0打包注意事项
  6. Android(安卓)反编译:加固前后对比
  7. FileProvider的使用
  8. Android(安卓)多语言开发
  9. android 上传文件到 spring 搭建的后台

随机推荐

  1. android 图表引擎AChartEngine(柱状图)
  2. Android(安卓)显示大图片
  3. Android(安卓)SDcard目录文件操作
  4. 【Android】使用ConnectivityManager与Ne
  5. Android动态设置控件高度
  6. Android(安卓)Studio 打包方式
  7. [转]Android文字跑马灯控件
  8. 各种奇妙的hack
  9. Android(安卓)Intent传递对象和集合
  10. android intent深入解析