0

I try to use /dev/uinput to simulate touch event in Android, some code like this:

first open "/dev/uinput" file, and create an udev:

static int open_uinput_device(){
uinp_fd = open(uinput_deivce_path, O_WRONLY | O_NDELAY);
if (uinp_fd <= 0) {
    debug("could not open %s, %s", uinput_deivce_path, strerror(errno));
    return -1;
}

memset(&ui_dev, 0, sizeof(ui_dev));
strncpy(ui_dev.name, "RemoteTV Event", UINPUT_MAX_NAME_SIZE);
ui_dev.id.bustype = BUS_USB;
ui_dev.id.vendor = 0x1341;
ui_dev.id.product = 0x0001;
ui_dev.id.version = 4;

ui_dev.absmin[ABS_MT_SLOT] = 0;
ui_dev.absmax[ABS_MT_SLOT] = 9;
ui_dev.absmin[ABS_MT_TOUCH_MAJOR] = 0;
ui_dev.absmax[ABS_MT_TOUCH_MAJOR] = 255;
ui_dev.absmin[ABS_MT_POSITION_X] = 0;
ui_dev.absmax[ABS_MT_POSITION_X] = screen_width - 1;
ui_dev.absmin[ABS_MT_POSITION_Y] = 0;
ui_dev.absmax[ABS_MT_POSITION_Y] = screen_Height - 1;
ui_dev.absmin[ABS_MT_TRACKING_ID] = 0;
ui_dev.absmax[ABS_MT_TRACKING_ID] = 65535;
ui_dev.absmin[ABS_MT_PRESSURE] = 0;
ui_dev.absmax[ABS_MT_PRESSURE] = 30;
ui_dev.absmin[ABS_MT_TOOL_TYPE] = 0;
ui_dev.absmax[ABS_MT_TOOL_TYPE] = 1;

//enable direct
ioctl(uinp_fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT);
//enable mouse event
ioctl(uinp_fd, UI_SET_EVBIT, EV_REL);
ioctl(uinp_fd, UI_SET_RELBIT, REL_X);
ioctl(uinp_fd, UI_SET_RELBIT, REL_Y);
//enable touch event
ioctl(uinp_fd, UI_SET_EVBIT, EV_ABS);
for (i = 0; i <= ABS_CNT; i++) {
    ioctl(uinp_fd, UI_SET_ABSBIT, i);
}

ioctl(uinp_fd, UI_SET_EVBIT, EV_SYN);
ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY);
for (i = 0; i < 256; i++) {
    ioctl(uinp_fd, UI_SET_KEYBIT, i);
}
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MOUSE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_TOUCH);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MOUSE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_LEFT);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MIDDLE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_RIGHT);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_FORWARD);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_BACK);

write(uinp_fd, &ui_dev, sizeof(ui_dev));
if (ioctl(uinp_fd, UI_DEV_CREATE)) {
    debug("Unable to create UINPUT device.");
    return -1;
}
return 0;

}

and then write some events in uinput_fd, code segment like this:

 int len;
// Move pointer to (100,100) location
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = type;
event.code = code;
event.value = value;
len = write(uinp_fd, &event, sizeof(event));
debug("SendEventToUinput done:%d %d %d",type, code, value);

I can see events have writen on /dev/input/event7 in terminal by enter command "getevent -l", like this:

/dev/input/event7: EV_KEY       BTN_TOUCH            DOWN                
/dev/input/event7: EV_ABS       ABS_MT_TRACKING_ID   00000027            
/dev/input/event7: EV_ABS       ABS_MT_TOUCH_MAJOR   0000005d            
/dev/input/event7: EV_ABS       ABS_MT_POSITION_X    00000251            
/dev/input/event7: EV_ABS       ABS_MT_POSITION_Y    0000048f            
/dev/input/event7: EV_SYN       SYN_REPORT           00000000            
/dev/input/event7: EV_ABS       ABS_MT_TOUCH_MAJOR   00000045            
/dev/input/event7: EV_SYN       SYN_REPORT           00000000            
/dev/input/event7: EV_ABS       ABS_MT_TRACKING_ID   ffffffff            
/dev/input/event7: EV_SYN       SYN_REPORT           00000000            
/dev/input/event7: EV_KEY       BTN_TOUCH            UP                  
/dev/input/event7: EV_SYN       SYN_REPORT           00000000 

but nothing show on screen, if I send same events on "dev/input/event4" it can work? why "dev/uinput" is invalide?

Someone help me please.

caihanyuan
  • 23
  • 1
  • 4

5 Answers5

1

When you execute this part:

ioctl(uinp_fd, UI_SET_EVBIT, EV_ABS);
for (i = 0; i <= ABS_CNT; i++) {
    ioctl(uinp_fd, UI_SET_ABSBIT, i);
}

You also set ABS_X and ABS_Y bits. ABS_X and ABS_Y bits must not be set together with ABS_MT_POSITION_X and ABS_MT_POSITION_Y bits.

I suggest only set the ABS bits that you will use.

Garren
  • 91
  • 3
0

Your ui_dev.name already exist, use another one, and it will work fine.

jlo
  • 54
  • 4
0

Looking at implementation of adb shell input: https://android.googlesource.com/platform/frameworks/base/+/HEAD/cmds/input/src/com/android/commands/input/Input.java There are type conversions of the coordinates. May be that is the reason, why exactly same coordinates sent to the input event translated to a different coordinates when capturing same with adb shell getevent. I still not have a solution, but you might find useful this information - to have coordinates not be translated, need to inject it at AOSP level in float form. -- batcilla

-1

in my pionion, you should use adb command line like this:

adb shell sendevent /dev/input/event[event_number_here] input_value_here

ex:

adb shell sendevent /dev/input/event2 1 315 1
adb shell sendevent /dev/input/event2 0 0 0

or you can try this command:

adb shell input tap x y

ex: adb shell input tap 150 150

GiapLee
  • 436
  • 2
  • 8
  • adb shell sendevent to "/dev/input/eventX" can work, but when I write events in "dev/uinput" it can't simulate touch event. Is there something wrong in my code segment? – caihanyuan Mar 14 '16 at 08:11
-2

Try changing sequence of assigning arguments in:

strncpy(ui_dev.name, "RemoteTV Event", UINPUT_MAX_NAME_SIZE);

make it:

strncpy(ui_dev.name,  UINPUT_MAX_NAME_SIZE, "RemoteTV Event");
チーズパン
  • 2,752
  • 8
  • 42
  • 63
  • Above suggestion may not be useful. – Trushal Alshi Dec 02 '16 at 12:29
  • I ran the code, it works fine... But not sure why the pointer not pointing to exact absolute co-ordinates. I have a external mouse connected to the Android box.When the mouse is moved, it seems that some change in the reference axes takes place and EV_ABS co-ordinate location on display changes.Is there something like calibration or assigning reference point needed for each Touch Event. Or does REL_X , REL_Y of mouse interfere with ABS_MT_POSITION_X, ABS_MT_POSITION_Y of the virtual uinput event? Many thanks. – Trushal Alshi Dec 08 '16 at 05:17