Android 4.0系统触摸设备概述    
1. Touch Device 分类
    在Android系统中触摸设备分为两类。
   多点触摸:
       设备支持ABS_MT_POSITION_X,ABS_MT_POSITION_Y绝对坐标
       输入设备没有任何按键,采用获得的多点触摸坐标来替代按键
   单点触摸:
       不支持多点触摸的都是单点触摸设备。
       设备需要支持ABS_X,ABS_Y绝对坐标,BTN_TOUCH键值。
   一旦一个设备被认为是触摸设备,通过设备的虚拟键映射文件来确定虚拟键。如果虚拟键映射文件不可用,设备的键盘布局文件会被载入。所有的内置触摸设备都应该有输入设备配置文件。如果没有该文件,系统将选择缺省配置文件。缺省配置文件主要针对通用目的的典型设备,比如外接USB或蓝牙触摸屏,触摸板。他们没有针对内置触摸屏设计,因此一般不会有好结果(:))。
   当输入配置文件被载入后,系统确定输入设备的类型,一般为三类: touch
screen, touch pad , pointer device.  (三类设备的描述见原文。)

   触摸设备的分类规则如下:
   1. 如果touch.deviceType特性被设置,则设备类型被指定。
   2. 果设备提供INPUT_PROP_DIRECT 特性,将会被认为是触摸屏,
   3. 如果设备提供INPUT_PROP_POINTER特性,将会被认为是触摸点
   4. 如果设备提供REL_X,REL_Y特性,将会被认为是触摸板。
   5. 其他情况,设备将会被认识为pointer设备。
2. 按钮
    按键时一个可选控制项,常被应用程序用来实现扩展功能。触摸设备上的按钮的功能与鼠标按钮基本类似,主要用于pointer类型触摸设备。
    一般支持下列按钮:

BTN_LEFT: mapped to MotionEvent.BUTTON_PRIMARY. 

     BTN_RIGHT: mapped to MotionEvent.BUTTON_SECONDARY. 

     BTN_MIDDLE: mapped to MotionEvent.BUTTON_MIDDLE. 

     BTN_BACK and BTN_SIDE: mapped to MotionEvent.BUTTON_BACK. Pressing this button also synthesizes a key press with the key code KeyEvent.KEYCODE_BACK. 

     BTN_FORWARD and BTN_EXTRA: mapped to MotionEvent.BUTTON_FORWARD. Pressing this button also synthesizes a key press with the key code KeyEvent.KEYCODE_FORWARD. 

     BTN_STYLUS: mapped to MotionEvent.BUTTON_SECONDARY. 

     BTN_STYLUS2: mapped to MotionEvent.BUTTON_TERTIARY.



3.  工具与工具类型
    此处的工具是指手指,触摸笔或其他用于接触触摸设备的东西。现在很多触摸设备支持多种触摸工具。对于Android系统中,在MotionEvent中,工具通常指一个点。
    支持的工具类型如下:

BIN_TOOL_FINGER and MT_TOOL_FINGER: mapped to MotionEvent.TOOL_TYPE_FINGER. 

     BTN_TOOL_PEN and MT_TOOL_PEN: mapped to MotionEvent.TOOL_TYPE_STYLUS. 

     BTN_TOOL_RUBBER: mapped to MotionEvent.TOOL_TYPE_ERASER. 

     BTN_TOOL_BRUSH: mapped to MotionEvent.TOOL_TYPE_STYLUS. 

     BTN_TOOL_PENCIL: mapped to MotionEvent.TOOL_TYPE_STYLUS. 

     BTN_TOOL_AIRBRUSH: mapped to MotionEvent.TOOL_TYPE_STYLUS. 

     BTN_TOOL_MOUSE: mapped to MotionEvent.TOOL_TYPE_MOUSE. 

     BTN_TOOL_LENS: mapped to MotionEvent.TOOL_TYPE_MOUSE. 

     BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP, and BTN_TOOL_QUADTAP: mapped to MotionEvent.TOOL_TYPE_FINGER.



