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

Commit a0d2b809 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Pass BTN_GEAR_DOWN and BTN_GEAR_UP to apps

The Steam controller has 2 large 'paddle' buttons on the back. When used
in USB mode with hid-steam, this sends BTN_GEAR_DOWN and BTN_GEAR_UP to
the user space.

But today, these events never reach the apps, even if they have proper
mappings. This is because these buttons are not considered to be
"keyboard or gamepad". Adjust the checks to include these 2 buttons in
KeyboardInputMapper.

Test: connect Steam controller over USB and check that the paddle
buttons produce events visible in the "gamepad tester" app
Test: atest inputflinger_tests
Bug: 147434575

Change-Id: I43f221c546ccc1277d578a185465bd5eadac9e8e
parent 2d76a5eb
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1318,7 +1318,7 @@ status_t EventHub::openDeviceLocked(const char* devicePath) {
    // joystick and gamepad buttons which are handled like keyboards for the most part.
    bool haveKeyboardKeys =
            containsNonZeroByte(device->keyBitmask, 0, sizeof_bit_array(BTN_MISC)) ||
            containsNonZeroByte(device->keyBitmask, sizeof_bit_array(KEY_OK),
            containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_WHEEL),
                                sizeof_bit_array(KEY_MAX + 1));
    bool haveGamepadButtons = containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_MISC),
                                                  sizeof_bit_array(BTN_MOUSE)) ||
+1 −1
Original line number Diff line number Diff line
@@ -233,7 +233,7 @@ void KeyboardInputMapper::process(const RawEvent* rawEvent) {
}

bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
    return scanCode < BTN_MOUSE || scanCode >= KEY_OK ||
    return scanCode < BTN_MOUSE || scanCode >= BTN_WHEEL ||
            (scanCode >= BTN_MISC && scanCode < BTN_MOUSE) ||
            (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI);
}
+22 −0
Original line number Diff line number Diff line
@@ -1848,6 +1848,28 @@ TEST_F(InputReaderIntegrationTest, SendsEventsToInputListener) {
    ASSERT_LE(prevTimestamp, keyArgs.eventTime);
}

/**
 * The Steam controller sends BTN_GEAR_DOWN and BTN_GEAR_UP for the two "paddle" buttons
 * on the back. In this test, we make sure that BTN_GEAR_DOWN / BTN_WHEEL and BTN_GEAR_UP
 * are passed to the listener.
 */
static_assert(BTN_GEAR_DOWN == BTN_WHEEL);
TEST_F(InputReaderIntegrationTest, SendsGearDownAndUpToInputListener) {
    std::unique_ptr<UinputSteamController> controller = createUinputDevice<UinputSteamController>();
    ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
    NotifyKeyArgs keyArgs;

    controller->pressAndReleaseKey(BTN_GEAR_DOWN);
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
    ASSERT_EQ(BTN_GEAR_DOWN, keyArgs.scanCode);

    controller->pressAndReleaseKey(BTN_GEAR_UP);
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
    ASSERT_EQ(BTN_GEAR_UP, keyArgs.scanCode);
}

// --- TouchProcessTest ---
class TouchIntegrationTest : public InputReaderIntegrationTest {
protected:
+3 −0
Original line number Diff line number Diff line
@@ -125,6 +125,9 @@ void UinputHomeKey::pressAndReleaseHomeKey() {
    pressAndReleaseKey(KEY_HOME);
}

// --- UinputSteamController
UinputSteamController::UinputSteamController() : UinputKeyboard({BTN_GEAR_DOWN, BTN_GEAR_UP}) {}

// --- UinputTouchScreen ---
UinputTouchScreen::UinputTouchScreen(const Rect* size)
      : UinputDevice(UinputTouchScreen::DEVICE_NAME), mSize(*size) {}
+10 −0
Original line number Diff line number Diff line
@@ -108,6 +108,16 @@ private:
    UinputHomeKey();
};

// A joystick device that sends a BTN_GEAR_DOWN / BTN_WHEEL key.
class UinputSteamController : public UinputKeyboard {
public:
    template <class D, class... Ts>
    friend std::unique_ptr<D> createUinputDevice(Ts... args);

private:
    UinputSteamController();
};

// --- UinputTouchScreen ---
// A touch screen device with specific size.
class UinputTouchScreen : public UinputDevice {