STF STF 框架之 minitouch 工具

汪汪 · March 15, 2016 · Last by 梦想网络 replied at September 27, 2019 · 9933 hits
本帖已被设为精华帖!

前言

有感于各路大神对STF细节功能的挖掘:
STF 框架之 minicap 工具
[STF 系列] 无痛接入基于 LDAP 的单点登录
发现除了minicap之外,对于STF的设备管理的触摸功能,他们用的是类似的依赖工具,叫minitouch,Git地址:https://github.com/openstf/minitouch

minitouch介绍

跟minicap一样,minitouch也是用NDK开发的,跟minicap使用方法类似,不过它只要上传一个minitouch文件就可以了。对应的文件路径树跟minicap一样就不重复介绍(不过它只需要对应不同的CPU的ABI,而不需要对应SDK版本)。实际测试这个触摸操作和minicap一样,实时性很高没什么卡顿。

使用概述

  • 判断设备的CPU的ABI: adb shell getprop ro.product.cpu.abi armeabi-v7a
  • adb push对应的minitouch文件到设备上(libs/$ABI对应的为你本地的minitouch路径): adb push libs/$ABI/minitouch /data/local/tmp/
  • 比较关键的一步,因为push上去的文件是没有执行权限的,需要运行chmod提升权限: C:\Users\Administrator>adb shell sshell@shamu:/ $ su root@shamu:/ # cd /data/local/tmp root@shamu:/data/local/tmp # chmod 777 minitouch root@shamu:/data/local/tmp # ls -l -rwxrwxrwx shell shell 25920 2016-02-24 21:09 minitouch
  • 本地端口转发(端口可以任意) adb forward tcp:1111 localabstract:minitouch
  • 启动minitouch

    C:\Users\Administrator>adb shell /data/local/tmp/minitouch
    Note: device /dev/input/mice is not supported by libevdev
    Type B touch device atmel_mxt_ts (1439x2559 with 16 contacts) detected on /dev/i
    nput/event0 (score 1100)
    Note: hard-limiting maximum number of contacts to 10

    minitouch执行触摸命令

    和minicap类似,minitouch也是通过socket通信进行操作,只不过minicap是读取socket信息,而minitouch则是向socket发送信息进行设备操作。
    每一个触摸操作为一条socket命令。
    写入的命令分别有

  • d 按下的操作,命令格式为:

    d <contact> <x> <y> <pressure>

    contact为触摸点索引,从0开始,可以有多个触摸点, 为具体点击的坐标,为压力值。(注意在程序中实现时每个命令结束一定要加上'\n')

    d 0 10 10 50\n
  • m 划动的操作,命令格式为:

    m <contact> <x> <y> <pressure>

    contact为触摸点索引,从0开始,可以有多个触摸点, 为要移动到的xy坐标,为压力值

    m 0 100 100 50\n
  • u 松开的操作,命令格式为:

    u <contact> 

    contact为触摸点索引,从0开始,可以有多个触摸点

    u 0\n
  • c 操作
    commit操作,用于提交当前的触摸设置并在屏幕上执行。注意对于相同触摸点的每条d、m、u操作后面都需要跟一个c操作,才能正确的在屏幕上执行

    c\n

    那么合在一起操作,比如点击设备的(0,0)并划动到(100,100)然后放开

    d 0 0 0 50\n
    c\n
    m 0 100 100 50\n
    c\n
    u 0\n
    c\n

    两个手指同时点击(10,10)和(20,20)

    d 0 10 10 50\n
    d 1 20 20 50\n
    c\n
    u 0\n
    u 1\n
    c\n

minitouch的output信息

之后进行触摸操作的时候我发现,部分设备是可以准确的执行到正确的坐标,而部分设备坐标存在巨大的偏差。于是有仔细的看下文档,仔细看了minitouch的output部分信息:

When you first open a connection to the socket, you'll get some protocol metadata which you'll need need to read from the socket. Other than that there will be no responses of any kind.

首先,当socket连接建立的时候,socket的首次output信息会返回minitouch对应的头信息,我尝试用一段C#代码对它进行读取

static void Main(string[] args)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1111));
byte[] chunk = new byte[1024];
socket.Receive(chunk);
Console.WriteLine(System.Text.Encoding.Default.GetString(chunk));
Console.ReadLine();
}

执行后可以看到返回的数据为:

官方文档中对它的描述分别为:

  • v minitouch协议的版本
  • ^ 这一段为对应的参数上线,如支持的最大触摸点个数,和触摸的x,y坐标的最大值,最大压力值(貌似搞不懂这个鸭梨)
  • $ 文档上写的是minicap 的pid(这个没确认过是否它写错了还是真的是和minicap有关)

这边要重点说的是max-x和max-y,这边返回的值有可能和你的设备的真实大小并不是一样的,比如我用三星GalaxyNote10.1的平板调试,读取到的max-x和max-y分别为4095x4095,而设备的实际分辨率为1600x2560。
所以我注意看了下官方文档有写了:

