多点触摸TP的touch异常事件

异常现象

android开启触摸白点模式后, 屏幕上出现白点不消失,存在一个长按down事件

分析

经过研究,发现多点触摸协议存在type A和type B。出现此异常的TP使用的是Type B的多点触摸协议,支持轨迹跟踪。

通过sendevent发送input event事件,发现该异常与ABS_MT_SLOT,ABS_MT_TRACKING_ID事件关系密切。先简单介绍下这2个事件。

多点触摸协议的事件

ABS_MT_SLOT这个事件的SLOT值由TP IC传递给主机.

ABS_MT_TRACKING_ID这个事件的值由Input Driver生成(也可以由TP Driver中hardCode)。在input driver中它的值分为2种情况正值(代表与之关联的SLOT的down事件),负值(-1代表与之关联的SLOT的UP事件);不同的SLOT匹配不同的ABS_MT_TRACKING_ID值,ABS_MT_TRACKING_ID值是一个递增的值。

本文之前提到的问题与ABS_MT_TRACKING_ID事件密切相关

异常的可能性

  1. TP Driver没有发送对应的ABS_MT_SLOT和ABS_MT_TRACKING_ID(-1)的事件

  1. TP Driver仅仅发送了ABS_MT_SLOT,没有发送ABS_MT_TRACKING_ID的正值;

第一类问题很好处理,仅仅需要在合适的时候增加一个UP的事件组合即可,第二类问题相对复杂。

第二类问题,可能是驱动本身遗漏了ABS_MT_TRACKING_ID的正值,相对容易排查;也可能是因为input event的异步发送导致的问题,这个问题相对复杂。经过调试input driver,我获取了一些信息。


对于常用的ABS_MT_SLOT常用通道(1~5)发生异常,很容易通过人为的多点触摸恢复,因为在新的多点触摸中驱动必然由down和up事件生成,那么此时异常旧恢复了,但是对于ABS_MT_SLOT通道值较大(10~15)的异常,旧很难通过人为的手动操作恢复了,没那么多手指去触摸呀。

我调试的是cyttsp的一款触摸板,通过手动触摸和sendevent命令同时操作很容易就触发这个bug。

经过调试我发现,cyttsp的驱动的sync_report插入了sendevent发送的事件中间,导致sendevent发送的事件添加了一个ABS_MT_SLOT为15的触摸事件集合,并且这个事件集合中没有ABS_MT_TRACKING_ID事件。最终这个点发送除去,并且被framework作为一个down事件处理。然而在最后释放的时候这个ABS_MT_SLOT为15对应的点确没有UP事件。

这个测试说明:缺少ABS_MT_TRACKING_ID的触摸down事件可以被framework处理,但是kernel没办法触发对应的

dev=8
function touch_point()
{
adb shell sendevent /dev/input/event${dev} 3 ABS_MT_SLOT $1
adb shell sendevent /dev/input/event${dev} 3 ABS_MT_TRACKING_ID $2            
adb shell sendevent /dev/input/event${dev} 3 53 $3
adb shell sendevent /dev/input/event${dev} 3 54 $4            
}

sendevent发送了ABS_MT_TRACKING_ID后,cyttsp发送了UP事件,完成了此次点击。后面2条命令继续发送,产生了以仅仅包含ABS_MT_SLOT的触摸事件。ABS_MT_SLOT的值为15是因为cyttsp驱动在每次事件处理后会遍历ABS_MT_SLOT并释放。


通过分析input模块代码,在tp driver或者user space空间向input driver发送input event时,

如果发送的事件ACTION_1包含(ABS_MT_SLOT,ABS_MT_POSITION_X,ABS_MT_POSITION_Y, ABS_MT_PRESSURE)且不含ABS_MT_TRACKING_ID时,

tp driver即使发送了ACTION_2(对应的ABS_MT_SLOT和ABS_MT_TRACKING_ID=-1),但是在input driver 模块处理event时,因为在input_handle_abs_event函数中逻辑如下:

