input.c中的resume会补发一个释放事件

问题描述和分析:

在手机休眠状态下通过按键唤醒手机的过程中getevent获取到的event事件信息和正常状态下信息不一致,导致某应用程序出现异常。

正常状态下按下power key的log信息和其对应的event事件:

[   45.663482] c0 [SPRD_EIC_KEYS_INFO] Pressed!  Key:Power Key ScanCode:116 value:1

0001 0074 00000001

0000 0000 00000000

正常状态下释放power key的log信息和其对应的event事件:

[   45.732818] c0 [SPRD_EIC_KEYS_INFO] Released! Key:Power Key ScanCode:116 value:0

0001 0074 00000000

0000 0000 00000000   正常释放事件对应的sync信息为全0

休眠状态下通过power key唤醒手机时的流程为:

按下power key之后便触发一个EIC中断,导致手机开始唤醒动作,kernel开始resume流程。该过程并不会检查按键是否抬起。

通常情况下,用户的操作是按下并很快释放,因此从kernel log中我们看到的现象和上述的正常流程是一样的。也就是有一个按下和一个释放的log出现。

但是如果如果我们持续用getevent去捕获事件信息的话,这个过程中我们却可以看到3组事件信息:一个按下,两个释放。

为了确认这个现象,我们又做了一个实验:只按下且不释放。

果然在这个实验中我们看到了kernel中的按下的log,但是getevent却得到了两组事件,一个按下,一个释放。

而且,释放对应的event事件和正常释放对应的事件有差异!

[   45.663482] c0 [SPRD_EIC_KEYS_INFO] Pressed!  Key:Power Key ScanCode:116 value:1

0001 0074 00000001

0000 0000 00000000

系统补发了一个释放事件:

0001 0074 00000000

0000 0000 00000001   注意这个补发事件的sync信息和正常的事件信息有小差异!

因此可以得到结论:在唤醒时,系统在某处补发了一个释放的事件。

因为getevent是运行在应用层的,它得到的事件都是来自kernel的,所以推测问题处在kernel。

而kernel中能发出一个事件的过程由驱动调用input子系统的相关函数来完成。

我们可以确认驱动没有做这个额外的动作,那么就剩下input子系统可以被怀疑了。

而问题仅仅在系统从休眠中被唤醒时,所以我们怀疑了一下input.c的resume流程,找到了疑点,这个过程中调用了一个reset函数,代码如下:

/**
 * input_reset_device() - reset/restore the state of input device
 * @dev: input device whose state needs to be reset
 *
 * This function tries to reset the state of an opened input device and
 * bring internal state and state if the hardware in sync with each other.
 * We mark all keys as released, restore LED state, repeat rate, etc.
 */
void input_reset_device(struct input_dev *dev)
{
	mutex_lock(&dev->mutex);

	if (dev->users) {
		input_dev_toggle(dev, true);

		/*
		 * Keys that have been pressed at suspend time are unlikely
		 * to be still pressed when we resume.
		 */
		spin_lock_irq(&dev->event_lock);
		input_dev_release_keys(dev);
		spin_unlock_irq(&dev->event_lock);
	}

	mutex_unlock(&dev->mutex);
}
EXPORT_SYMBOL(input_reset_device);

#ifdef CONFIG_PM
static int input_dev_suspend(struct device *dev)
{
	struct input_dev *input_dev = to_input_dev(dev);

	mutex_lock(&input_dev->mutex);

	if (input_dev->users)
		input_dev_toggle(input_dev, false);

	mutex_unlock(&input_dev->mutex);

	return 0;
}

static int input_dev_resume(struct device *dev)
{
	struct input_dev *input_dev = to_input_dev(dev);

	input_reset_device(input_dev);

	return 0;
}

而reset中又调用了 input_dev_release_keys(dev); 问题就在这里。通过注释掉该release动作,我们发现上述补发动作就没有了。

可见,input子系统在resume时会检查每一个输入设备,如果该设备的按键处于按下状态,它就会强制补发一个释放事件。

时间: 2024-07-29 00:02:04

input.c中的resume会补发一个释放事件的相关文章

ajax form表单提交 input file中的文件