4.  悬停状态 vs 触摸状态
    InputReader组件能将悬停中的工具和触摸中的工具区分开。同样的,悬停中的工具和触摸中的工具用不同的方式向应用程序报告。

Touching tools are reported to applications as touch events using MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE, MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWN and MotionEvent.ACTION_POINTER_UP. 

    Hovering tools are reported to applications as generic motion events using MotionEvent.ACTION_HOVER_ENTER, MotionEvent.ACTION_HOVER_MOVE and MotionEvent.ACTION_HOVER_EXIT.



5.  触摸设备驱动要求:
    5.1. 触摸设备应该只注册他们实际支持的键和坐标。注册超量的坐标或键值将造成系统特定算法混乱或造成系统不能正确识别设备。例如: 如果一个设备返回了BTN_TOUCH键值,无论工具实际触摸屏幕或只是在一个范围内悬停,系统将假定BTN_TOUCHIN被触发。
    5.2. 单点触摸设备用下列Linux输入事件:
  

ABS_X: (REQUIRED) Reports the X coordinate of the tool. 

     ABS_Y: (REQUIRED) Reports the Y coordinate of the tool. 

     ABS_PRESSURE: (optional) Reports the physical pressure applied to the tip of the tool or the signal strength of the touch contact. 

     ABS_TOOL_WIDTH: (optional) Reports the cross-sectional area or width of the touch contact or of the tool itself. 

     ABS_DISTANCE: (optional) Reports the distance of the tool from the surface of the touch device. 

     ABS_TILT_X: (optional) Reports the tilt of the tool from the surface of the touch device along the X axis. 

     ABS_TILT_Y: (optional) Reports the tilt of the tool from the surface of the touch device along the Y axis. 

     BTN_TOUCH: (REQUIRED) Indicates whether the tool is touching the device. 

     BTN_LEFT, BTN_RIGHT, BTN_MIDDLE, BTN_BACK, BTN_SIDE, BTN_FORWARD, BTN_EXTRA, BTN_STYLUS, BTN_STYLUS2: (optional) Reports button states. 

     BTN_TOOL_FINGER, BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_BRUSH, BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH, BTN_TOOL_MOUSE, BTN_TOOL_LENS, BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP, BTN_TOOL_QUADTAP: (optional) Reports the tool type.


    5.3.  多点触摸设备用下列Linux输入事件:
 

