首页
社区
课程
招聘
[原创]通过模拟触摸屏控制器驱动来实现手机点击,滑动操作
发表于: 2023-12-16 01:28 10566

[原创]通过模拟触摸屏控制器驱动来实现手机点击,滑动操作

2023-12-16 01:28
10566

该项目主要作用是模拟驱动来实现对触摸屏的操控。如:滑动,点击操作。

本人使用该代码,尝试在真机上在某社交app执行点赞以及滑动下一个视频动作。

这是在下的项目地址:
https://github.com/2290474055/marlin_touch_set_input/tree/main

该手机使用的是真机piexl 1,系统版本是android10

直接使用synaptics_dsx_core.c替换掉原先的驱动中的该文件,位于/private/msm-google/drivers/input/touchscreeen/synaptics_dsx_htc_2.6/synaptics_dsx_core.c

只需要创建一个android工程的c++版本,然后创建my_dev_user.cpp文件正常写c++代码或者c代码,或者将我的文件直接拷贝放到这里
在cmake中添加代码
add_executable(text_my_dev my_dev_user.cpp)
即可编译为elf可执行文件

至此,所有代码步骤完成。

在Linux输入子系统中报告触摸屏输入事件,通过调用
input_mt_slot(p_inputdev,0);
input_mt_report_slot_state(p_inputdev,MT_TOOL_FINGER, 1);
input_report_key(p_inputdev,BTN_TOUCH, 1);
input_report_key(p_inputdev,BTN_TOOL_FINGER, 1);
input_report_abs(p_inputdev,ABS_MT_POSITION_X, x);
input_report_abs(p_inputdev,ABS_MT_POSITION_Y, y);
input_report_abs(p_inputdev,ABS_MT_TOUCH_MAJOR,
synaptics_sqrt(wxwx + wywy));
input_report_abs(p_inputdev,ABS_MT_TOUCH_MINOR,min(wx, wy));
input_report_abs(p_inputdev,ABS_MT_PRESSURE, 1);

依据此原理,是可以通过构建android动态加载的驱动ko文件可以制作一个通用驱动。但本人并没有深入继续研究该目标。仅供需要的大佬考虑。

整个分为3个部分
整个分为3个部分
    文件synaptics_dsx_core.c,该驱动为内核原本的驱动,其中添加了函数synaptics_rmi4_f12_abs_report_me为关键代码用来向输入子系统报告触摸屏操作。通过封装synaptics_rmi4_f12_abs_report_me实现2个函数,set_input_touch_slide,set_input_touch_click分别实现滑动和点击事件
 
