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

Commit 3133642c authored by Prabir Pradhan's avatar Prabir Pradhan Committed by Android (Google) Code Review
Browse files

Merge changes I5669af54,I80d29513

* changes:
  Differentiate Uinput devices by productId for testing
  Add integration tests for stylus button behavior
parents ed2def6d b7d434e2
Loading
Loading
Loading
Loading
+91 −1
Original line number Diff line number Diff line
@@ -2373,7 +2373,7 @@ TEST_F(InputReaderIntegrationTest, TestInvalidDevice) {
    // An invalid input device that is only used for this test.
    class InvalidUinputDevice : public UinputDevice {
    public:
        InvalidUinputDevice() : UinputDevice("Invalid Device") {}
        InvalidUinputDevice() : UinputDevice("Invalid Device", 99 /*productId*/) {}

    private:
        void configureDevice(int fd, uinput_user_dev* device) override {}
@@ -2825,6 +2825,96 @@ TEST_F(TouchIntegrationTest, StylusButtonsGenerateKeyEvents) {
                  WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
}

TEST_F(TouchIntegrationTest, StylusButtonsSurroundingTouchGesture) {
    const Point centerPoint = mDevice->getCenterPoint();

    // Press the stylus button.
    mDevice->sendKey(BTN_STYLUS, 1);
    mDevice->sendSync();
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
            AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
                  WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));

    // Start and finish a stylus gesture.
    mDevice->sendSlot(FIRST_SLOT);
    mDevice->sendTrackingId(FIRST_TRACKING_ID);
    mDevice->sendToolType(MT_TOOL_PEN);
    mDevice->sendDown(centerPoint);
    mDevice->sendSync();
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
                  WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
                  WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));

    mDevice->sendTrackingId(INVALID_TRACKING_ID);
    mDevice->sendSync();
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0))));
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0))));

    // Release the stylus button.
    mDevice->sendKey(BTN_STYLUS, 0);
    mDevice->sendSync();
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
            AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
                  WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
}

TEST_F(TouchIntegrationTest, StylusButtonsWithinTouchGesture) {
    const Point centerPoint = mDevice->getCenterPoint();

    // Start a stylus gesture.
    mDevice->sendSlot(FIRST_SLOT);
    mDevice->sendTrackingId(FIRST_TRACKING_ID);
    mDevice->sendToolType(MT_TOOL_PEN);
    mDevice->sendDown(centerPoint);
    mDevice->sendSync();
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0))));

    // Press and release a stylus button. Each change in button state also generates a MOVE event.
    mDevice->sendKey(BTN_STYLUS, 1);
    mDevice->sendSync();
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
            AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
                  WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
                  WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS),
                  WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));

    mDevice->sendKey(BTN_STYLUS, 0);
    mDevice->sendSync();
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
            AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
                  WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0))));
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0))));

    // Finish the stylus gesture.
    mDevice->sendTrackingId(INVALID_TRACKING_ID);
    mDevice->sendSync();
    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
            AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
                  WithToolType(AMOTION_EVENT_TOOL_TYPE_STYLUS), WithButtonState(0))));
}

