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

Commit 3cdfc4d9 authored by Jeff Brown's avatar Jeff Brown Committed by Android (Google) Code Review
Browse files

Merge "Support composite touch / joystick devices better."

parents d318b73e 9ee285af
Loading
Loading
Loading
Loading
+43 −5
Original line number Diff line number Diff line
@@ -78,6 +78,40 @@ static inline const char* toString(bool value) {
    return value ? "true" : "false";
}

// --- Global Functions ---

uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses) {
    // Touch devices get dibs on touch-related axes.
    if (deviceClasses & INPUT_DEVICE_CLASS_TOUCH) {
        switch (axis) {
        case ABS_X:
        case ABS_Y:
        case ABS_PRESSURE:
        case ABS_TOOL_WIDTH:
        case ABS_DISTANCE:
        case ABS_TILT_X:
        case ABS_TILT_Y:
        case ABS_MT_SLOT:
        case ABS_MT_TOUCH_MAJOR:
        case ABS_MT_TOUCH_MINOR:
        case ABS_MT_WIDTH_MAJOR:
        case ABS_MT_WIDTH_MINOR:
        case ABS_MT_ORIENTATION:
        case ABS_MT_POSITION_X:
        case ABS_MT_POSITION_Y:
        case ABS_MT_TOOL_TYPE:
        case ABS_MT_BLOB_ID:
        case ABS_MT_TRACKING_ID:
        case ABS_MT_PRESSURE:
        case ABS_MT_DISTANCE:
            return INPUT_DEVICE_CLASS_TOUCH;
        }
    }

    // Joystick devices get the rest.
    return deviceClasses & INPUT_DEVICE_CLASS_JOYSTICK;
}

// --- EventHub::Device ---