ABS_MT_POSITION_X: (REQUIRED) Reports the X coordinate of the tool. 

     ABS_MT_POSITION_Y: (REQUIRED) Reports the Y coordinate of the tool. 

     ABS_MT_PRESSURE: (optional) Reports the physical pressure applied to the tip of the tool or the signal strength of the touch contact. 

     ABS_MT_TOUCH_MAJOR: (optional) Reports the cross-sectional area of the touch contact, or the length of the longer dimension of the touch contact. 

     ABS_MT_TOUCH_MINOR: (optional) Reports the length of the shorter dimension of the touch contact. This axis should not be used if ABS_MT_TOUCH_MAJOR is reporting an area measurement. 

     ABS_MT_WIDTH_MAJOR: (optional) Reports the cross-sectional area of the tool itself, or the length of the longer dimension of the tool itself. This axis should not be used if the dimensions of the tool itself are unknown. 

     ABS_MT_WIDTH_MINOR: (optional) Reports the length of the shorter dimension of the tool itself. This axis should not be used if ABS_MT_WIDTH_MAJOR is reporting an area measurement or if the dimensions of the tool itself are unknown. 

     ABS_MT_ORIENTATION: (optional) Reports the orientation of the tool. 

     ABS_MT_DISTANCE: (optional) Reports the distance of the tool from the surface of the touch device. 

     ABS_MT_TOOL_TYPE: (optional) Reports the tool type as MT_TOOL_FINGER or MT_TOOL_PEN. 

     ABS_MT_TRACKING_ID: (optional) Reports the tracking id of the tool. The tracking id is an arbitrary non-negative integer that is used to identify and track each tool independently when multiple tools are active. For example, when multiple fingers are touching the device, each finger should be assigned a distinct tracking id that is used as long as the finger remains in contact. Tracking ids may be reused when their associated tools move out of range. 

     ABS_MT_SLOT: (optional) Reports the slot id of the tool, when using the Linux multi-touch protocol 'B'. Refer to the Linux multi-touch protocol documentation for more details. 

     BTN_TOUCH: (REQUIRED) Indicates whether the tool is touching the device. 

     BTN_LEFT, BTN_RIGHT, BTN_MIDDLE, BTN_BACK, BTN_SIDE, BTN_FORWARD, BTN_EXTRA, BTN_STYLUS, BTN_STYLUS2: (optional) Reports button states. 

     BTN_TOOL_FINGER, BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_BRUSH, BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH, BTN_TOOL_MOUSE, BTN_TOOL_LENS, BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP, BTN_TOOL_QUADTAP: (optional) Reports the tool type.


    5.4.  如果单点触摸和多点触摸的坐标都被设定,只有多点触摸的坐标被使用,单点触摸的坐标将会被忽略。
    5.5.  ABS_X,ABS_Y,ABS_MT_POSITION_X,ABS_MT_POSITION_Y坐标的最大值和最小值定义了设备的活动区域(单位: 设备特定平面单位)。对于触摸屏,活动范围对应于实际显示部分。
          对于触摸屏,系统自动将触摸位置从平面单位转换为显示像素,转换公式如下:
               displayX = (x - minX) * displayWidth / (maxX - minX + 1)
               displayY = (y - minY) * displayHeight / (maxY - minY + 1)
           一个触摸屏可能会返回超出活动范围的触摸坐标。
           超出活动范围的触摸点,不会转发给应用程序,可能被用作虚拟键。
           在活动区域内,或进入,离开显示区域的触摸点都将转发给应用程序。当然,如果一个触摸从应用程序内开始,移动到活动区域外面,应用程序将接受到触摸事件的显示坐标,它可能是个负数,或超出活动范围。
        一个触摸设备应该不要限定触摸坐标在活动区域范围内,如果一个触摸退出了活动区域,它应该作为超出活动范围的报告,或根本不报告。
    5.6.  当工具接触设备时,ABS_PRESSUER或ABS_MT_PRESSUER的值,必须时非0值。0指明工具为悬停状态。报告pressure信息是可选的,但是强烈推荐。应用程序能用压力信息去实现压力感应图或其他功能。
    5.7.  当工具接触设备时,ABS_TOOL_WIDTH, ABS_MT_TOUCH_MAJOR, ABS_MT_TOUCH_MINOR, ABS_MT_WIDTH_MAJOR, or ABS_MT_WIDTH_MINOR应该为非0值,0时其他情况(非强制要求)。 报告size信息时可选的,但强烈推荐.
    5.8.  当时工具接触设备时, ABS_DISTANCE or ABS_MT_DISTANCE 应该近似0.
    5.9.  当工具与设备垂直时, ABS_TILT_X and
ABS_TILT_Y应该为0 。 (后面内容没翻译,请见原文)
    5.10. 如果工具类型被定义为ABS_MT_TOOL_TYPE,它将支持所有的BTN_TOOL_*。如果根本没有工具类型时有效的,默认工具类型: MotionEvent.TOOL_TYPE_FINGER.
    5.11. 符合下列条件,工具将被认是激活的:
        当使用单点触摸协议,如果BTN_TOUCH,或BTN_TOOL_*为1,工具是激活的。
        当使用多点触摸协议‘A',只要它出现在最近的同步报告中,他是激活的。如果工具停止出现在同步报告中,它结束存在。
        当使用多点触摸协议‘b’,只要他有一个活动槽,工具就是激活的。当它离开槽,工具结束存在。
    5.12.  根据下列条件决定工具悬停状态:
        如果工具类型为: BTN_TOOL_MOUSE or BTN_TOOL_LENS,无论其他条件是否满足,他们都没有悬停状态。
        如果工具是活动的,并且驱动报告压力信息,但压力为0,这是工具时悬停的。
        如果工具是活动的,并且驱动支持BTN_TOUCH键值,并且BTN_TOUCH为0,工具时悬停的。
    5.13. InputReader支持多点触摸协议a,b,新驱动应该用b协议,但是,A也能用。
    5.14. 对于anroid4.0,触摸屏驱动需要符合Linux 输入协议规范。
        下列改变时必须的:
        1. 但是工具变成非激活(手指抬起),它应该停止出现在多点触摸的后续同步报告中。当所有的工具都变成非激活,驱动应该发送一个空同步报告包。例如:SYN_REPORT后面跟 SYN_MT_REPORT。
       前面的android版本,通过发送压力值为0,作为up事件。旧的行为与Linux输入协议规范不兼容,不再支持。
         2. 物理压力或信号强度信息应该用ABS_MT_PRESSURE报告,前期android版本反馈压力信息用ABS_MT_TOUCH_MAJOR,旧的行为与Linux输入协议规范不兼容,不再支持。
         3. 触摸大小信息应该用 ABS_MT_TOUCH_MAJOR报告,以前的android用ABS_MT_TOOL_MAJOR,旧的行为与Linux输入协议规范不兼容,不再支持。
     触摸设备驱动不再需要Android特定自定义,通过遵守标准Linux输入协议,Android能支持很多触摸设备。