// --- InputDeviceTest ---
class InputDeviceTest : public testing::Test {
protected:
+15 −11
Original line number Diff line number Diff line
@@ -24,7 +24,8 @@ namespace android {

// --- UinputDevice ---

UinputDevice::UinputDevice(const char* name) : mName(name) {}
UinputDevice::UinputDevice(const char* name, int16_t productId)
      : mName(name), mProductId(productId) {}

UinputDevice::~UinputDevice() {
    if (ioctl(mDeviceFd, UI_DEV_DESTROY)) {
@@ -43,7 +44,7 @@ void UinputDevice::init() {
    strlcpy(device.name, mName, UINPUT_MAX_NAME_SIZE);
    device.id.bustype = BUS_USB;
    device.id.vendor = 0x01;
    device.id.product = 0x01;
    device.id.product = mProductId;
    device.id.version = 1;

    ASSERT_NO_FATAL_FAILURE(configureDevice(mDeviceFd, &device));
@@ -76,8 +77,8 @@ void UinputDevice::injectEvent(uint16_t type, uint16_t code, int32_t value) {

// --- UinputKeyboard ---

UinputKeyboard::UinputKeyboard(const char* name, std::initializer_list<int> keys)
      : UinputDevice(name), mKeys(keys.begin(), keys.end()) {}
UinputKeyboard::UinputKeyboard(const char* name, int16_t productId, std::initializer_list<int> keys)
      : UinputDevice(name, productId), mKeys(keys.begin(), keys.end()) {}

void UinputKeyboard::configureDevice(int fd, uinput_user_dev* device) {
    // enable key press/release event
@@ -121,23 +122,26 @@ void UinputKeyboard::pressAndReleaseKey(int key) {

// --- UinputHomeKey ---

UinputHomeKey::UinputHomeKey() : UinputKeyboard("Test Uinput Home Key", {KEY_HOME}) {}
UinputHomeKey::UinputHomeKey() : UinputKeyboard(DEVICE_NAME, PRODUCT_ID, {KEY_HOME}) {}

void UinputHomeKey::pressAndReleaseHomeKey() {
    pressAndReleaseKey(KEY_HOME);
}

// --- UinputSteamController
// --- UinputSteamController ---

UinputSteamController::UinputSteamController()
      : UinputKeyboard("Test Uinput Steam Controller", {BTN_GEAR_DOWN, BTN_GEAR_UP}) {}
      : UinputKeyboard(DEVICE_NAME, PRODUCT_ID, {BTN_GEAR_DOWN, BTN_GEAR_UP}) {}

// --- UinputExternalStylus ---

// --- UinputExternalStylus
UinputExternalStylus::UinputExternalStylus()
      : UinputKeyboard("Test Uinput External Stylus", {BTN_STYLUS, BTN_STYLUS2, BTN_STYLUS3}) {}
      : UinputKeyboard(DEVICE_NAME, PRODUCT_ID, {BTN_STYLUS, BTN_STYLUS2, BTN_STYLUS3}) {}

// --- UinputTouchScreen ---
UinputTouchScreen::UinputTouchScreen(const Rect* size)
      : UinputDevice(UinputTouchScreen::DEVICE_NAME), mSize(*size) {}

UinputTouchScreen::UinputTouchScreen(const Rect& size)
      : UinputDevice(DEVICE_NAME, PRODUCT_ID), mSize(size) {}

void UinputTouchScreen::configureDevice(int fd, uinput_user_dev* device) {
    // Setup the touch screen device
+29 −10
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ namespace android {
template <class D, class... Ts>
std::unique_ptr<D> createUinputDevice(Ts... args) {
    // Using `new` to access non-public constructors.
    std::unique_ptr<D> dev(new D(&args...));
    std::unique_ptr<D> dev(new D(args...));
    EXPECT_NO_FATAL_FAILURE(dev->init());
    return dev;
}
@@ -51,8 +51,9 @@ public:

protected:
    const char* mName;
    const int16_t mProductId;

    UinputDevice(const char* name);
    explicit UinputDevice(const char* name, int16_t productId);

    // Signals which types of events this device supports before it is created.
    // This must be overridden by subclasses.
@@ -71,7 +72,8 @@ private:

class UinputKeyboard : public UinputDevice {
public:
    static constexpr const char* KEYBOARD_NAME = "Test Keyboard Device";
    static constexpr const char* KEYBOARD_NAME = "Test Uinput Keyboard Device";
    static constexpr int16_t PRODUCT_ID = 42;

    // Injects key press and sync.
    void pressKey(int key);
@@ -84,7 +86,8 @@ public:
    friend std::unique_ptr<D> createUinputDevice(Ts... args);

protected:
    UinputKeyboard(const char* name, std::initializer_list<int> keys = {});
    explicit UinputKeyboard(const char* name, int16_t productId = PRODUCT_ID,
                            std::initializer_list<int> keys = {});

private:
    void configureDevice(int fd, uinput_user_dev* device) override;
@@ -97,6 +100,9 @@ private:
// A keyboard device that has a single HOME key.
class UinputHomeKey : public UinputKeyboard {
public:
    static constexpr const char* DEVICE_NAME = "Test Uinput Home Key";
    static constexpr int16_t PRODUCT_ID = 43;

    // Injects 4 events: key press, sync, key release, and sync.
    void pressAndReleaseHomeKey();

@@ -104,34 +110,47 @@ public:
    friend std::unique_ptr<D> createUinputDevice(Ts... args);

private:
    UinputHomeKey();
    explicit UinputHomeKey();
};

// --- UinputSteamController ---

// A joystick device that sends a BTN_GEAR_DOWN / BTN_WHEEL key.
class UinputSteamController : public UinputKeyboard {
public:
    static constexpr const char* DEVICE_NAME = "Test Uinput Steam Controller";
    static constexpr int16_t PRODUCT_ID = 44;

    template <class D, class... Ts>
    friend std::unique_ptr<D> createUinputDevice(Ts... args);

private:
    UinputSteamController();
    explicit UinputSteamController();
};

// --- UinputExternalStylus ---

// A stylus that reports button presses.
class UinputExternalStylus : public UinputKeyboard {
public:
    static constexpr const char* DEVICE_NAME = "Test Uinput External Stylus";
    static constexpr int16_t PRODUCT_ID = 45;

    template <class D, class... Ts>
    friend std::unique_ptr<D> createUinputDevice(Ts... args);

private:
    UinputExternalStylus();
    explicit UinputExternalStylus();
};

// --- UinputTouchScreen ---
// A touch screen device with specific size.

// A multi-touch touchscreen device with specific size that also supports styluses.
class UinputTouchScreen : public UinputDevice {
public:
    static constexpr const char* DEVICE_NAME = "Test Touch Screen";
    static constexpr const char* DEVICE_NAME = "Test Uinput Touch Screen";
    static constexpr int16_t PRODUCT_ID = 46;

    static const int32_t RAW_TOUCH_MIN = 0;
    static const int32_t RAW_TOUCH_MAX = 31;
    static const int32_t RAW_ID_MIN = 0;
@@ -157,7 +176,7 @@ public:
    const Point getCenterPoint();

protected:
    UinputTouchScreen(const Rect* size);
    explicit UinputTouchScreen(const Rect& size);

private:
    void configureDevice(int fd, uinput_user_dev* device) override;