Inputflinger: hook up key event replacement processing

Add handling of "replacement" key events in InputReader and EventHub by
consulting device's character key map (if exists) for presence of
replacement key code for given get code and meta state combination,
before passing it to InputDispatcher.

This enables defining special keys, such as ESC, on keyboards lacking
enough physical keys, via combination of normal keys and modifiers, for
example AltR + 1 => ESC.

Bug: 24504154

Change-Id: I7e36104808bedcf724436c1fbb63d37c35cca8af
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index 6b60c7c..5859606 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -438,10 +438,12 @@
     return false;
 }
 
-status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
-        int32_t* outKeycode, uint32_t* outFlags) const {
+status_t EventHub::mapKey(int32_t deviceId,
+        int32_t scanCode, int32_t usageCode, int32_t metaState,
+        int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const {
     AutoMutex _l(mLock);
     Device* device = getDeviceLocked(deviceId);
+    status_t status = NAME_NOT_FOUND;
 
     if (device) {
         // Check the key character map first.
@@ -449,22 +451,34 @@
         if (kcm != NULL) {
             if (!kcm->mapKey(scanCode, usageCode, outKeycode)) {
                 *outFlags = 0;
-                return NO_ERROR;
+                status = NO_ERROR;
             }
         }
 
         // Check the key layout next.
-        if (device->keyMap.haveKeyLayout()) {
+        if (status != NO_ERROR && device->keyMap.haveKeyLayout()) {
             if (!device->keyMap.keyLayoutMap->mapKey(
                     scanCode, usageCode, outKeycode, outFlags)) {
-                return NO_ERROR;
+                status = NO_ERROR;
+            }
+        }
+
+        if (status == NO_ERROR) {
+            if (kcm != NULL) {
+                kcm->tryRemapKey(*outKeycode, metaState, outKeycode, outMetaState);
+            } else {
+                *outMetaState = metaState;
             }
         }
     }
 
-    *outKeycode = 0;
-    *outFlags = 0;
-    return NAME_NOT_FOUND;
+    if (status != NO_ERROR) {
+        *outKeycode = 0;
+        *outFlags = 0;
+        *outMetaState = metaState;
+    }
+
+    return status;
 }
 
 status_t EventHub::mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const {