EventHub::Device::Device(int fd, int32_t id, const String8& path,
@@ -936,13 +970,17 @@ status_t EventHub::openDeviceLocked(const char *devicePath) {
    }

    // See if this device is a joystick.
    // Ignore touchscreens because they use the same absolute axes for other purposes.
    // Assumes that joysticks always have gamepad buttons in order to distinguish them
    // from other devices such as accelerometers that also have absolute axes.
    if (haveGamepadButtons
            && !(device->classes & INPUT_DEVICE_CLASS_TOUCH)
            && containsNonZeroByte(device->absBitmask, 0, sizeof_bit_array(ABS_MAX + 1))) {
        device->classes |= INPUT_DEVICE_CLASS_JOYSTICK;
    if (haveGamepadButtons) {
        uint32_t assumedClasses = device->classes | INPUT_DEVICE_CLASS_JOYSTICK;
        for (int i = 0; i <= ABS_MAX; i++) {
            if (test_bit(i, device->absBitmask)
                    && (getAbsAxisUsage(i, assumedClasses) & INPUT_DEVICE_CLASS_JOYSTICK)) {
                device->classes = assumedClasses;
                break;
            }
        }
    }

    // Check whether this device has switches.
+6 −0
Original line number Diff line number Diff line
@@ -111,6 +111,12 @@ enum {
    INPUT_DEVICE_CLASS_EXTERNAL      = 0x80000000,
};

/*
 * Gets the class that owns an axis, in cases where multiple classes might claim
 * the same axis for different purposes.
 */
extern uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses);

/*
 * Grand Central Station for events.
 *
+10 −4
Original line number Diff line number Diff line
@@ -390,7 +390,7 @@ void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {

InputDevice* InputReader::createDeviceLocked(int32_t deviceId,
        const String8& name, uint32_t classes) {
    InputDevice* device = new InputDevice(&mContext, deviceId, name);
    InputDevice* device = new InputDevice(&mContext, deviceId, name, classes);

    // External devices.
    if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
@@ -842,9 +842,10 @@ bool InputReaderThread::threadLoop() {

// --- InputDevice ---

InputDevice::InputDevice(InputReaderContext* context, int32_t id, const String8& name) :
        mContext(context), mId(id), mName(name), mSources(0),
        mIsExternal(false), mDropUntilNextSync(false) {
InputDevice::InputDevice(InputReaderContext* context, int32_t id, const String8& name,
        uint32_t classes) :
        mContext(context), mId(id), mName(name), mClasses(classes),
        mSources(0), mIsExternal(false), mDropUntilNextSync(false) {
}

InputDevice::~InputDevice() {
@@ -5759,6 +5760,11 @@ void JoystickInputMapper::configure(nsecs_t when,
    if (!changes) { // first time only
        // Collect all axes.
        for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
            if (!(getAbsAxisUsage(abs, getDevice()->getClasses())
                    & INPUT_DEVICE_CLASS_JOYSTICK)) {
                continue; // axis must be claimed by a different device
            }

            RawAbsoluteAxisInfo rawAxisInfo;
            getAbsoluteAxisInfo(abs, &rawAxisInfo);
            if (rawAxisInfo.valid) {
+4 −2
Original line number Diff line number Diff line
@@ -430,12 +430,13 @@ private:
/* Represents the state of a single input device. */
class InputDevice {
public:
    InputDevice(InputReaderContext* context, int32_t id, const String8& name);
    InputDevice(InputReaderContext* context, int32_t id, const String8& name, uint32_t classes);
    ~InputDevice();

    inline InputReaderContext* getContext() { return mContext; }
    inline int32_t getId() { return mId; }
    inline const String8& getName() { return mName; }
    inline uint32_t getClasses() { return mClasses; }
    inline uint32_t getSources() { return mSources; }

    inline bool isExternal() { return mIsExternal; }
@@ -483,10 +484,11 @@ public:
private:
    InputReaderContext* mContext;
    int32_t mId;
    String8 mName;
    uint32_t mClasses;

    Vector<InputMapper*> mMappers;

    String8 mName;
    uint32_t mSources;
    bool mIsExternal;
    bool mDropUntilNextSync;
+11 −5
Original line number Diff line number Diff line
@@ -852,8 +852,8 @@ public:
        mNextDevice = device;
    }

    InputDevice* newDevice(int32_t deviceId, const String8& name) {
        return new InputDevice(&mContext, deviceId, name);
    InputDevice* newDevice(int32_t deviceId, const String8& name, uint32_t classes) {
        return new InputDevice(&mContext, deviceId, name, classes);
    }

protected:
@@ -912,7 +912,7 @@ protected:
    FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId,
            const String8& name, uint32_t classes, uint32_t sources,
            const PropertyMap* configuration) {
        InputDevice* device = mReader->newDevice(deviceId, name);
        InputDevice* device = mReader->newDevice(deviceId, name, classes);
        FakeInputMapper* mapper = new FakeInputMapper(device, sources);
        device->addMapper(mapper);
        mReader->setNextDevice(device);
@@ -1211,6 +1211,7 @@ class InputDeviceTest : public testing::Test {
protected:
    static const char* DEVICE_NAME;
    static const int32_t DEVICE_ID;
    static const uint32_t DEVICE_CLASSES;

    sp<FakeEventHub> mFakeEventHub;
    sp<FakeInputReaderPolicy> mFakePolicy;
@@ -1226,7 +1227,7 @@ protected:
        mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);

        mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
        mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME));
        mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME), DEVICE_CLASSES);
    }

    virtual void TearDown() {
@@ -1241,10 +1242,13 @@ protected:

const char* InputDeviceTest::DEVICE_NAME = "device";
const int32_t InputDeviceTest::DEVICE_ID = 1;
const uint32_t InputDeviceTest::DEVICE_CLASSES = INPUT_DEVICE_CLASS_KEYBOARD
        | INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_JOYSTICK;

TEST_F(InputDeviceTest, ImmutableProperties) {
    ASSERT_EQ(DEVICE_ID, mDevice->getId());
    ASSERT_STREQ(DEVICE_NAME, mDevice->getName());
    ASSERT_EQ(DEVICE_CLASSES, mDevice->getClasses());
}

TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
@@ -1390,6 +1394,7 @@ class InputMapperTest : public testing::Test {
protected:
    static const char* DEVICE_NAME;
    static const int32_t DEVICE_ID;
    static const uint32_t DEVICE_CLASSES;

    sp<FakeEventHub> mFakeEventHub;
    sp<FakeInputReaderPolicy> mFakePolicy;
@@ -1402,7 +1407,7 @@ protected:
        mFakePolicy = new FakeInputReaderPolicy();
        mFakeListener = new FakeInputListener();
        mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);
        mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME));
        mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME), DEVICE_CLASSES);

        mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
    }
@@ -1483,6 +1488,7 @@ protected:

const char* InputMapperTest::DEVICE_NAME = "device";
const int32_t InputMapperTest::DEVICE_ID = 1;
const uint32_t InputMapperTest::DEVICE_CLASSES = 0; // not needed for current tests


// --- SwitchInputMapperTest ---