6. 触摸设备操作
    下面是android平台触摸设备操作的简短摘要:
     1. EventHub 从evdev驱动读取未处理的事件。
     2. InputReade 处理未处理事件,并且更新位置的内部状态,工具的特性,按键状态。
     3. 如果BACK或FORWARD键被按下或弹起,InputReader将向InputDispatcher报告按键状态。
     4. InputReader决定虚拟按键是否发生,如果发生,将向InputDispatcher报告按键状态。
     5. InputReader决定触摸是否发生在显示范围内,如果是,它向InputDispatcher报告触摸事件。
     6. 如果没有触摸中的工具,但是至少有一个悬停中的工具,InputReader向InputDispatcher报告悬停事件。
     7. 如果触摸设备类型为pointer,InputReader进行点位置检测,同步移动点,并向InputDispatcher报告点事件。
     8. InputDispatcher用WindowManagerPolicy来决定是否派遣事件,是否需要唤醒服务。这是InputDispatcher转发事件到对应的应用程序。

7. 触摸设备配置文件:
     触摸设备的行为通过设备的坐标轴,按键,输入特性,输入设备配置,虚拟按键映射和按键布局来决定。
    7.1  特性
    系统通过许多输入设备配置特性来配置和校准触摸设备的行为。
    这个做的一个原因时因为触摸设备的驱动程序经常用设备特定单位来报告触摸特性。例如,许多触摸设备测量触摸区域用设备特定的内置比例因子。
    系统用输入设备配置文件中编码校准参数去解码,转换,规范触摸设备返回的值,使之变成应用程序能明白的标准值。
    7.2 文档约定:
        7.2.1 未处理坐标轴值:(通过触摸设备驱动EV_ABS事件报告)
        

raw.x    The value of the ABS_X or ABS_MT_POSITION_X axis. 

             raw.y    The value of the ABS_Y or ABS_MT_POSITION_Y axis. 

             raw.pressure    The value of the ABS_PRESSURE or ABS_MT_PRESSURE axis, or 0 if not available. 

             raw.touchMajor    The value of the ABS_MT_TOUCH_MAJOR axis, or 0 if not available. 

             raw.touchMinor    The value of the ABS_MT_TOUCH_MINOR axis, or raw.touchMajor if not available. 

             raw.toolMajor    The value of the ABS_TOOL_WIDTH or ABS_MT_WIDTH_MAJOR axis, or 0 if not available. 

             raw.toolMinor    The value of the ABS_MT_WIDTH_MINOR axis, or raw.toolMajor if not available. 

             raw.orientation    The value of the ABS_MT_ORIENTATION axis, or 0 if not available. 

             raw.distance    The value of the ABS_DISTANCE or ABS_MT_DISTANCE axis, or 0 if not available. 

             raw.tiltX    The value of the ABS_TILT_X axis, or 0 if not available. 

             raw.tiltY    The value of the ABS_TILT_Y axis, or 0 if not available.



        7.2.2  未处理坐标轴范围: (调用EVIOCGABS ioctl获得每个坐标轴的值)
      