//该函数为实现触摸关键函数
//stop为控制是触摸还是停止,true为手指离开,false为手指还在屏幕上
//x,y位坐标
static int synaptics_rmi4_f12_abs_report_me(bool stop,int x,int y)
{
    int wx;
    int wy;
    //判断是手指是否离开触摸屏
    if(stop == true){
        data_me.object_type_and_status = 20;
    }else{
        data_me.object_type_and_status = F12_FINGER_STATUS;
    }
 
    wx = 0;
    wy = 0;
 
    switch (data_me.object_type_and_status) {
    case F12_FINGER_STATUS:
    case F12_GLOVED_FINGER_STATUS:
        /* Stylus has priority over fingers */     
        printk(KERN_ALERT "zeyu F12_GLOVED_FINGER_STATUS\n");
        //向输入子系统报告触摸屏触摸信息,p_inputdev为触摸屏设备的指针,该指针我是通过正常驱动函数中拿到的,当然也可以通过其他途径,大家自行考虑
        input_mt_slot(p_inputdev,0);
        input_mt_report_slot_state(p_inputdev,
                MT_TOOL_FINGER, 1);
 
        input_report_key(p_inputdev,
                BTN_TOUCH, 1);
        input_report_key(p_inputdev,
                BTN_TOOL_FINGER, 1);
        input_report_abs(p_inputdev,
                ABS_MT_POSITION_X, x);
        input_report_abs(p_inputdev,
                ABS_MT_POSITION_Y, y);
        input_report_abs(p_inputdev,
                ABS_MT_TOUCH_MAJOR,
                synaptics_sqrt(wx*wx + wy*wy));
        input_report_abs(p_inputdev,
                ABS_MT_TOUCH_MINOR,
                min(wx, wy));
 
 
        input_report_abs(p_inputdev,
                ABS_MT_PRESSURE, 1);
             
             
        break;
    default:
        //当手指离开触摸屏时执行到这里
        printk(KERN_ALERT "zeyu default\n");
        input_mt_slot(p_inputdev, 0);
        input_mt_report_slot_state(p_inputdev,
                    MT_TOOL_FINGER, 0);
        break;
    }
     
    //该函数执行立即同步,不然会有延迟
    input_sync(p_inputdev);
 
    return 0;
     
}
 
 
 
 
//该函数为实现点击触摸屏
void set_input_touch_click(int x,int y)
{
    //这是为了模拟更像所以多调用几次
    synaptics_rmi4_f12_abs_report_me(false,x,y);
    synaptics_rmi4_f12_abs_report_me(false,x,y);
    synaptics_rmi4_f12_abs_report_me(false,x,y);
    synaptics_rmi4_f12_abs_report_me(false,x,y);
    synaptics_rmi4_f12_abs_report_me(false,x,y);
    synaptics_rmi4_f12_abs_report_me(false,x,y);
    //手指离开屏幕(如果不设置,则表示为长时间触摸该位置)
    synaptics_rmi4_f12_abs_report_me(true,x,y);
    return;
}
//该代码作用为将该符号到处给其他驱动使用
EXPORT_SYMBOL(set_input_touch_click);
 
 
//该函数实现滑动触摸屏,为开始的位置到停止的位置,可以看到我都是分为9次移动过去,系统会通过判断时间等来判断点击和移动的。其中代码就不仔细分析了。
void set_input_touch_slide(int start_x,int start_y,int end_x,int end_y)
{
    int tmp_x = 0;
    int tmp_y = 0;
    int zeyu_x = 0;
    int zeyu_y = 0;
    size_t i = 0;
    if ((end_x == start_x) && (end_y == start_y)) {
        return;
    }
    if ((end_x >= start_x) && (end_y >= start_y)) {
        tmp_x = end_x - start_x;
        tmp_y = end_y - start_y;
        tmp_x = tmp_x / 9;
        tmp_y = tmp_y / 9;
        for (i = 0; i <= 9; i++)
        {
            zeyu_x = start_x + (tmp_x * i);
            zeyu_y = start_y + (tmp_y * i);
            if (i == 9) {
                zeyu_x = end_x;
                zeyu_y = end_y;
            }
            synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
            }
        synaptics_rmi4_f12_abs_report_me(true,0,0);
            return;
        }
    if ((end_x >= start_x) && (end_y <= start_y)) {
        tmp_x = end_x - start_x;
            tmp_y = start_y - end_y;
            tmp_x = tmp_x / 9;
            tmp_y = tmp_y / 9;
            for (i = 0; i <= 9; i++)
            {
                    zeyu_x = start_x + (tmp_x * i);
                    zeyu_y = start_y - (tmp_y * i);
                    if (i == 9) {
                        zeyu_x = end_x;
                        zeyu_y = end_y;
                    }
                    synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
            }
        synaptics_rmi4_f12_abs_report_me(true,0,0);
            return;
        }
    if ((end_x <= start_x) && (end_y >= start_y)) {
            tmp_x = start_x - end_x;
            tmp_y = end_y - start_y;
            tmp_x = tmp_x / 9;
            tmp_y = tmp_y / 9;
            for (i = 0; i <= 9; i++)
            {
                    zeyu_x = start_x - (tmp_x * i);
                    zeyu_y = start_y + (tmp_y * i);
                    if (i == 9) {
                        zeyu_x = end_x;
                        zeyu_y = end_y;
                    }
                    synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
            }
        synaptics_rmi4_f12_abs_report_me(true,0,0);
            return;
        }
    if ((end_x <= start_x) && (end_y <= start_y)) {
            tmp_x = start_x - end_x;
            tmp_y = start_y - end_y;
            tmp_x = tmp_x / 9;
            tmp_y = tmp_y / 9;
            for (i = 0; i <= 9; i++)
            {
                    zeyu_x = start_x - (tmp_x * i);
                    zeyu_y = start_y - (tmp_y * i);
                    if (i == 9) {
                        zeyu_x = end_x;
                        zeyu_y = end_y;
                    }
                    synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
            }
        synaptics_rmi4_f12_abs_report_me(true,0,0);
               return;
        }
    return;
}
EXPORT_SYMBOL(set_input_touch_slide);
    文件synaptics_dsx_core.c,该驱动为内核原本的驱动,其中添加了函数synaptics_rmi4_f12_abs_report_me为关键代码用来向输入子系统报告触摸屏操作。通过封装synaptics_rmi4_f12_abs_report_me实现2个函数,set_input_touch_slide,set_input_touch_click分别实现滑动和点击事件
 