It's also very important to note that the maximum X and Y coordinates may, but usually do not, match the display size. You'll need to work out a good way to map display coordinates to touch coordinates if required, possibly by using percentages for screen coordinates.
文档里有说到通常不匹配显示大小,你需要自己用一个方法来映射坐标,建议是用百分比来显示

于是我做了个实验,对设备发送了

d 0 2048 2048 50\n      
c\n

然后在设备上发现,设备被点击的坐标是800,1280,果然分别是真实坐标的一半。
那么就是说我们在实际应用中需要给设备分别换算出真实设备大小和minitouch映射大小的宽度和高度的百分比参数,来进行正确的坐标映射。
需要对设备进行操作的时候,将要点击的坐标除以这个百分比就可以得到要给设备发送的正确坐标。
用C#做了个简单的实现:

public class MiniTouchStream
{
private String IP = "127.0.0.1";
private int PORT = 1111;
private Socket socket;
private Banner banner = new Banner();
private AndroidDevice device;

public Banner Banner
{
get
{
return banner;
}
}

public MiniTouchStream(AndroidDevice device)
{
this.device = device;
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(new IPEndPoint(IPAddress.Parse(IP), PORT));
ParseBanner(socket);
}

private void ParseBanner(Socket socket)
{
byte[] chunk = new byte[64];
socket.Receive(chunk);
string[] result = Encoding.Default.GetString(chunk).Split(new char[2] { '\n', ' ' }).ToArray();
banner.Version = Convert.ToInt32(result[1]);
banner.MaxContacts = Convert.ToInt32(result[3]);
banner.MaxX = Convert.ToInt32(result[4]);
banner.MaxY = Convert.ToInt32(result[5]);
banner.MaxPressure = Convert.ToInt32(result[6]);
banner.Pid = Convert.ToInt32(result[8]);
banner.PercentX = (double)device.Width / banner.MaxX;
banner.PercentY = (double)device.Height / banner.MaxY;
}

public void TouchDown(Point downpoint)
{
Point realpoint = PointConvert(downpoint);
ExecuteTouch(string.Format("d 0 {0} {1} 50\n", realpoint.X.ToString(), realpoint.Y.ToString()));
}

public void TouchUp()
{
ExecuteTouch(string.Format("u 0\n"));
}

public void TouchMove(Point movepoint)
{
Point realpoint = PointConvert(movepoint);
ExecuteTouch(string.Format("m 0 {0} {1} 50\n", realpoint.X.ToString(), realpoint.Y.ToString()));
}

public void ExecuteTouch(string touchcommand)
{
byte[] inbuff = Encoding.ASCII.GetBytes(touchcommand);
socket.Send(inbuff);
string ccommand = "c\n";
inbuff = Encoding.ASCII.GetBytes(ccommand);
socket.Send(inbuff);
}

private Point PointConvert(Point point)
{
Point realpoint = new Point((int)(point.X / banner.PercentX) * device.Scale, (int)(point.Y / banner.PercentY) * device.Scale);
return realpoint;
}
}

最后贴个结合minicap和minitouch简单写的一个小demo,
C#demo
第一次启动可能会稍微慢点,耐心等下

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 20 条回复 时间 点赞

赞。学习了。

—— 来自TesterHome官方 安卓客户端

知道stf开发这个工具的用意是什么吗

汪汪 #3 · March 15, 2016 作者

#2楼 @seveniruby 母鸡噢~ -。- ~我原来以为只是给stf用的。。。。。

#2楼 @seveniruby 很明显,发送指令用的啊,比如你点击stf界面上的界面,他要发送点击指定给device端

#4楼 @doctorq 那为什么不用adb那

#5楼 @seveniruby 慢以及不稳定

汪汪 #7 · March 16, 2016 作者

#6楼 @doctorq 同意,试过demo就可以看出这个操作响应的实时性是多高。。。我试过用这个在屏幕上直接打了盘皇室战争~~哈哈 。。。。。

#2楼 @seveniruby 同问

—— 来自TesterHome官方 安卓客户端

好东西啊

你好,能写一篇stf 部署在服务器的教程吗?

#10楼 @siterui 网上大把,但要***,注意相关的版本号就可以了。

#11楼 @0x88 嗯,主要是e文差,很多都看不明白

#12楼 @siterui 我有写文档和资源包,过两天整理下再发出来。

请问楼主是怎么编译成so的,我弄了好久都没成功,主要是#include 这东西不知道怎么弄

c# 的啊 之前没看到 源码 拿走了 研究一下 thanks

感谢大神分享,还有源码,调试看看

官方说点击的操作如下:

d 0 10 10 50
c
u 0
c

为何我这样操作还是跟长按了一样。。

demo好像出了点什么问题呢:

minitouch 可以监控获取手机上点击、滑动的坐标吗

win7 打不开 直接已停止工作

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up