raw.*.min    The inclusive minimum value of the raw axis. 

             raw.*.max    The inclusive maximum value of the raw axis. 

             raw.*.range    Equivalent to raw.*.max - raw.*.min. 

             raw.*.fuzz    The accuracy of the raw axis. eg. fuzz = 1 implies values are accurate to +/- 1 unit. 

             raw.width    The inclusive width of the touch area, equivalent to raw.x.range + 1. 

             raw.height    The inclusive height of the touch area, equivalent to raw.y.range + 1.


 
        7.2.3   输出范围:
            output.width:
                输出宽度,对于触摸屏,它是以像素为单位的显示宽度,对于触摸板,等同于raw.width。indicating that no interpolation will be performed.
            output.height
                输出高度,它是以像素为单位的显示高度,对于触摸板,等同于raw.height, indicating that no interpolation will be performed.
            output.diag
                The diagonal length of the output coordinate system, equivalent to sqrt(output.width ^2 + output.height ^2).

    7.3  基本配置项:
         7.3.1  device.internal:  每个输入设备的通用配置:
                 Definition: device.internal = 0 | 1
                 指明为内设组件,还是外接设备。
                 0: the device is external.
                 1: the device is internal.
                 如果这个值为设定,USB或蓝牙设备默认为0,其他为1;
    
        7.3.2  touch.deviceType:  触摸设备类型
                 定义: touch.deviceType = touchScreen | touchPad | pointer | default
           7.3.3  touch.orientationAware:  触摸设备是否对显示定位改变作出反应。
                  Definition: touch.orientationAware = 0 | 1
                   1:  当显示定位变化是,触摸设备报告的触摸坐标被传递。
                   2.   触摸设备报告的触摸坐标不受显示定位改变影响。
                  触摸屏缺省为1,其他为0
        7.3.4  touch.gestureMode: 该项只对pointer设备有用
                Definition: touch.gestureMode = pointer | spots | default
                (具体请见原文)
        7.3.5  屏幕校准项
            7.3.5.1  x,y 域: 接触区域的中心坐标信息
                    计算方式:从设备内描述坐标值直接转换为输出坐标系统
                

xScale = output.width / raw.width 

                         yScale = output.height / raw.height 


                     If not orientation aware or screen rotation is 0 degrees: 

                       output.x = (raw.x - raw.x.min) * xScale 

                       output.y = (raw.y - raw.y.min) * yScale 

                     Else If rotation is 90 degrees: 

                        output.x = (raw.y - raw.y.min) * yScale 

                        output.y = (raw.x.max - raw.x) * xScale 

                     Else If rotation is 180 degrees: 

                        output.x = (raw.x.max - raw.x) * xScale 

                        output.y = (raw.y.max - raw.y) * yScale 

                     Else If rotation is 270 degrees: 

                        output.x = (raw.y.max - raw.y) * yScale 

                        output.y = (raw.x - raw.x.min) * xScale 

                     End If


        7.3.5.2      TouchMajor, TouchMinor, ToolMajor, ToolMinor, Size 域:
                  TouchMajor,TouchMinor 描述接触区域的近似面积(单位: 像素)
                  ToolMajor,ToolMinor  描述工具的近似面积(单位:像素)
                  Size:  描述接触的标准大小与触摸设备能感知的最大区域的比值。最小为0.0,最大为1.0
                  当长度和宽度被确定后,TouchMajor指定最大面积,TouchMinor指定最小面积。如果为园,则相等。
                  相同道理,ToolMajor,ToolMinor。
                  如果接触大小无效,而工具大小有效,则工具大小等于接触大小。反之依然。

        7.3.5.3   touch.size.calibration: (后面计算公式一看就明白啥意思)
          Definition: touch.size.calibration = none | geometric | diameter | area | default
          触摸设备用于报告触摸大小和工具大小的度量方式:
          none:  大小为0
          geometric:  假定和位置用相同的平面单元,用相同的方式度量。
          diameter:   假定大小按照比例从接触区域或工具的宽度获的。
          area:       假定大小按照比例从接触区域或工具的面积获的。
          default:    如果raw.touchMajor或raw.toolMajor坐标轴有效,系统用geometric校准。其他用none。

        7.3.5.4 touch.size.scale  一个非负浮点数,(后面计算公式一看就明白啥意思)
             一个特定的校准用比例常量因子。  The default value is 1.0.
        7.3.5.5   touch.size.bias  一个非负浮点数,(后面计算公式一看就明白啥意思)
            一个特定的校准用偏差常量。 The default value is 0.0.
        7.3.5.6   touch.size.isSummed  = 0 | 1 (后面计算公式一看就明白啥意思)
            所有激活接触的大小的和一起报告,或者每个接触单独报告。
            1: 报告大小将会被接触区域个数除。
            0: 不处理.
        7.3.5.7  计算:
     