//该函数为实现触摸关键函数
//stop为控制是触摸还是停止,true为手指离开,false为手指还在屏幕上
//x,y位坐标
static int synaptics_rmi4_f12_abs_report_me(bool stop,int x,int y)
{
    int wx;
    int wy;
    //判断是手指是否离开触摸屏
    if(stop == true){
        data_me.object_type_and_status = 20;
    }else{
        data_me.object_type_and_status = F12_FINGER_STATUS;
    }
 
    wx = 0;
    wy = 0;
 
    switch (data_me.object_type_and_status) {
    case F12_FINGER_STATUS:
    case F12_GLOVED_FINGER_STATUS:
        /* Stylus has priority over fingers */     
        printk(KERN_ALERT "zeyu F12_GLOVED_FINGER_STATUS\n");
        //向输入子系统报告触摸屏触摸信息,p_inputdev为触摸屏设备的指针,该指针我是通过正常驱动函数中拿到的,当然也可以通过其他途径,大家自行考虑
        input_mt_slot(p_inputdev,0);
        input_mt_report_slot_state(p_inputdev,
                MT_TOOL_FINGER, 1);
 
        input_report_key(p_inputdev,
                BTN_TOUCH, 1);
        input_report_key(p_inputdev,
                BTN_TOOL_FINGER, 1);
        input_report_abs(p_inputdev,
                ABS_MT_POSITION_X, x);
        input_report_abs(p_inputdev,
                ABS_MT_POSITION_Y, y);
        input_report_abs(p_inputdev,
                ABS_MT_TOUCH_MAJOR,
                synaptics_sqrt(wx*wx + wy*wy));
        input_report_abs(p_inputdev,
                ABS_MT_TOUCH_MINOR,
                min(wx, wy));
 
 
        input_report_abs(p_inputdev,
                ABS_MT_PRESSURE, 1);
             
             
        break;
    default:
        //当手指离开触摸屏时执行到这里
        printk(KERN_ALERT "zeyu default\n");
        input_mt_slot(p_inputdev, 0);
        input_mt_report_slot_state(p_inputdev,
                    MT_TOOL_FINGER, 0);
        break;
    }
     
    //该函数执行立即同步,不然会有延迟
    input_sync(p_inputdev);
 
    return 0;
     
}
 
 
 
 
//该函数为实现点击触摸屏
void set_input_touch_click(int x,int y)
{
    //这是为了模拟更像所以多调用几次
    synaptics_rmi4_f12_abs_report_me(false,x,y);
    synaptics_rmi4_f12_abs_report_me(false,x,y);
    synaptics_rmi4_f12_abs_report_me(false,x,y);
    synaptics_rmi4_f12_abs_report_me(false,x,y);
    synaptics_rmi4_f12_abs_report_me(false,x,y);
    synaptics_rmi4_f12_abs_report_me(false,x,y);
    //手指离开屏幕(如果不设置,则表示为长时间触摸该位置)
    synaptics_rmi4_f12_abs_report_me(true,x,y);
    return;
}
//该代码作用为将该符号到处给其他驱动使用
EXPORT_SYMBOL(set_input_touch_click);
 
 
//该函数实现滑动触摸屏,为开始的位置到停止的位置,可以看到我都是分为9次移动过去,系统会通过判断时间等来判断点击和移动的。其中代码就不仔细分析了。
void set_input_touch_slide(int start_x,int start_y,int end_x,int end_y)
{
    int tmp_x = 0;
    int tmp_y = 0;
    int zeyu_x = 0;
    int zeyu_y = 0;
    size_t i = 0;
    if ((end_x == start_x) && (end_y == start_y)) {
        return;
    }
    if ((end_x >= start_x) && (end_y >= start_y)) {
        tmp_x = end_x - start_x;
        tmp_y = end_y - start_y;
        tmp_x = tmp_x / 9;
        tmp_y = tmp_y / 9;
        for (i = 0; i <= 9; i++)
        {
            zeyu_x = start_x + (tmp_x * i);
            zeyu_y = start_y + (tmp_y * i);
            if (i == 9) {
                zeyu_x = end_x;
                zeyu_y = end_y;
            }
            synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
            }
        synaptics_rmi4_f12_abs_report_me(true,0,0);
            return;
        }
    if ((end_x >= start_x) && (end_y <= start_y)) {
        tmp_x = end_x - start_x;
            tmp_y = start_y - end_y;
            tmp_x = tmp_x / 9;
            tmp_y = tmp_y / 9;
            for (i = 0; i <= 9; i++)
            {
                    zeyu_x = start_x + (tmp_x * i);
                    zeyu_y = start_y - (tmp_y * i);
                    if (i == 9) {
                        zeyu_x = end_x;
                        zeyu_y = end_y;
                    }
                    synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
            }
        synaptics_rmi4_f12_abs_report_me(true,0,0);
            return;
        }
    if ((end_x <= start_x) && (end_y >= start_y)) {
            tmp_x = start_x - end_x;
            tmp_y = end_y - start_y;
            tmp_x = tmp_x / 9;
            tmp_y = tmp_y / 9;
            for (i = 0; i <= 9; i++)
            {
                    zeyu_x = start_x - (tmp_x * i);
                    zeyu_y = start_y + (tmp_y * i);
                    if (i == 9) {
                        zeyu_x = end_x;
                        zeyu_y = end_y;
                    }
                    synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
            }
        synaptics_rmi4_f12_abs_report_me(true,0,0);
            return;
        }
    if ((end_x <= start_x) && (end_y <= start_y)) {
            tmp_x = start_x - end_x;
            tmp_y = start_y - end_y;
            tmp_x = tmp_x / 9;
            tmp_y = tmp_y / 9;
            for (i = 0; i <= 9; i++)
            {
                    zeyu_x = start_x - (tmp_x * i);
                    zeyu_y = start_y - (tmp_y * i);
                    if (i == 9) {
                        zeyu_x = end_x;
                        zeyu_y = end_y;
                    }
                    synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
            }
        synaptics_rmi4_f12_abs_report_me(true,0,0);

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2024-7-16 22:56 被琳宇编辑 ,原因: 补充
收藏
免费 8
支持
分享
最新回复 (10)
雪    币: 1281
活跃值: (4515)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
支持!
2023-12-16 08:44
1
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
点赞
2023-12-16 15:46
0
雪    币: 1329
活跃值: (1929)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
为啥不用autojs呢?
2023-12-16 18:58
0
雪    币: 2937
活跃值: (30841)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
感谢分享
2023-12-16 23:19
0
雪    币: 147
活跃值: (1554)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
6
mb_lpcoesnt 为啥不用autojs呢?
是的,但是本人为了学习内核而写的。
2023-12-16 23:33
0
雪    币: 2546
活跃值: (4403)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
只有成果 没有过程
2023-12-18 18:55
0
雪    币: 14
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8

很棒的思路

最后于 2024-1-6 06:33 被mb_wxmrqhty编辑 ,原因:
2024-1-6 06:32
0
雪    币: 1671
活跃值: (215812)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
9
tql
2024-1-8 09:48
0
雪    币: 242
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
需要root吗?
2024-4-19 08:06
0
游客
登录 | 注册 方可回帖
返回
//