背景:
前面文章已经对aosp自带的uinput命令进行了如何使用的实战,具体看下面文章:
手把手教你uinput命令的使用方式-重学安卓input子系统
但是明显只使用命令还是有以下问题,命令注入事件性能不够块,注入的事件需要提前准备好,相当于只能实现录制事件,然后播放录制事件这种,所以基于这个背景那就需要有一个非常灵活的方式通过uinput来实现对事件的自由控制,那么需要使用代码来实现对/dev/uinput节点直接进行相关的事件写入,这样事件发什么都是由代码自由控制,灵活性大大提高。
下面就用代码实现注入鼠标设备,而且鼠标可以在拨号盘上面进行点击的功能
实战代码如下:
核心c文件如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <time.h>
#define die(str, args...) do { \
perror(str); \
exit(EXIT_FAILURE); \
} while(0)
int main(void)
{
int fd;
struct uinput_user_dev uidev;
struct input_event ev;
int dx = 0, dy = 0;
int i;
fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
if(fd < 0) die("error: open");
//config uinput working mode, mouse or touchscreen? relative coordinates or absolute coordinate?
if(ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0) //support key button
die("error: ioctl");
if(ioctl(fd, UI_SET_KEYBIT, BTN_LEFT) < 0) //support mouse left key
die("error: ioctl");
if(ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT) < 0) //support mouse right key
die("error: ioctl");
if(ioctl(fd, UI_SET_EVBIT, EV_REL) < 0) //uinput use relative coordinates
die("error: ioctl");
if(ioctl(fd, UI_SET_RELBIT, REL_X) < 0) //uinput use x coordinates
die("error: ioctl");
if(ioctl(fd, UI_SET_RELBIT, REL_Y) < 0) //uinput use y coordinates
die("error: ioctl");
memset(&uidev, 0, sizeof(uidev)); //creat an virtul input device node in /dev/input/***
snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-sample");
uidev.id.bustype = BUS_USB;
uidev.id.vendor = 0x1;
uidev.id.product = 0x1;
uidev.id.version = 1;
if(write(fd, &uidev, sizeof(uidev)) < 0)
die("error: write");
if(ioctl(fd, UI_DEV_CREATE) < 0)
die("error: ioctl");
sleep(2);
srand(time(NULL));
while(1) {
if (dx == 80) {
dx = -80;
}
//模拟鼠标移动
for(i = 0; i < 20; i++) {
//send input event to kernel input system
memset(&ev, 0, sizeof(struct input_event));
ev.type = EV_REL; //send x coordinates
ev.code = REL_X;
ev.value = dx = dx +1;
if(write(fd, &ev, sizeof(struct input_event)) < 0)
die("error: write");
memset(&ev, 0, sizeof(struct input_event));
ev.type = EV_REL; //send y coordinates
ev.code = REL_Y;
ev.value = dy;
if(write(fd, &ev, sizeof(struct input_event)) < 0)
die("error: write");
usleep(15000);
dy = 0;
}
//模拟鼠标左键点击
//mouse click left key begin
memset(&ev, 0, sizeof(struct input_event));
ev.type = EV_KEY; //mouse left key
ev.code = BTN_LEFT;
ev.value = 1;
if(write(fd, &ev, sizeof(struct input_event)) < 0)
die("error: write");
memset(&ev, 0, sizeof(struct input_event));
ev.type = EV_SYN; // inform input system to process this input event
ev.code = 0;
ev.value = 0;
if(write(fd, &ev, sizeof(struct input_event)) < 0)
die("error: write");
memset(&ev, 0, sizeof(struct input_event));
ev.type = EV_KEY; //mouse left key
ev.code = BTN_LEFT;
ev.value = 0;
if(write(fd, &ev, sizeof(struct input_event)) < 0)
die("error: write");
memset(&ev, 0, sizeof(struct input_event));
ev.type = EV_SYN; // inform input system to process this input event
ev.code = 0;
ev.value = 0;
if(write(fd, &ev, sizeof(struct input_event)) < 0)
die("error: write");
sleep(1);
//mouse click left key end
}
sleep(2);
if(ioctl(fd, UI_DEV_DESTROY) < 0)
die("error: ioctl");
close(fd);
return 0;
}
对应的Android.mk文件
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
uinput.c
LOCAL_MODULE := uinput_test
include $(BUILD_EXECUTABLE)
编译push:
mmm demo_uinput/
adb push out/target/product/emu64x/system/bin/uinput_test /data/local/tmp/
实战成果如下:
同时使用getevent命令也可以获取到相关的输出:
adb shell getevent -lrt
add device 15: /dev/input/event14
name: "uinput-sample"
[ 151687.511482] /dev/input/event14: EV_REL REL_X 00000001
[ 151687.511482] /dev/input/event14: EV_SYN SYN_REPORT 00000000 rate 0
[ 151687.526731] /dev/input/event14: EV_KEY BTN_MOUSE DOWN
[ 151687.526731] /dev/input/event14: EV_SYN SYN_REPORT 00000000 rate 65
[ 151687.526770] /dev/input/event14: EV_KEY BTN_MOUSE UP
[ 151687.526770] /dev/input/event14: EV_SYN SYN_REPORT 00000000 rate 25641
[ 151688.526906] /dev/input/event14: EV_REL REL_X 00000002
[ 151688.526906] /dev/input/event14: EV_SYN SYN_REPORT 00000000 rate 0
[ 151688.542255] /dev/input/event14: EV_KEY BTN_MOUSE DOWN
[ 151688.542255] /dev/input/event14: EV_SYN SYN_REPORT 00000000 rate 65
[ 151688.542324] /dev/input/event14: EV_KEY BTN_MOUSE UP
[ 151688.542324] /dev/input/event14: EV_SYN SYN_REPORT 00000000 rate 14492
更多framework实战干货,请关注下面“千里马学框架”