If raw.touchMajor and raw.toolMajor are available: 

                 touchMajor = raw.touchMajor 

                 touchMinor = raw.touchMinor 

                 toolMajor = raw.toolMajor 

                 toolMinor = raw.toolMinor 

             Else If raw.touchMajor is available: 

                 toolMajor = touchMajor = raw.touchMajor 

                 toolMinor = touchMinor = raw.touchMinor 

             Else If raw.toolMajor is available: 

                 touchMajor = toolMajor = raw.toolMajor 

                 touchMinor = toolMinor = raw.toolMinor 

             Else 

                 touchMajor = toolMajor = 0 

                 touchMinor = toolMinor = 0 

                 size = 0 

             End If 


             size = avg(touchMajor, touchMinor) 


             If touch.size.isSummed == 1: 

                 touchMajor = touchMajor / numberOfActiveContacts 

                 touchMinor = touchMinor / numberOfActiveContacts 

                 toolMajor = toolMajor / numberOfActiveContacts 

                 toolMinor = toolMinor / numberOfActiveContacts 

                 size = size / numberOfActiveContacts 

              End If 


             If touch.size.calibration == "none": 

                 touchMajor = toolMajor = 0 

                 touchMinor = toolMinor = 0 

                 size = 0 

             Else If touch.size.calibration == "geometric": 

                 outputScale = average(output.width / raw.width, output.height /     raw.height) 

             touchMajor = touchMajor * outputScale 

                 touchMinor = touchMinor * outputScale 

                 toolMajor = toolMajor * outputScale 

                 toolMinor = toolMinor * outputScale 

             Else If touch.size.calibration == "area": 

                 touchMajor = sqrt(touchMajor) 

                 touchMinor = touchMajor 

                 toolMajor = sqrt(toolMajor) 

                 toolMinor = toolMajor 

             Else If touch.size.calibration == "diameter": 

                 touchMinor = touchMajor 

                 toolMinor = toolMajor 

             End If 


             If touchMajor != 0: 

                output.touchMajor = touchMajor * touch.size.scale + touch.size.bias 

             Else 

                  output.touchMajor = 0 

             End If 


             If touchMinor != 0: 

                  output.touchMinor = touchMinor * touch.size.scale + touch.size.bias 

             Else 

                  output.touchMinor = 0 

             End If 


             If toolMajor != 0: 

                  output.toolMajor = toolMajor * touch.size.scale + touch.size.bias 

             Else 

                  output.toolMajor = 0 

             End If 


             If toolMinor != 0: 

                  output.toolMinor = toolMinor * touch.size.scale + touch.size.bias 

             Else 

                  output.toolMinor = 0 

             End If 


             output.size = size


    7.3.6 Pressure 域
        描述触摸设备提供的近似物理压力,0.0~1.0
        7.3.6.1 touch.pressure.calibration
            Definition: touch.pressure.calibration = none | physical | amplitude | default
            用于触摸设备的压力的测量类型:
            none: 压力值不测量,触摸时1.0,反之0.0
            physical:  假定压力坐标轴符合触摸板提供的实际压力强度。
            amplitude: 假定压力坐标轴符合信号幅度,信号幅度与接触大小和压力有关。
            default:如果压力坐标无效,用物理校准,其他情况none。

        7.3.6.2 touch.pressure.scale  一个非负浮点数(后面计算公式一看就明白啥意思)
            特定的校准用常理比例因子。The default value is 1.0 / raw.pressure.max.
        7.3.6.3  计算:
            

