Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49ccac53 authored by Jeff Brown's avatar Jeff Brown
Browse files

Refactor key code mapping.

Added handling for EV_MSC / MSC_SCAN which typically reports
the HID usage associated with a key.  This will enable key maps
to map keys with HID usages that Linux does not natively recognize.

Removed keyCode and flags fields from EventHub RawEvent since
they don't necessarily make sense in isolation now that we
pay attention to HID usage codes too.

Removed the fallback code for mapping keys and axes.  In practice,
an input device should be self-sufficient.  We should not ever
need to look at the built-in keyboard's key map.  In fact, there
usually isn't a built-in keyboard anyhow.  This code was originally
working around a problem where we weren't loading the key map
for touch screens with virtual keys, which has long since been fixed.

Change-Id: I0a319bdec44be9514f795526347397e94d53a127
parent db13a6bf
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -64,7 +64,8 @@ class KeyLayoutMap : public RefBase {
public:
    static status_t load(const String8& filename, sp<KeyLayoutMap>* outMap);

    status_t mapKey(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const;
    status_t mapKey(int32_t scanCode, int32_t usageCode,
            int32_t* outKeyCode, uint32_t* outFlags) const;
    status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const;

    status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const;
@@ -78,11 +79,14 @@ private:
        uint32_t flags;
    };

    KeyedVector<int32_t, Key> mKeys;
    KeyedVector<int32_t, Key> mKeysByScanCode;
    KeyedVector<int32_t, Key> mKeysByUsageCode;
    KeyedVector<int32_t, AxisInfo> mAxes;

    KeyLayoutMap();

    const Key* getKey(int32_t scanCode, int32_t usageCode) const;

    class Parser {
        KeyLayoutMap* mMap;
        Tokenizer* mTokenizer;
+32 −15
Original line number Diff line number Diff line
@@ -80,32 +80,49 @@ status_t KeyLayoutMap::load(const String8& filename, sp<KeyLayoutMap>* outMap) {
    return status;
}

status_t KeyLayoutMap::mapKey(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const {
    ssize_t index = mKeys.indexOfKey(scanCode);
    if (index < 0) {
status_t KeyLayoutMap::mapKey(int32_t scanCode, int32_t usageCode,
        int32_t* outKeyCode, uint32_t* outFlags) const {
    const Key* key = getKey(scanCode, usageCode);
    if (!key) {
#if DEBUG_MAPPING
        ALOGD("mapKey: scanCode=%d ~ Failed.", scanCode);
        ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode);
#endif
        *keyCode = AKEYCODE_UNKNOWN;
        *flags = 0;
        *outKeyCode = AKEYCODE_UNKNOWN;
        *outFlags = 0;
        return NAME_NOT_FOUND;
    }

    const Key& k = mKeys.valueAt(index);
    *keyCode = k.keyCode;
    *flags = k.flags;
    *outKeyCode = key->keyCode;
    *outFlags = key->flags;

#if DEBUG_MAPPING
    ALOGD("mapKey: scanCode=%d ~ Result keyCode=%d, flags=0x%08x.", scanCode, *keyCode, *flags);
    ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d, outFlags=0x%08x.",
            scanCode, usageCode, *outKeyCode, *outFlags);
#endif
    return NO_ERROR;
}

const KeyLayoutMap::Key* KeyLayoutMap::getKey(int32_t scanCode, int32_t usageCode) const {
    if (scanCode) {
        ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
        if (index >= 0) {
            return &mKeysByScanCode.valueAt(index);
        }
    }
    if (usageCode) {
        ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
        if (index >= 0) {
            return &mKeysByUsageCode.valueAt(index);
        }
    }
    return NULL;
}

status_t KeyLayoutMap::findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const {
    const size_t N = mKeys.size();
    const size_t N = mKeysByScanCode.size();
    for (size_t i=0; i<N; i++) {
        if (mKeys.valueAt(i).keyCode == keyCode) {
            outScanCodes->add(mKeys.keyAt(i));
        if (mKeysByScanCode.valueAt(i).keyCode == keyCode) {
            outScanCodes->add(mKeysByScanCode.keyAt(i));
        }
    }
    return NO_ERROR;
@@ -190,7 +207,7 @@ status_t KeyLayoutMap::Parser::parseKey() {
                scanCodeToken.string());
        return BAD_VALUE;
    }
    if (mMap->mKeys.indexOfKey(scanCode) >= 0) {
    if (mMap->mKeysByScanCode.indexOfKey(scanCode) >= 0) {
        ALOGE("%s: Duplicate entry for key scan code '%s'.", mTokenizer->getLocation().string(),
                scanCodeToken.string());
        return BAD_VALUE;
@@ -231,7 +248,7 @@ status_t KeyLayoutMap::Parser::parseKey() {
    Key key;
    key.keyCode = keyCode;
    key.flags = flags;
    mMap->mKeys.add(scanCode, key);
    mMap->mKeysByScanCode.add(scanCode, key);
    return NO_ERROR;
}

+12 −41
Original line number Diff line number Diff line
@@ -117,6 +117,8 @@ static void setDescriptor(InputDeviceIdentifier& identifier) {
        }
    }
    identifier.descriptor = sha1(rawDescriptor);
    ALOGV("Created descriptor: raw=%s, cooked=%s", rawDescriptor.string(),
            identifier.descriptor.string());
}

// --- Global Functions ---
@@ -434,58 +436,35 @@ bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
    return false;
}

status_t EventHub::mapKey(int32_t deviceId, int scancode,
        int32_t* outKeycode, uint32_t* outFlags) const
{
status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
        int32_t* outKeycode, uint32_t* outFlags) const {
    AutoMutex _l(mLock);
    Device* device = getDeviceLocked(deviceId);

    if (device && device->keyMap.haveKeyLayout()) {
        status_t err = device->keyMap.keyLayoutMap->mapKey(scancode, outKeycode, outFlags);
        if (err == NO_ERROR) {
            return NO_ERROR;
        }
    }
    
    if (mBuiltInKeyboardId != NO_BUILT_IN_KEYBOARD) {
        device = getDeviceLocked(mBuiltInKeyboardId);
        
        if (device && device->keyMap.haveKeyLayout()) {
            status_t err = device->keyMap.keyLayoutMap->mapKey(scancode, outKeycode, outFlags);
        status_t err = device->keyMap.keyLayoutMap->mapKey(
                scanCode, usageCode, outKeycode, outFlags);
        if (err == NO_ERROR) {
            return NO_ERROR;
        }
    }
    }

    *outKeycode = 0;
    *outFlags = 0;
    return NAME_NOT_FOUND;
}

status_t EventHub::mapAxis(int32_t deviceId, int scancode, AxisInfo* outAxisInfo) const
{
status_t EventHub::mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const {
    AutoMutex _l(mLock);
    Device* device = getDeviceLocked(deviceId);

    if (device && device->keyMap.haveKeyLayout()) {
        status_t err = device->keyMap.keyLayoutMap->mapAxis(scancode, outAxisInfo);
        status_t err = device->keyMap.keyLayoutMap->mapAxis(scanCode, outAxisInfo);
        if (err == NO_ERROR) {
            return NO_ERROR;
        }
    }

    if (mBuiltInKeyboardId != NO_BUILT_IN_KEYBOARD) {
        device = getDeviceLocked(mBuiltInKeyboardId);

        if (device && device->keyMap.haveKeyLayout()) {
            status_t err = device->keyMap.keyLayoutMap->mapAxis(scancode, outAxisInfo);
            if (err == NO_ERROR) {
                return NO_ERROR;
            }
        }
    }

    return NAME_NOT_FOUND;
}

@@ -729,16 +708,8 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz
#endif
                        event->deviceId = deviceId;
                        event->type = iev.type;
                        event->scanCode = iev.code;
                        event->code = iev.code;
                        event->value = iev.value;
                        event->keyCode = AKEYCODE_UNKNOWN;
                        event->flags = 0;
                        if (iev.type == EV_KEY && device->keyMap.haveKeyLayout()) {
                            status_t err = device->keyMap.keyLayoutMap->mapKey(iev.code,
                                        &event->keyCode, &event->flags);
                            ALOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n",
                                    iev.code, event->keyCode, event->flags, err);
                        }
                        event += 1;
                    }
                    capacity -= count;
@@ -960,7 +931,7 @@ status_t EventHub::openDeviceLocked(const char *devicePath) {
    ALOGV("  name:       \"%s\"\n", identifier.name.string());
    ALOGV("  location:   \"%s\"\n", identifier.location.string());
    ALOGV("  unique id:  \"%s\"\n", identifier.uniqueId.string());
    ALOGV("  descriptor: \"%s\" (%s)\n", identifier.descriptor.string(), rawDescriptor.string());
    ALOGV("  descriptor: \"%s\"\n", identifier.descriptor.string());
    ALOGV("  driver:     v%d.%d.%d\n",
        driverVersion >> 16, (driverVersion >> 8) & 0xff, driverVersion & 0xff);

+7 −9
Original line number Diff line number Diff line
@@ -39,8 +39,8 @@

/* Convenience constants. */

#define BTN_FIRST 0x100  // first button scancode
#define BTN_LAST 0x15f   // last button scancode
#define BTN_FIRST 0x100  // first button code
#define BTN_LAST 0x15f   // last button code

namespace android {

@@ -58,10 +58,8 @@ struct RawEvent {
    nsecs_t when;
    int32_t deviceId;
    int32_t type;
    int32_t scanCode;
    int32_t keyCode;
    int32_t code;
    int32_t value;
    uint32_t flags;
};

/* Describes an absolute axis. */
@@ -173,10 +171,10 @@ public:

    virtual bool hasInputProperty(int32_t deviceId, int property) const = 0;

    virtual status_t mapKey(int32_t deviceId, int scancode,
    virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
            int32_t* outKeycode, uint32_t* outFlags) const = 0;

    virtual status_t mapAxis(int32_t deviceId, int scancode,
    virtual status_t mapAxis(int32_t deviceId, int32_t scanCode,
            AxisInfo* outAxisInfo) const = 0;

    // Sets devices that are excluded from opening.
@@ -252,10 +250,10 @@ public:

    virtual bool hasInputProperty(int32_t deviceId, int property) const;

    virtual status_t mapKey(int32_t deviceId, int scancode,
    virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
            int32_t* outKeycode, uint32_t* outFlags) const;

    virtual status_t mapAxis(int32_t deviceId, int scancode,
    virtual status_t mapAxis(int32_t deviceId, int32_t scanCode,
            AxisInfo* outAxisInfo) const;

    virtual void setExcludedDevices(const Vector<String8>& devices);
+41 −24
Original line number Diff line number Diff line
@@ -946,14 +946,12 @@ void InputDevice::process(const RawEvent* rawEvents, size_t count) {
    size_t numMappers = mMappers.size();
    for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
#if DEBUG_RAW_EVENTS
        ALOGD("Input event: device=%d type=0x%04x scancode=0x%04x "
                "keycode=0x%04x value=0x%08x flags=0x%08x",
                rawEvent->deviceId, rawEvent->type, rawEvent->scanCode, rawEvent->keyCode,
                rawEvent->value, rawEvent->flags);
        ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x",
                rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value);
#endif

        if (mDropUntilNextSync) {
            if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) {
            if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
                mDropUntilNextSync = false;
#if DEBUG_RAW_EVENTS
                ALOGD("Recovered from input event buffer overrun.");
@@ -963,7 +961,7 @@ void InputDevice::process(const RawEvent* rawEvents, size_t count) {
                ALOGD("Dropped input event while waiting for next input sync.");
#endif
            }
        } else if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_DROPPED) {
        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
            ALOGI("Detected input event buffer overrun for device %s.", getName().string());
            mDropUntilNextSync = true;
            reset(rawEvent->when);
@@ -1092,7 +1090,7 @@ void CursorButtonAccumulator::clearButtons() {

void CursorButtonAccumulator::process(const RawEvent* rawEvent) {
    if (rawEvent->type == EV_KEY) {
        switch (rawEvent->scanCode) {
        switch (rawEvent->code) {
        case BTN_LEFT:
            mBtnLeft = rawEvent->value;
            break;
@@ -1159,7 +1157,7 @@ void CursorMotionAccumulator::clearRelativeAxes() {

void CursorMotionAccumulator::process(const RawEvent* rawEvent) {
    if (rawEvent->type == EV_REL) {
        switch (rawEvent->scanCode) {
        switch (rawEvent->code) {
        case REL_X:
            mRelX = rawEvent->value;
            break;
@@ -1198,7 +1196,7 @@ void CursorScrollAccumulator::clearRelativeAxes() {

void CursorScrollAccumulator::process(const RawEvent* rawEvent) {
    if (rawEvent->type == EV_REL) {
        switch (rawEvent->scanCode) {
        switch (rawEvent->code) {
        case REL_WHEEL:
            mRelWheel = rawEvent->value;
            break;
@@ -1261,7 +1259,7 @@ void TouchButtonAccumulator::clearButtons() {

void TouchButtonAccumulator::process(const RawEvent* rawEvent) {
    if (rawEvent->type == EV_KEY) {
        switch (rawEvent->scanCode) {
        switch (rawEvent->code) {
        case BTN_TOUCH:
            mBtnTouch = rawEvent->value;
            break;
@@ -1467,7 +1465,7 @@ void SingleTouchMotionAccumulator::clearAbsoluteAxes() {

void SingleTouchMotionAccumulator::process(const RawEvent* rawEvent) {
    if (rawEvent->type == EV_ABS) {
        switch (rawEvent->scanCode) {
        switch (rawEvent->code) {
        case ABS_X:
            mAbsX = rawEvent->value;
            break;
@@ -1551,7 +1549,7 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
    if (rawEvent->type == EV_ABS) {
        bool newSlot = false;
        if (mUsingSlotsProtocol) {
            if (rawEvent->scanCode == ABS_MT_SLOT) {
            if (rawEvent->code == ABS_MT_SLOT) {
                mCurrentSlot = rawEvent->value;
                newSlot = true;
            }
@@ -1570,7 +1568,7 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
        } else {
            Slot* slot = &mSlots[mCurrentSlot];

            switch (rawEvent->scanCode) {
            switch (rawEvent->code) {
            case ABS_MT_POSITION_X:
                slot->mInUse = true;
                slot->mAbsMTPositionX = rawEvent->value;
@@ -1626,7 +1624,7 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
                break;
            }
        }
    } else if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_MT_REPORT) {
    } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
        // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
        mCurrentSlot += 1;
    }
@@ -1757,7 +1755,7 @@ uint32_t SwitchInputMapper::getSources() {
void SwitchInputMapper::process(const RawEvent* rawEvent) {
    switch (rawEvent->type) {
    case EV_SW:
        processSwitch(rawEvent->when, rawEvent->scanCode, rawEvent->value);
        processSwitch(rawEvent->when, rawEvent->code, rawEvent->value);
        break;
    }
}
@@ -1849,6 +1847,7 @@ void KeyboardInputMapper::reset(nsecs_t when) {
    mMetaState = AMETA_NONE;
    mDownTime = 0;
    mKeyDowns.clear();
    mCurrentHidUsage = 0;

    resetLedState();

@@ -1858,13 +1857,32 @@ void KeyboardInputMapper::reset(nsecs_t when) {
void KeyboardInputMapper::process(const RawEvent* rawEvent) {
    switch (rawEvent->type) {
    case EV_KEY: {
        int32_t scanCode = rawEvent->scanCode;
        int32_t scanCode = rawEvent->code;
        int32_t usageCode = mCurrentHidUsage;
        mCurrentHidUsage = 0;

        if (isKeyboardOrGamepadKey(scanCode)) {
            processKey(rawEvent->when, rawEvent->value != 0, rawEvent->keyCode, scanCode,
                    rawEvent->flags);
            int32_t keyCode;
            uint32_t flags;
            if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, &keyCode, &flags)) {
                keyCode = AKEYCODE_UNKNOWN;
                flags = 0;
            }
            processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags);
        }
        break;
    }
    case EV_MSC: {
        if (rawEvent->code == MSC_SCAN) {
            mCurrentHidUsage = rawEvent->value;
        }
        break;
    }
    case EV_SYN: {
        if (rawEvent->code == SYN_REPORT) {
            mCurrentHidUsage = 0;
        }
    }
    }
}

@@ -2183,7 +2201,7 @@ void CursorInputMapper::process(const RawEvent* rawEvent) {
    mCursorMotionAccumulator.process(rawEvent);
    mCursorScrollAccumulator.process(rawEvent);

    if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) {
    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
        sync(rawEvent->when);
    }
}
@@ -3016,8 +3034,7 @@ void TouchInputMapper::configureVirtualKeys() {
        virtualKey.scanCode = virtualKeyDefinition.scanCode;
        int32_t keyCode;
        uint32_t flags;
        if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode,
                & keyCode, & flags)) {
        if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, &keyCode, &flags)) {
            ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
                    virtualKey.scanCode);
            mVirtualKeys.pop(); // drop the key
@@ -3311,7 +3328,7 @@ void TouchInputMapper::process(const RawEvent* rawEvent) {
    mCursorScrollAccumulator.process(rawEvent);
    mTouchButtonAccumulator.process(rawEvent);

    if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) {
    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
        sync(rawEvent->when);
    }
}
@@ -5920,7 +5937,7 @@ void JoystickInputMapper::reset(nsecs_t when) {
void JoystickInputMapper::process(const RawEvent* rawEvent) {
    switch (rawEvent->type) {
    case EV_ABS: {
        ssize_t index = mAxes.indexOfKey(rawEvent->scanCode);
        ssize_t index = mAxes.indexOfKey(rawEvent->code);
        if (index >= 0) {
            Axis& axis = mAxes.editValueAt(index);
            float newValue, highNewValue;
@@ -5956,7 +5973,7 @@ void JoystickInputMapper::process(const RawEvent* rawEvent) {
    }

    case EV_SYN:
        switch (rawEvent->scanCode) {
        switch (rawEvent->code) {
        case SYN_REPORT:
            sync(rawEvent->when, false /*force*/);
            break;
Loading