Support non-orientation aware keyboards and other devices.

Fixed a bug with dpad keys on external keyboards being rotated
according to the display orientation by adding a new input device
configuration property called "keyboard.orientationAware".

Added a mechanism for overriding the key layout and key character
map in the input device configuration file using the new
"keyboard.layout" and "keyboard.characterMap" properties.

Also added "trackball.orientationAware", "touch.orientationAware" and
"touch.deviceType" configuration properties.

Rewrote the configuration property reading code in native code
so that it can be used by EventHub and other components.

Added basic support for installable idc, kl, and kcm files
in /data/system/devices.  However, there is no provision for
copying files there yet.

Disabled long-press character pickers on full keyboards so that
key repeating works as expected.

Change-Id: I1bd9f0c3d344421db444e7d271eb09bc8bab4791
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index f468217..f831086 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -93,12 +93,13 @@
 
 EventHub::device_t::device_t(int32_t _id, const char* _path, const char* name)
     : id(_id), path(_path), name(name), classes(0)
-    , keyBitmask(NULL), layoutMap(NULL), fd(-1), next(NULL) {
+    , keyBitmask(NULL), layoutMap(NULL), configuration(NULL), fd(-1), next(NULL) {
 }
 
 EventHub::device_t::~device_t() {
     delete [] keyBitmask;
     delete layoutMap;
+    delete configuration;
 }
 
 EventHub::EventHub(void)
@@ -144,6 +145,16 @@
     return device->classes;
 }
 
+void EventHub::getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const {
+    outConfiguration->clear();
+
+    AutoMutex _l(mLock);
+    device_t* device = getDeviceLocked(deviceId);
+    if (device && device->configuration) {
+        *outConfiguration = *device->configuration;
+    }
+}
+
 status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
         RawAbsoluteAxisInfo* outAxisInfo) const {
     outAxisInfo->clear();
@@ -716,6 +727,9 @@
     mFDs[mFDCount].events = POLLIN;
     mFDs[mFDCount].revents = 0;
 
+    // Load the configuration file for the device.
+    loadConfiguration(device);
+
     // Figure out the kinds of events the device reports.
     
     uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
@@ -803,7 +817,6 @@
         device->name = name;
 
         // Configure the keymap for the device.
-
         configureKeyMap(device);
 
         // Tell the world about the devname (the descriptive name)
@@ -868,9 +881,11 @@
         return -1;
     }
 
-    LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
-         deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes);
-         
+    LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x "
+            "configuration='%s'\n",
+         deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes,
+         device->configurationFile.string());
+
     LOGV("Adding device %s %p at %d, id = %d, classes = 0x%x\n",
          deviceName, device, mFDCount, devid, device->classes);
 
@@ -883,8 +898,24 @@
     return 0;
 }
 
+void EventHub::loadConfiguration(device_t* device) {
+    device->configurationFile = getInputDeviceConfigurationFilePath(device->name,
+            INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION);
+    if (device->configurationFile.isEmpty()) {
+        LOGI("No input device configuration file found for device '%s'.",
+                device->name.string());
+    } else {
+        status_t status = PropertyMap::load(device->configurationFile,
+                &device->configuration);
+        if (status) {
+            LOGE("Error loading input device configuration file for device '%s'.",
+                    device->name.string());
+        }
+    }
+}
+
 void EventHub::configureKeyMap(device_t* device) {
-    android::resolveKeyMap(device->name, device->keyMapInfo);
+    android::resolveKeyMap(device->name, device->configuration, device->keyMapInfo);
 }
 
 void EventHub::setKeyboardProperties(device_t* device, bool firstKeyboard) {
@@ -1058,12 +1089,12 @@
                 dump.appendFormat(INDENT3 "Path: %s\n", device->path.string());
                 dump.appendFormat(INDENT3 "IsDefaultKeyMap: %s\n",
                         toString(device->keyMapInfo.isDefaultKeyMap));
-                dump.appendFormat(INDENT3 "KeyMapName: %s\n",
-                        device->keyMapInfo.keyMapName.string());
                 dump.appendFormat(INDENT3 "KeyLayoutFile: %s\n",
                         device->keyMapInfo.keyLayoutFile.string());
                 dump.appendFormat(INDENT3 "KeyCharacterMapFile: %s\n",
                         device->keyMapInfo.keyCharacterMapFile.string());
+                dump.appendFormat(INDENT3 "ConfigurationFile: %s\n",
+                        device->configurationFile.string());
             }
         }
     } // release lock