android使用uinput节点任意注入鼠标事件-重学安卓input子系统

背景:

前面文章已经对aosp自带的uinput命令进行了如何使用的实战,具体看下面文章: 手把手教你uinput命令的使用方式-重学安卓input子系统 但是明显只使用命令还是有以下问题,命令注入事件性能不够块,注入的事件需要提前准备好,相当于只能实现录制事件,然后播放录制事件这种,所以基于这个背景那就需要有一个非常灵活的方式通过uinput来实现对事件的自由控制,那么需要使用代码来实现对/dev/uinput节点直接进行相关的事件写入,这样事件发什么都是由代码自由控制,灵活性大大提高。

下面就用代码实现注入鼠标设备,而且鼠标可以在拨号盘上面进行点击的功能

实战代码如下:

核心c文件如下:

cpp 复制代码
#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文件

cpp 复制代码
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
    uinput.c

LOCAL_MODULE := uinput_test

include $(BUILD_EXECUTABLE)

编译push:

bash 复制代码
mmm demo_uinput/
adb push out/target/product/emu64x/system/bin/uinput_test /data/local/tmp/

实战成果如下: 同时使用getevent命令也可以获取到相关的输出:

adb shell getevent -lrt

bash 复制代码
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实战干货,请关注下面"千里马学框架"

原文地址:blog.csdn.net/learnframew...

相关推荐
郭老二7 小时前
【前端】vue3:编译步骤
前端
不在逃避q7 小时前
Trae/Vs Code/Cursor命令行无法跑npm命令
前端·arcgis·npm
夏殇之殁8 小时前
包中创建自定义列表项。 . 使用自定义列表项进行数据绑定 . 将天气预报数据保存到本地内存表,通过LiveBindings进行显示。 ...
服务器·前端·javascript
The Chosen One9858 小时前
高进度算法模板速记(待完善)
java·前端·算法
陈随易8 小时前
MoonBit抓包模块pcap,查看电脑的每一次联网通信
前端·后端·程序员
新中地GIS开发老师9 小时前
WebGIS开发学生作品|低空航天管理与航线规划系统
前端·javascript·webgis·三维gis开发
用户059540174469 小时前
大模型对话记忆持久化踩坑实录:用 Playwright 自动化测了 300 次,终于揪出会话丢失的真凶
前端·css
丙氨酸長鏈9 小时前
Web前端入门第 问:JavaScript 一个简单的 IndexedDB 数据库入门示例
前端·javascript·数据库
kyriewen10 小时前
面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了
前端·javascript·面试
IT_陈寒10 小时前
Vite热更新失效?你可能漏了这个配置
前端·人工智能·后端