ajax form表单提交 input file中的文件 现今的主流浏览器由于ajax提交form表单无法把文件类型数据提交到后台,供后台处理,可是开发中由于某些原因又不得不用ajax提交文件, 为了解决这个问题我走了不少弯路: 1.用原生的 input file , 不支持ajax上传文件,你肯定会说可以用 ajax form表单上传了呀?不过我后面还要调用上传成功后用js处理一些对话框,所以这种方法排除 2.用了 uploadify 上传插件,弄出来能上传东西,结果不理想:因为不能判断上传的

input框中自动展示当前日期 yyyy/mm/dd

直接上代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>input框中自动展示当前日期</title> </head> <body> <input type="text" id="input"> <script>

C程序中,如何设计和编写一个应用系统?

1.文件操作的基本方法:C语言将计算机的输入输出设备都看作是文件.例如,键盘文件.屏幕文件等. 2.从结构化程序和函数角度分析,按照功能,将不同的代码放到一起,用大括号括起来,然后给这段代码起个名字表示,然后还要设置上参数,一遍使用这个函数的时候向里传递实际的值,类似一个加法的函数,完成两个数的相加. 3.结构体的作用和应用, do {  system("cls"); printf("\n\n\n              ********学生信息管理系统********\n

在表单(input)中id和name的区别

在表单(input)中id和name的区别  但是name在以下用途是不能替代的: 1. 表单(form)的控件名,提交的数据都用控件的name而不是id来控制.因为有许多name会同时对应多个控件,比如checkbox和radio,而id必须是全文档中唯一的.此外浏览器会根据name来设定发送到服务器的request.因此如果用id,服务器是无法得到数据的. 2. frame和window的名字,用于在其他frame或window指定target. 例如:<frameset cols="

关于在input标签中输入数字的问题(正则表达式)

在项目开发中遇到文本框限制输入内容的问题,自己在网上找了找,又加了点自己的,简略写出了几个,在这写一下,希望对其他人有所帮助. 可在input标签中根据情况加入属性: 情况1:需要只能输入数字: onkeyup='this.value=this.value.replace(/\D/gi,"")' 情况2:需要只能输入小数(牵扯到金额等): onkeyup="this.value=(this.value.match(/\d+(\.\d{0,2})?/)||[''])[0]&qu

input框中的name和id的区别

1. 可以说几乎每个做过Web开发的人都问过,到底元素的ID和Name有什么区别阿?为什么有了ID还要有Name呢?! 而同样我们也可以得到最classical的答案:ID就像是一个人的身份证号码,而Name就像是他的名字,ID显然是唯一的,而Name是可以重复的. 上周我也遇到了ID和Name的问题,在页面里输入了一个input type="hidden",只写了一个ID='SliceInfo',赋值后submit,在后台用Request.Params["SliceInfo

实现bootstrap布局的input输入框中的图标点击功能

使用bootstrap布局可以在input的输入框中添加譬如登录名输入框中的一键清除图标和密码输入框中显示密码的小眼睛图标.如下图: 但是在将图标放入input输入框中,这些小图标是无法获得点击事件的: 那么问题来了,怎样让这些小图标能够获得点击事件呢? 我也不知道,但是可以用一种迂回的方式,来间接的实现该功能. 重点来了: 在小图标的位置上,添加一个看不见的元素,元素的大小正好将小图标覆盖,但是没有背景颜色和边框:相当于给小图标盖了一个透明的被子: <div class="input-g

Uploadify在MVC中使用方法案例(一个视图多次上传单张图片)

Controller 中代码和 上一节文章(http://www.cnblogs.com/yechangzhong-826217795/p/3785842.html )一样 视图中代码如下: <script type="text/javascript"> $(function () { $(".uploadpic").each(function (i) { $('#uploadify' + i).uploadify({ 'buttonText': '上传

如何从40亿整数中找到不存在的一个

前言 给定一个最多包含40亿个随机排列的32位的顺序整数的顺序文件,找出一个不在文件中的32位整数.(在文件中至少确实一个这样的数-为什么?).在具有足够内存的情况下,如何解决该问题?如果有几个外部的"临时"文件可用,但是仅有几百字节的内存,又该如何解决该问题? 分析 这仍然是<编程珠玑>中的一个问题.前面我们曾经提到过<位图法>,我们使用位图法解决了这个问题.32位整型最多有4294967296个整数,而很显然40亿个数中必然会至少缺一个.我们同样也可以尝试使