android 录制

引用:http://www.jtben.com/document/919575

出自ATHZ-SEC1-WIKI

 
跳转到: 导航搜索

 

Android 事件录制脚本的生成 

Software R&D Center-SW R&D Dept.-Sec.1
HZSWTL2011008

Prepared by: Andy3 Liu
Jan. 21 2011


目录

[隐藏]

背景

AndroidAutoTest tool是通过ADB shell getevent 命令从android设备获取事件数据来实现事件录制的。然而获取的原始事件数据是字符与16进制数组成的字符串序列,不具备可读性及可修改性。根据项目设计要求,需根据监听结果实时的动态生成可执行的python脚本,以便于后期事件回放。从getevent获取的原始事件数据示例如下:

         4244-540927: /dev/input/event0: 0003 0000 0000009e  
         4244-541083: /dev/input/event0: 0003 0001 000001c7  
         4244-541182: /dev/input/event0: 0001 014a 00000001 
         4244-541283: /dev/input/event0: 0000 0000 00000000  
         4244-573333: /dev/input/event0: 0001 014a 00000000  
         4244-573473: /dev/input/event0: 0000 0000 00000000  
         4246-190284: /dev/input/event0: 0003 0000 00000080  
         4246-190440: /dev/input/event0: 0003 0001 000000a4  
         4246-190541: /dev/input/event0: 0001 014a 00000001  
         4246-190622: /dev/input/event0: 0000 0000 00000000  
         4246-238300: /dev/input/event0: 0001 014a 00000000  
         4246-238454: /dev/input/event0: 0000 0000 00000000  
         4247-704749: /dev/input/event0: 0003 0000 00000084  
         4247-704904: /dev/input/event0: 0003 0001 0000011e  
         4247-705004: /dev/input/event0: 0001 014a 00000001  
         4247-705085: /dev/input/event0: 0000 0000 00000000  
         4247-750322: /dev/input/event0: 0001 014a 00000000  
         4247-750408: /dev/input/event0: 0000 0000 00000000


最终预期转化为类似如下的脚本内容:

         KeyDown(102)
         Delay(17)  
         KeyUp(102)  
         Delay(1563)  
         TouchDown(158,455)  
         Delay(33)  
         TouchUp()  
         Delay(1617)  
         TouchDown(128,164)  
         Delay(48)  
         TouchUp()  
         Delay(1466)  
         TouchDown(132,286)  
         Delay(46)  
         TouchUp()

实现过程

整个过程最主要的工作就是解析事件数据流,即将数据流中解析成一个个完整独立的事件。

数据结构

以下2个类是解析过程中使用的主要数据结构:

EventItem:事件元,表示从设备读取的一行事件数据 Sec_time 事件发生时间的秒数
Ms_time 事件发生时间的微妙数
type 事件类型码
code 扫描码或键值
value
RawInputEvent:一个完整的事件所包含的所有属性,尚未被识别 When (default = -1) 事件发生时间的毫秒数
Type (default = -1) 事件类型码
Keycode (default = -1) 键值
Value (default = -1)
X (default = -1) X坐标值
Y (default = -1) Y坐标值

事件监听数据的获取

事件数据读取是通过调用ddmslib中的IDevice提供的public void executeShellCommand(String command, IShellOutputReceiver receiver, int maxTimeToOutputResponse)接口函数来实现的,此处command参数为:”getevent -t”。自定义一个实现了IShellOutputReceiver接口的MultiLineReceiver子类实例receiver,每当设备有事件发生时,receiver中实现的回调函数processNewLines(String[] lines)就会被调用,其参数lines就是从设备获取到的事件数据。接下来在processNewLines函数中解析lines即可。

监听数据解析

本节描述如何将原始事件数据中解析成事件。此部分由一个EventParse类完成。
由于android模拟器与真是设备以及设备与设备之间的存在差异,读取到的原始事件数据格式往往各不一样,解析起来略有不同,因此需要根据连接设备的不同实现各自的解析器类。以下内容暂基于模拟器。

事件类型

经分析可发现,Android设备的事件可以细分为如下5种基本类型:
KeyDown: 键按下
KeyUp: 键弹起
TouchDown: 触屏按下
TouchMove: 触屏移动
TouchUp: 触屏弹起

其他所有事件都是上述事件中的一种或多种的组合。

事件数据提取

从android设备读取的原始事件流由一行行如:

         422-211293: /dev/input/event0: 001 014a 00000001

的字符串组成,从左到右可以得到如下信息:

sec_time 事件发生时间的秒数
ms_time 事件发生时间的微妙数
deviceId android设备事件输入文件名
type 事件类型码
code 扫描码或键值
value

这样每一行都可以得到一个实例化的EventItem对象。这里一个EventItem对象就表示一个事件元素

事件识别

一个完整的keydown、TouchDown或TouchUp等事件是由一个或多个事件元素组成。通常一个完整的事件产生后会紧跟着一个事件同步行,标志一个完整事件的结束,该行数据由全零组成。开始处理前实例化一个空的RawInputEvent对象,然后我们可以一行一行的如下处理来填充这个对象:

TypeCodeValue填充RawInputEvent实例
0x01 code (<0x100) 1 Keycode = code 
Value = 1
0x01 code (<0x100) 0 Keycode = code 
Value = 0
0x01 0x14a 1 Value = 1
0x01 0x14a 0 Value = 0
0x03 1 x X = x
0x03 0 y Y = y
0 0 0 事件完成

当读到一个事件同步行时,一个完整独立的事件就完成了,RawInputEvent实例中已经包含了该事件的完整数据。然后对该实例各属性进行判断来识别事件类型,具体如下:

RawInputEvent事件实例属性 识别结果
TypeKeycodeValueXY
1 code 1     KeyDown事件,keycode=code
1 code 0     KeyUp事件,Keycode=code
3   1 x x TouchDown事件,X=x,Y=y
3   0 -1 -1 TouchUp事件
3   -1 x y TouchMove事件,X=x,Y=y

脚本生成

每解析出一个事件,我们就向录制脚本内容中添加一行对应代码,该行是一个已定义好的python函数的语句,表示执行一个事件动作,其参数就是该类型事件所必要的属性。函数与事件类型的对应关系如下:

事件类型必要属性Python语句
键按下 键值:Keycode KeyDown(keycode)
键弹起 键值:keycode KeyUp(keycode)
触屏按下 X坐标值:x Y坐标值:y TouchDown(x,y)
触屏弹起 TouchUp()
触屏移动 X坐标值:x Y坐标值:y TouchMove(x,y)

另外,每个事件发生的时间是不同的,两两之间有一定的间隔。在向脚本中新添加一行事件前,首先计算当前添加时间与上一事件的添加事件的差值s,然后插入一行python函数代码:Delay(s),表示两事件之间发生时间的间隔,再将当前事件代码添加进脚本中。

脚本运行

一次录制完成后,得到的脚本内容是由一连串python函数语句组成,示例如下图所示:
Simple-script.png
所有函数均是上一节中提到的6个事件函数中的一个。显然此脚本是无法直接执行的。所有脚本在被执行前都需事先加载一个公用的模块,该模块中定义了若干函数,包括上面6个事件函数。头模块加上录制得到的脚本内容就组成了一个可执行的python脚本,示例如下:
Detail-script.png
脚本录制完成之后执行之前可以被编辑修改,插入一些其他函数或逻辑判断语句等符合python语法规则与代码格式的内容,以实现测试人员期望的动作或流程。

posted @ 2013-03-15 17:37  镇水古月  阅读(355)  评论(0编辑  收藏  举报