static int input_handle_abs_event(struct input_dev *dev,
                  unsigned int code, int *pval)
{
    struct input_mt *mt = dev->mt;
    bool is_mt_event;
    int *pold;

    if (code == ABS_MT_SLOT) {
        //input_event函数发送ABS_MT_SLOT消息时,实际上并不将对应的事件添加到队列中
        //仅仅完成了赋值操作
        if (mt && *pval >= 0 && *pval < mt->num_slots)
            mt->slot = *pval;
        return INPUT_IGNORE_EVENT;
    }

    is_mt_event = input_is_mt_value(code);

    if (!is_mt_event) {
        pold = &dev->absinfo[code].value;
    } else if (mt) {
        //因为ACTION_1中没有ABS_MT_TRACKING_ID的值,因此这个值一直为-1
        //当发送ACTION_2事件时,这个pold的值为-1
        pold = &mt->slots[mt->slot].abs[code - ABS_MT_FIRST];
    } else {
        /*
         * Bypass filtering for multi-touch events when
         * not employing slots.
         */
        pold = NULL;
    }

    if (pold) {
        *pval = input_defuzz_abs_event(*pval, *pold,
                        dev->absinfo[code].fuzz);
        //pold和pval都为-1,因此不处理这个事件,丢失抬起事件
        if (*pold == *pval)
            return INPUT_IGNORE_EVENT;

        *pold = *pval;
    }

    /* Flush pending slot event */
    if (is_mt_event && mt && mt->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
        input_abs_set_val(dev, ABS_MT_SLOT, mt->slot);
        //input_event函数发送ABS_MT_SLOT消息时,实际上并不将对应的事件添加到队列中
        //在使用input_event发送其他消息时,根据需要在返回值中增加INPUT_SLOT,
        //然后在input_handle_event函数中把ABS_MT_SLOT数据添加发送队列中
        return INPUT_PASS_TO_HANDLERS | INPUT_SLOT;
    }

    return INPUT_PASS_TO_HANDLERS;
}

出现白点不消失后,需要再次给对应的ABS_MT_SLOT,发送一条包含ABS_MT_TRACKING_ID的值(需要为正值),然后再次发送释放point的input event(对应的ABS_MT_SLOT和ABS_MT_TRACKING_ID=-1)

### 主动式触摸TP与被动式触摸TP的技术差异及应用场景 主动式触摸屏(Active Touch Panel, TP)和被动式触摸屏(Passive Touch Panel, TP)在技术实现和应用场景上存在显著差异。以下是两者的详细对比: #### 1. 技术原理差异 - **主动式触摸屏**通过使用特定的传感器或发射器来检测触控操作,这些传感器可以识别由专用工具(如电容笔)发出的信号[^1]。这种技术通常依赖于高频信号的传输和接收,从而实现高精度的触控识别。 - **被动式触摸屏**则主要依靠人体导电性或物体对屏幕的压力来完成触控操作。例如,电容屏通过检测手指或其他导电物体引起的电场变化来定位触,而电阻屏则通过压力改变电路状态来实现触控功能[^1]。 #### 2. 精度与灵敏度 - **主动式触摸屏**由于采用专用工具,能够提供更高的精度和灵敏度,适合需要精细操作的应用场景,如绘图、签名验证等[^3]。 - **被动式触摸屏**虽然也能实现多点触控,但其精度相对较低,尤其是在复杂手势或小尺寸屏幕上,容易出现误触或延迟现象[^1]。 #### 3. 应用场景 - **主动式触摸屏**广泛应用于专业领域,如医疗设备、工业控制面板以及高端平板电脑和智能手机中的手写输入功能。例如,艺术家使用支持主动式触控的平板进行数字绘画时,可以获得更自然的手感和更高的准确性。 - **被动式触摸屏**则更多地服务于普通消费者市场,包括日常使用的智能手机、平板电脑、ATM机、POS机等。其优势在于无需额外工具即可操作,用户体验更加便捷[^2]。 #### 4. 成本与维护 - **主动式触摸屏**因涉及更复杂的硬件设计和技术要求,通常成本较高,且需要用户购买配套的触控笔等配件。 - **被动式触摸屏**的成本较低,易于生产和普及,同时无需额外购置工具,降低了用户的使用门槛。 #### 5. 技术发展趋势 随着传感器技术的进步,主动式触摸屏正在向更高分辨率、更低延迟的方向发展,以满足专业用户的需求。而被动式触摸屏则在提升多点触控能力和抗干扰性能方面持续改进,以适应多样化的生活场景[^4]。 ```python # 示例代码:模拟主动式与被动式触摸屏的触控检测 class TouchScreen: def __init__(self, type): self.type = type def detect_touch(self, input_tool): if self.type == "active": if input_tool == "stylus": return "High precision touch detected" else: return "No touch detected" elif self.type == "passive": if input_tool == "finger": return "Touch detected with lower precision" else: return "No touch detected" # 测试 active_screen = TouchScreen("active") passive_screen = TouchScreen("passive") print(active_screen.detect_touch("stylus")) # 输出:High precision touch detected print(passive_screen.detect_touch("finger")) # 输出:Touch detected with lower precision ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值