If touch.pressure.calibration == "physical" or "amplitude": 

                     output.pressure = raw.pressure * touch.pressure.scale 

                 Else 

                     If hovering: 

                         output.pressure = 0 

                     Else 

                         output.pressure = 1 

                     End If 

                 End If



    7.3.7 Orientation Tilt 域: (因为没用到,没翻译,请看原文)
        Orientation 域描述了触摸位置和工具的角度测试的定位,0: 主坐标轴时垂直的,-PI/2: 主坐标轴向左,PI/2: 主坐标轴向右,如果一个指示型工具,定位范围在一个全圆范围内。 -PI/PI
        Tilt 描述工具的倾斜角度。

         7.3.7.1  ouch.orientation.calibration
     Definition: = none | interpolated | vector | default
     none: set to 0.
     interpolated:  the orientation is linearly interpolated such that a raw value of raw.orientation.min maps to -PI/2 and a raw value of raw.orientation.max maps to PI/2. The center value of (raw.orientation.min + raw.orientation.max) / 2 maps to 0.

     vector:  the orientation is interpreted as a packed vector consisiting of two signed 4-bit fields. This representation is used on Atmel Object Based Protocol parts. When decoded, the vector yields an orientation angle and confidence magnitude. The confidence magnitude is used to scale the size information, unless it is geometric.

    If the value is default, the system uses the interpolated calibration if the orientation axis available, otherwise uses none.

        7.3.7.2 计算:
     

If touch.tiltX and touch.tiltY are available: 

             tiltXCenter = average(raw.tiltX.min, raw.tiltX.max) 

             tiltYCenter = average(raw.tiltY.min, raw.tiltY.max) 

             tiltXAngle = (raw.tiltX - tiltXCenter) * PI / 180 

             tiltYAngle = (raw.tiltY - tiltYCenter) * PI / 180 

             output.orientation = atan2(-sin(tiltXAngle), sinf(tiltYAngle)) 

             output.tilt = acos(cos(tiltXAngle) * cos(tiltYAngle)) 

         Else If touch.orientation.calibration == "interpolated": 

             center = average(raw.orientation.min, raw.orientation.max) 

             output.orientation = PI / (raw.orientation.max - raw.orientation.min) 

             output.tilt = 0 

         Else If touch.orientation.calibration == "vector": 

             c1 = (raw.orientation & 0xF0) >> 4 

             c2 = raw.orientation & 0x0F 


             If c1 != 0 or c2 != 0: 

                 If c1 >= 8 Then c1 = c1 - 16 

                 If c2 >= 8 Then c2 = c2 - 16 

                 angle = atan2(c1, c2) / 2 

                 confidence = sqrt(c1*c1 + c2*c2) 


                 output.orientation = angle 


                 If touch.size.calibration == "diameter" or "area": 

                     scale = 1.0 + confidence / 16 

                     output.touchMajor *= scale 

                     output.touchMinor /= scale 

                     output.toolMajor *= scale 

                     output.toolMinor /= scale 

                 End If 

             Else 

                 output.orientation = 0 

             End If 

             output.tilt = 0 

         Else 

             output.orientation = 0 

             output.tilt = 0 

         End If 


         If orientation aware: 

             If screen rotation is 90 degrees: 

                 output.orientation = output.orientation - PI / 2 

             Else If screen rotation is 270 degrees: 

                 output.orientation = output.orientation + PI / 2 

             End If 

         End If



    7.3.8 Distance 域:
        Distance 域描述工具和触摸设备面板的距离。如果接触为0.

        7.3.8.1  touch.distance.calibration
            Definition: touch.distance.calibration = none | scaled | default
            none: set to 0.
            scaled: 报告的距离乘以因子。
            default: 如果距离坐标无效,系统用因子校准。其他情况为none.
            
        7.3.8.2  touch.distance.scale   = <a non-negative floating point number>
            一个特定的校准用常量比例因子。The default value is 1.0.
        7.3.8.3 计算:
        If touch.distance.calibration == "scaled":
            output.distance = raw.distance * touch.distance.scale
        Else
            output.distance = 0
        End If
    7.4  例子:

# Input device configuration file for a touch screen that supports pressure, 

         # size and orientation.  The pressure and size scale factors were obtained 

         # by measuring the characteristics of the device itself and deriving 

         # useful approximations based on the resolution of the touch sensor and the 

         # display. 

         # 

         # Note that these parameters are specific to a particular device model. 

         # Different parameters will need to be used for other devices. 


         # Basic Parameters 

         touch.deviceType = touchScreen 

         touch.orientationAware = 1 


         # Size 

         # Based on empirical measurements, we estimate the size of the contact 

         # using size = sqrt(area) * 28 + 0. 

         touch.size.calibration = area 

         touch.size.scale = 28 

         touch.size.bias = 0 

         touch.size.isSummed = 0 


         # Pressure 

         # Driver reports signal strength as pressure. 

         # 

         # A normal index finger touch typically registers about 80 signal strength 

         # units although we don't expect these values to be accurate. 

         touch.pressure.calibration = amplitude 

         touch.pressure.scale = 0.0125 


         # Orientation 

         touch.orientation.calibration = vector



8.  虚拟键映射文件:
    触摸设备经常用作实现虚拟按键。
    依靠触摸控制器的兼容性,有很多中方式可以实现。有些触摸控制器能直接配置用设置寄存器方式实现软按键。其他情况用软件从触摸坐标映射按键码实现。
    当虚拟按键用软件实现,内核必须导出一个虚拟按键映射文件: virtualkeys.<devicename> 作为主板的特性。例如: 如果一个触摸屏设备驱动报告它的名字:touchfeely:,虚拟按键映射文件必须放在:/sys/board_properties/virtualkeys.touchfeely.
    一个虚拟按键文件描述了Linux虚拟按键的键值在触摸版上的坐标。
    另外,对于虚拟按键映射文件,它必须符合键布局文件和按键符号映射文件,从Linux按键码映射到Android按键码,并指定键盘设备类型。
    8.1 语法:
        用新行或:分割, “#”开头表示注释,6个用:分割的部分,格式如下
      

0x01: A version code. Must always be 0x01. 

             <Linux key code>: The Linux key code of the virtual key. 

             <centerX>: The X pixel coordinate of the center of the virtual key. 

             <centerY>: The Y pixel coordinate of the center of the virtual key. 

             <width>: The width of the virtual key in pixels. 

             <height>: The height of the virtual key in pixels.


    8.2  例如:(480 * 800)
     

Virtual key map file: /sys/board_properties/virtualkeys.touchyfeely. 

         # One key per line 

         0x01:158:55:835:90:55 

         0x01:139:172:835:125:55 

         0x01:102:298:835:115:55 

         0x01:217:412:835:95:55 


         Key layout file: /system/usr/keylayout/touchyfeely.kl. 

         key 158 BACK 

         key 139 MENU 

         key 102 HOME 

         key 217 SEARCH 


         Key character map file: /system/usr/keychars/touchyfeely.kcm. 


         type SPECIAL_FUNCTION



9. 总结
    综上所述,Android系统中不再需要包含定制的触摸设备驱动,而是将在Linux内核中实现符合Linux输入设备规范的驱动。Adnroid系统通过输入设备配置文件中的参数设置从Linux内核层获取的输入设备信息转化为android系统能识别的标准信息。触摸设备的校准参数是存放在输入设备配置文件中。 配置文件依次获取路径:

    /system/usr/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc
    /system/usr/idc/Vendor_XXXX_Product_XXXX.idc
    /system/usr/idc/DEVICE_NAME.idc
    /data/system/devices/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc
    /data/system/devices/idc/Vendor_XXXX_Product_XXXX.idc
    /data/system/devices/idc/DEVICE_NAME.idc

    InputReader,Eventhub为cpp文件,位于android源码的
frameworks/base/services/input 目录下。文件很大,有兴趣的朋友,可以自行阅读。