It's same way of checking MouseEventCheckTest.
For test, get lists of libinput devices and check validation of created touch event.
Only different thing with others is check it is mult touch support.
It supports multi touch, it generates libiput touch event and saves sequencely. For example, touch down, move, up.
It checkes devices capability which is touch, and checkes matching of events. If one of them checked successfully same events as created events, other touch devices can be skipped.
Change-Id: I0a60e675c14714c67debd0cfaac3c9ed80a1dc03
'test_hal_libinput.cpp',
'test_hal_libinput_info.cpp',
'test_hal_libinput_eventgen.cpp',
+ 'test_hal_libinput_mtdev_check.cpp',
]
libinput_haltests_include_dirs = include_directories(
TEST_F(LibInputHalTest, TouchEventCheckTest)
{
- EXPECT_TRUE(true);
+ EXPECT_TRUE(handle_libinput_add_event(li) != -1);
+ EXPECT_TRUE(validate_touch_event(li));
}
_write_event_to_device_node(EV_KEY, keycode, value);
}
+static void _touch_gen_mt_slot(int value)
+{
+ _write_event_to_device_node(EV_ABS, ABS_MT_SLOT, value);
+}
+
+static void _touch_gen_mt_tracking_id(int value)
+{
+ _write_event_to_device_node(EV_ABS, ABS_MT_TRACKING_ID, value);
+}
+
+static void _touch_gen_mt_touch_major(int value)
+{
+ _write_event_to_device_node(EV_ABS, ABS_MT_TOUCH_MAJOR, value);
+}
+
+static void _touch_gen_mt_touch_minor(int value)
+{
+ _write_event_to_device_node(EV_ABS, ABS_MT_TOUCH_MINOR, value);
+}
+
+static void _touch_gen_mt_position_x(int value)
+{
+ _write_event_to_device_node(EV_ABS, ABS_MT_POSITION_X, value);
+}
+
+static void _touch_gen_mt_position_y(int value)
+{
+ _write_event_to_device_node(EV_ABS, ABS_MT_POSITION_Y, value);
+}
+
static void _button_gen_down(int button)
{
if(button <3)
_sync_gen();
}
+static void _touch_gen_down(int idx, int x, int y)
+{
+#define MAX_TRACKING_ID 65535
+ static int tracking_id = 0;
+
+ _touch_gen_mt_slot(idx);
+ _touch_gen_mt_tracking_id(tracking_id);
+ tracking_id++;
+ if(tracking_id > MAX_TRACKING_ID)
+ tracking_id = 0;
+
+ _touch_gen_mt_touch_major(10);
+ _touch_gen_mt_touch_minor(5);
+ _touch_gen_mt_position_x(x);
+ _touch_gen_mt_position_y(y);
+ _sync_gen();
+}
+
+static void _touch_gen_move(int idx, int x, int y)
+{
+ _touch_gen_mt_slot(idx);
+ _touch_gen_mt_position_x(x);
+ _touch_gen_mt_position_y(y);
+ _sync_gen();
+}
+
+static void _touch_gen_up(int idx)
+{
+ _touch_gen_mt_slot(idx);
+ _touch_gen_mt_tracking_id(-1);
+ _sync_gen();
+}
+
static void _input_mousegen(int button, int x, int y, int mouse_state)
{
switch(mouse_state) {
}
}
+static void _input_touchgen(int idx, int x, int y, int touch_state)
+{
+ switch(touch_state) {
+ case EVENT_STATE_PRESS:
+ _touch_gen_down(idx, x, y);
+ break;
+ case EVENT_STATE_RELEASE:
+ _touch_gen_up(idx);
+ break;
+ case EVENT_STATE_MOTION:
+ _touch_gen_move(idx, x, y);
+ break;
+ case EVENT_STATE_ALL:
+ _touch_gen_down(idx, x, y);
+ _touch_gen_move(idx, x, y);
+ _touch_gen_up(idx);
+ break;
+ default:
+ return;
+ }
+}
+
int input_mouse_event_gen(int _fd, int button, int x, int y, int state)
{
if (_fd < 0) return -1;
return 0;
}
+
+int input_touch_event_gen(int _fd, int idx, int x, int y, int state)
+{
+ if(_fd < 0) return -1;
+ fd = _fd;
+ _input_touchgen(idx, x, y, state);
+
+ return 0;
+}
int input_mouse_event_gen(int _fd, int button, int x, int y, int state);
int input_keyboard_event_gen(int _fd, int code, int state);
+int input_touch_event_gen(int _fd, int idx, int x, int y, int state);
#ifdef __cplusplus
}
#include "test_hal_libinput_info.h"
#include "test_hal_libinput_eventgen.h"
+#include "test_hal_libinput_mtdev_check.h"
#include <limits.h>
#include <libevdev/libevdev.h>
#include <libevdev/libevdev-uinput.h>
static int
handle_touch_event(struct libinput_event *ev)
{
+ enum libinput_event_type etype = libinput_event_get_type(ev);
+ struct libinput_event_touch *t = libinput_event_get_touch_event(ev);
+ const char *type;
+ double x, y;
+ double tx, ty;
+ int32_t slot, seat_slot;
+
+ switch(etype) {
+ case LIBINPUT_EVENT_TOUCH_DOWN:
+ type = "TOUCH_DOWN";
+ break;
+ case LIBINPUT_EVENT_TOUCH_UP:
+ type = "TOUCH_UP";
+ break;
+ case LIBINPUT_EVENT_TOUCH_MOTION:
+ type = "TOUCH_MOTION";
+ break;
+ case LIBINPUT_EVENT_TOUCH_CANCEL:
+ type = "TOUCH_CANCEL";
+ break;
+ case LIBINPUT_EVENT_TOUCH_FRAME:
+ type = "TOUCH_FRAME";
+ break;
+ default:
+ abort();
+ }
+
+ if (etype != LIBINPUT_EVENT_TOUCH_FRAME) {
+ slot = libinput_event_touch_get_slot(t);
+ seat_slot = libinput_event_touch_get_seat_slot(t);
+ }
+
+ switch (etype) {
+ case LIBINPUT_EVENT_TOUCH_FRAME:
+ LOG("type: %s\n", type);
+ break;
+ case LIBINPUT_EVENT_TOUCH_DOWN:
+ case LIBINPUT_EVENT_TOUCH_MOTION:
+ x = libinput_event_touch_get_x(t);
+ y = libinput_event_touch_get_y(t);
+ tx = libinput_event_touch_get_x_transformed(t, 100);
+ ty = libinput_event_touch_get_y_transformed(t, 100);
+ LOG("type: %s, slot: %d, seat_slot: %d, point: [%6.2f, %6.2f], transformed: [%6.2f, %6.2f]\n",
+ type, slot, seat_slot, x, y, tx, ty);
+ LOG("type = %d, slot : %d, x = %d, y = %d, state = %d\n", queue_record_event[pop_idx].t.event_type, queue_record_event[pop_idx].t.idx, queue_record_event[pop_idx].t.x,
+ queue_record_event[pop_idx].t.y, queue_record_event[pop_idx].t.state);
+ EXPECT_EQ(queue_record_event[pop_idx].t.event_type, etype);
+ EXPECT_EQ(queue_record_event[pop_idx].t.idx, (int)slot);
+ EXPECT_EQ(queue_record_event[pop_idx].t.x, (int)x);
+ EXPECT_EQ(queue_record_event[pop_idx].t.y, (int)y);
+ break;
+ case LIBINPUT_EVENT_TOUCH_UP:
+ case LIBINPUT_EVENT_TOUCH_CANCEL:
+ LOG("type: %s, slot: %d, seat_slot: %d\n",
+ type, slot, seat_slot);
+ LOG("type = %d, slot : %d,state = %d\n", queue_record_event[pop_idx].t.event_type, queue_record_event[pop_idx].t.idx,
+ queue_record_event[pop_idx].t.state);
+ EXPECT_EQ(queue_record_event[pop_idx].t.event_type, etype);
+ EXPECT_EQ(queue_record_event[pop_idx].t.idx, (int)slot);
+ break;
+ default:
+ abort();
+ }
return 0;
}
return 0;
}
+int multi_touch_support(struct libinput *li, int idx)
+{
+ int fd = -1;
+
+ if(devices[idx].cap == LIBINPUT_DEVICE_CAP_TOUCH){
+ LOG("multi_touch_support\n");
+ fd = open(devices[idx].path, O_RDONLY | O_NONBLOCK);
+ if (fd < 0) {
+ LOGE("ERROR: could not open device\n");
+ return -1;
+ }
+ if (ioctl(fd, EVIOCGRAB, 1)) {
+ LOGE("ERROR: could not grab the device\n");
+ return -1;
+ }
+ if (check_device_mtprops(fd) < 0) {
+ ioctl(fd, EVIOCGRAB, 0);
+ close(fd);
+ LOGE("ERROR: NO mt must props\n");
+ return -1;
+ }
+ ioctl(fd, EVIOCGRAB, 0);
+ close(fd);
+ }
+ else
+ return -1;
+ return 0;
+}
+
+int create_touch_event(struct libinput *li, int idx)
+{
+ int fd = -1;
+ int n = 0;
+
+ struct record_event rc_e;
+ struct record_libinput_event_touch t[] = {
+ {LIBINPUT_EVENT_TOUCH_DOWN, 1, 100, 100, 1},
+ {LIBINPUT_EVENT_TOUCH_MOTION, 1, 120, 150, 2},
+ {LIBINPUT_EVENT_TOUCH_UP, 1, 120, 150, 0},
+ };
+
+ if(devices[idx].cap == LIBINPUT_DEVICE_CAP_TOUCH){
+ LOG("create_touch_event\n");
+ fd = open(devices[idx].path, O_RDWR);
+ if (fd < 0) {
+ LOGE("ERROR: could not open device\n");
+ return -1;
+ }
+
+ n = sizeof(t)/sizeof(struct record_libinput_event_touch);
+ rc_e.device = LIBINPUT_DEVICE_CAP_TOUCH;
+ for(int i=0; i<n; ++i)
+ {
+ rc_e.t = t[i];
+
+ if(input_touch_event_gen(fd, t[i].idx, t[i].x, t[i].y, t[i].state) < 0) {
+ LOG("No device\n");
+ continue;
+ }
+ queue_record_event[queue_idx++] = rc_e;
+ }
+
+ libinput_dispatch(li);
+ close(fd);
+ }
+ else
+ return -1;
+ return 0;
+}
+
bool validate_mouse_event(struct libinput *li)
{
bool val = false;
}
return val;
}
+
+bool validate_touch_event(struct libinput *li)
+{
+ bool val = false;
+ bool checked = false;
+ int ret = 0;
+
+ for(int i=0; i< devices_cnt; ++i) {
+ if(devices[i].cap == LIBINPUT_DEVICE_CAP_TOUCH) {
+ LOG("LIBINPUT_DEVICE_CAP_TOUCH, path = %s\n", devices[i].path);
+ checked = true;
+ queue_idx = 0;
+ pop_idx = -1;
+ if(multi_touch_support(li, i) < 0) {
+ LOG("NO MULTI TOUCH SURPPORT. dont' have to test touch\n");
+ }
+ else{
+ create_touch_event(li, i);
+ ret = handle_libinput_event(li);
+ if(queue_idx == (pop_idx+1) && !ret) {
+ val = true;
+ }
+ }
+ }
+ if(val) return true;
+ }
+ if(!val && !checked){
+ LOG("No Devices\n");
+ return true;
+ }
+ return val;
+}
bool validate_mouse_event(struct libinput *li);
bool validate_keyboard_event(struct libinput *li);
+bool validate_touch_event(struct libinput *li);
struct record_device {
enum libinput_device_capability cap;
--- /dev/null
+/*****************************************************************************
+ *
+ * mtdev - Multitouch Protocol Translation Library (MIT license)
+ *
+ * Copyright (C) 2010 Henrik Rydberg <rydberg@euromail.se>
+ * Copyright (C) 2010 Canonical Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ ****************************************************************************/
+
+#include <mtdev.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include "test_hal_libinput_mtdev_check.h"
+
+#ifndef input_event_sec
+#define input_event_sec time.tv_sec
+#define input_event_usec time.tv_usec
+#endif
+
+static int check_must_have(int code)
+{
+ int ret = -1;
+ switch (code)
+ {
+ case ABS_MT_SLOT:
+ case ABS_MT_TOUCH_MAJOR:
+ case ABS_MT_TOUCH_MINOR:
+ case ABS_MT_POSITION_X:
+ case ABS_MT_POSITION_Y:
+ case ABS_MT_TRACKING_ID:
+ ret = 0;
+ break;
+
+ case ABS_MT_WIDTH_MAJOR:
+ case ABS_MT_WIDTH_MINOR:
+ case ABS_MT_ORIENTATION:
+ case ABS_MT_TOOL_TYPE:
+ case ABS_MT_BLOB_ID:
+ case ABS_MT_PRESSURE:
+ case ABS_MT_DISTANCE:
+ break;
+ }
+ return ret;
+}
+
+
+static const char* print_code(int code)
+{
+ const char * code_str = NULL;
+ switch (code)
+ {
+ case ABS_MT_SLOT:
+ code_str = "ABS_MT_SLOT";
+ break;
+ case ABS_MT_TOUCH_MAJOR:
+ code_str = "ABS_MT_TOUCH_MAJOR";
+ break;
+ case ABS_MT_TOUCH_MINOR:
+ code_str = "ABS_MT_TOUCH_MINOR";
+ break;
+ case ABS_MT_POSITION_X:
+ code_str = "ABS_MT_POSITION_X";
+ break;
+ case ABS_MT_POSITION_Y:
+ code_str = "ABS_MT_POSITION_Y";
+ break;
+ case ABS_MT_TRACKING_ID:
+ code_str = "ABS_MT_TRACKING_ID";
+ break;
+
+ case ABS_MT_WIDTH_MAJOR:
+ code_str = "ABS_MT_WIDTH_MAJOR";
+ break;
+ case ABS_MT_WIDTH_MINOR:
+ code_str = "ABS_MT_WIDTH_MINOR";
+ break;
+ case ABS_MT_ORIENTATION:
+ code_str = "ABS_MT_ORIENTATION";
+ break;
+ case ABS_MT_TOOL_TYPE:
+ code_str = "ABS_MT_TOOL_TYPE";
+ break;
+ case ABS_MT_BLOB_ID:
+ code_str = "ABS_MT_BLOB_ID";
+ break;
+ case ABS_MT_PRESSURE:
+ code_str = "ABS_MT_PRESSURE";
+ break;
+ case ABS_MT_DISTANCE:
+ code_str = "ABS_MT_DISTANCE";
+ break;
+ }
+ return code_str;
+}
+
+static int check_has_props(const struct mtdev *dev, int name)
+{
+ int ret = -1;
+ if(!check_must_have(name) && mtdev_has_mt_event(dev, name)) {
+ LOG("must have && it has : %s\n", print_code(name));
+ ret = 0;
+ }
+ else if (!check_must_have(name) && !mtdev_has_mt_event(dev, name)) {
+ LOGE("ERROR!! must have && it doesnt have : %s\n", print_code(name));
+ ret = -1;
+ }
+ else { // no must
+ LOG("don't have to : %s\n", print_code(name));
+ ret = 0;
+ }
+ return ret;
+}
+
+static int check_props(const struct mtdev *dev)
+{
+ LOG("supported mt events:\n");
+
+ if(check_has_props(dev, ABS_MT_SLOT) < 0) return -1;
+ if(check_has_props(dev, ABS_MT_TOUCH_MAJOR) < 0) return -1;
+ if(check_has_props(dev, ABS_MT_TOUCH_MINOR) < 0) return -1;
+ if(check_has_props(dev, ABS_MT_WIDTH_MAJOR) < 0) return -1;
+ if(check_has_props(dev, ABS_MT_WIDTH_MINOR) < 0) return -1;
+ if(check_has_props(dev, ABS_MT_ORIENTATION) < 0) return -1;
+ if(check_has_props(dev, ABS_MT_POSITION_X) < 0) return -1;
+ if(check_has_props(dev, ABS_MT_POSITION_Y) < 0) return -1;
+ if(check_has_props(dev, ABS_MT_TOOL_TYPE) < 0) return -1;
+ if(check_has_props(dev, ABS_MT_BLOB_ID) < 0) return -1;
+ if(check_has_props(dev, ABS_MT_TRACKING_ID) < 0) return -1;
+ if(check_has_props(dev, ABS_MT_PRESSURE) < 0) return -1;
+ if(check_has_props(dev, ABS_MT_DISTANCE) < 0) return -1;
+
+ return 0;
+}
+
+int check_device_mtprops(int fd)
+{
+ int ret = -1;
+ struct mtdev dev;
+ ret = mtdev_open(&dev, fd);
+ if (ret) {
+ LOGE("ERROR! could not open device: %d\n", ret);
+ return -1;
+ }
+ ret = check_props(&dev);
+ mtdev_close(&dev);
+ return ret;
+}
--- /dev/null
+#ifndef __LIBINPUT_TESTS_MT_H__
+#define __LIBINPUT_TESTS_MT_H__
+
+#include <stdio.h>
+#include "test_hal_libinput_info.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <linux/input.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+
+int check_device_mtprops(int fd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __LIBINPUT_TESTS_MT_H__
\ No newline at end of file