Android应用程序键盘(Keyboard)消息处理机制分析(6)

Step 21. EventHub.openDevice
这个函数定义在frameworks/base/libs/ui/EventHub.cpp文件中:

  1. int EventHub::openDevice(const char *deviceName) {   
  2.     int version;   
  3.     int fd;   
  4.     struct pollfd *new_mFDs;   
  5.     device_t **new_devices;   
  6.     char **new_device_names;   
  7.     char name[80];   
  8.     char location[80];   
  9.     char idstr[80];   
  10.     struct input_id id;   
  11.    
  12.     LOGV("Opening device: %s", deviceName);   
  13.    
  14.     AutoMutex _l(mLock);   
  15.    
  16.     fd = open(deviceName, O_RDWR);   
  17.     if(fd < 0) {   
  18.         LOGE("could not open %s, %s\n", deviceName, strerror(errno));   
  19.         return -1;   
  20.     }   
  21.    
  22.     ......   
  23.    
  24.     int devid = 0;   
  25.     while (devid < mNumDevicesById) {   
  26.         if (mDevicesById[devid].device == NULL) {   
  27.             break;   
  28.         }   
  29.         devid++;   
  30.     }   
  31.        
  32.     ......   
  33.    
  34.     mDevicesById[devid].seq = (mDevicesById[devid].seq+(1<<SEQ_SHIFT))&SEQ_MASK;   
  35.     if (mDevicesById[devid].seq == 0) {   
  36.         mDevicesById[devid].seq = 1<<SEQ_SHIFT;   
  37.     }   
  38.    
  39.     new_mFDs = (pollfd*)realloc(mFDs, sizeof(mFDs[0]) * (mFDCount + 1));   
  40.     new_devices = (device_t**)realloc(mDevices, sizeof(mDevices[0]) * (mFDCount + 1));   
  41.     if (new_mFDs == NULL || new_devices == NULL) {   
  42.         LOGE("out of memory");   
  43.         return -1;   
  44.     }   
  45.     mFDs = new_mFDs;   
  46.     mDevices = new_devices;   
  47.    
  48.     ......   
  49.    
  50.     device_t* device = new device_t(devid|mDevicesById[devid].seq, deviceName, name);   
  51.     if (device == NULL) {   
  52.         LOGE("out of memory");   
  53.         return -1;   
  54.     }   
  55.    
  56.     device->fd = fd;   
  57.     mFDs[mFDCount].fd = fd;   
  58.     mFDs[mFDCount].events = POLLIN;   
  59.     mFDs[mFDCount].revents = 0;   
  60.    
  61.     // Figure out the kinds of events the device reports.   
  62.    
  63.     uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];   
  64.     memset(key_bitmask, 0, sizeof(key_bitmask));   
  65.    
  66.     LOGV("Getting keys...");   
  67.     if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) {   
  68.         // See if this is a keyboard.  Ignore everything in the button range except for   
  69.         // gamepads which are also considered keyboards.   
  70.         if (containsNonZeroByte(key_bitmask, 0, sizeof_bit_array(BTN_MISC))   
  71.             || containsNonZeroByte(key_bitmask, sizeof_bit_array(BTN_GAMEPAD),   
  72.             sizeof_bit_array(BTN_DIGI))   
  73.             || containsNonZeroByte(key_bitmask, sizeof_bit_array(KEY_OK),   
  74.             sizeof_bit_array(KEY_MAX + 1))) {   
  75.                 device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;   
  76.    
  77.                 device->keyBitmask = new uint8_t[sizeof(key_bitmask)];   
  78.                 if (device->keyBitmask != NULL) {   
  79.                     memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));   
  80.                 } else {   
  81.                     delete device;   
  82.                     LOGE("out of memory allocating key bitmask");   
  83.                     return -1;   
  84.                 }   
  85.         }   
  86.     }   
  87.    
  88.     ......   
  89.    
  90.     if ((device->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0) {   
  91.         char tmpfn[sizeof(name)];   
  92.         char keylayoutFilename[300];   
  93.    
  94.         // a more descriptive name   
  95.         device->name = name;   
  96.    
  97.         // replace all the spaces with underscores   
  98.         strcpy(tmpfn, name);   
  99.         for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ' '))   
  100.             *p = '_';   
  101.    
  102.         // find the .kl file we need for this device   
  103.         const char* root = getenv("ANDROID_ROOT");   
  104.         snprintf(keylayoutFilename, sizeof(keylayoutFilename),   
  105.             "%s/usr/keylayout/%s.kl", root, tmpfn);   
  106.         bool defaultKeymap = false;   
  107.         if (access(keylayoutFilename, R_OK)) {   
  108.             snprintf(keylayoutFilename, sizeof(keylayoutFilename),   
  109.                 "%s/usr/keylayout/%s", root, "qwerty.kl");   
  110.             defaultKeymap = true;   
  111.         }   
  112.         status_t status = device->layoutMap->load(keylayoutFilename);   
  113.         if (status) {   
  114.             LOGE("Error %d loading key layout.", status);   
  115.         }   
  116.    
  117.         // tell the world about the devname (the descriptive name)   
  118.         if (!mHaveFirstKeyboard && !defaultKeymap && strstr(name"-keypad")) {   
  119.             // the built-in keyboard has a well-known device ID of 0,   
  120.             // this device better not go away.   
  121.             mHaveFirstKeyboard = true;   
  122.             mFirstKeyboardId = device->id;   
  123.             property_set("hw.keyboards.0.devname"name);   
  124.         } else {   
  125.             // ensure mFirstKeyboardId is set to -something-.   
  126.             if (mFirstKeyboardId == 0) {   
  127.                 mFirstKeyboardId = device->id;   
  128.             }   
  129.         }   
  130.         char propName[100];   
  131.         sprintf(propName, "hw.keyboards.%u.devname", device->id);   
  132.         property_set(propName, name);   
  133.    
  134.         // 'Q' key support = cheap test of whether this is an alpha-capable kbd   
  135.         if (hasKeycodeLocked(device, AKEYCODE_Q)) {   
  136.             device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY;   
  137.         }   
  138.    
  139.         // See if this device has a DPAD.   
  140.         if (hasKeycodeLocked(device, AKEYCODE_DPAD_UP) &&   
  141.             hasKeycodeLocked(device, AKEYCODE_DPAD_DOWN) &&   
  142.             hasKeycodeLocked(device, AKEYCODE_DPAD_LEFT) &&   
  143.             hasKeycodeLocked(device, AKEYCODE_DPAD_RIGHT) &&   
  144.             hasKeycodeLocked(device, AKEYCODE_DPAD_CENTER)) {   
  145.                 device->classes |= INPUT_DEVICE_CLASS_DPAD;   
  146.         }   
  147.    
  148.         // See if this device has a gamepad.   
  149.         for (size_t i = 0; i < sizeof(GAMEPAD_KEYCODES)/sizeof(GAMEPAD_KEYCODES[0]); i++) {   
  150.             if (hasKeycodeLocked(device, GAMEPAD_KEYCODES[i])) {   
  151.                 device->classes |= INPUT_DEVICE_CLASS_GAMEPAD;   
  152.                 break;   
  153.             }   
  154.         }   
  155.    
  156.         LOGI("New keyboard: device->id=0x%x devname='%s' propName='%s' keylayout='%s'\n",   
  157.             device->id, name, propName, keylayoutFilename);   
  158.     }   
  159.    
  160.     ......   
  161.    
  162.     mDevicesById[devid].device = device;   
  163.     device->next = mOpeningDevices;   
  164.     mOpeningDevices = device;   
  165.     mDevices[mFDCount] = device;   
  166.    
  167.     mFDCount++;   
  168.     return 0;   
  169. }   




本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966617,如需转载请自行联系原作者
上一篇:Web APi之消息处理管道(五)


下一篇:Ansible源码解析Inventory总管概念__init__.py