Android底层开发之Linux输入子系统要不要判断系统休眠状态上报键值

Android底层开发之Linux输入子系统要不要判断系统休眠状态上报键值

题外话:一个问题研究到最后,那边记录文档的前半部分基本上都是无用的,甚至是错误的。重点在最后,前边仅仅是一些假想推测。

http://blog.csdn.net/kangear/article/details/40072707

在调试一下红外遥控器input驱动时,直接采用的是一个半成品的驱动在上边实现的自己的设备的匹配,但同时遇到了一些关于input输入子系统的疑惑。

按键一般有「按下和抬起」两个状态一般使用0和1来分别表示。一般如下方式上报按键键值就可以完成「按下和抬起」两个状态的收集。

input_event(ddata->input, EV_KEY, KEY_POWER, 1);

input_sync(ddata->input);

但是最近遇到一个奇怪的问题是内核中的KEY_WAKEUP唤醒键值使用上述方法上报时,用户空间只能检测到状态0,第二次按键时才会有状态1。这样导致Android系统不能正常唤醒,需要按两次才能唤醒系统。

目前的解决方法是将之前上报KEY_WAKEUP的地上改为KEY_POWER键值。但是好奇心引着我弄清楚它们是怎么回事。

经验出这里边上报如下一样连续上报1/0状态才可以在用户空间正常的检测到1/0状态。

input_event(ddata->input, EV_KEY, KEY_WAKEUP, 1);

input_sync(ddata->input);

input_event(ddata->input, EV_KEY, KEY_WAKEUP, 0);

input_sync(ddata->input);

直觉告诉我可以是由于我对这个两个api的不了解造成的,比较是凡事必有因的。

除了KEY_WAKEUP换个其它键值试试。结果和KEY_WAKEUPG一样不能同步,可以推断出是非POWER按键就不行。这可以能所在代码位置有关系:

}else if ((get_suspend_state())&&(ddata->keycode==KEY_POWER)){

input_event(ddata->input, EV_KEY, KEY_POWER, 1);

input_sync(ddata->input);

}

再进一步测试在非PM_SUSPEND_ON电源模式下,所有的按键都是如何的。测试结果是所有的非POWER按键都出现了按键不能同步的问题。但是不能以点概面,使用GPIO连接的物理按键并不会有此问题,那么就排除了input子系统中做了手脚。问题出就出在了Remote control驱动中对的处理。

找出了问题所在了,确实是出在了Remote control驱动中,上报键值对PM状态进行了判断,如果

static void remotectl_timer(unsigned long _data)

if(ddata->press != ddata->pre_press) {

ddata->pre_press = ddata->press = 0;

if (get_suspend_state()==0){

//input_event(ddata->input, EV_KEY, ddata->keycode, 1);

//input_sync(ddata->input);

input_event(ddata->input, EV_KEY, ddata->keycode, 0);

input_sync(ddata->input);

}else if ((get_suspend_state())&&(ddata->keycode==KEY_POWER)){

//input_event(ddata->input, EV_KEY, KEY_WAKEUP, 1);

//input_sync(ddata->input);

input_event(ddata->input, EV_KEY, KEY_WAKEUP, 0);

input_sync(ddata->input);

}

}

将过滤条件去除后,可以和GPIO连接的物理按键一样的效果了,即无论系统处理什么样的状态,休眠或者唤醒状态都上传了键值。同时这也给我带来了一个疑惑,按键驱动中要不要进行suspend状态判断,根据Android中的经验所有的状态都要上传的,响应不响应是看上层系统的决定;但是如果对于普通的嵌入式Linux系统就不一定了,如果input子系统在系统休眠的时候上传了键值,那么对应的应用层可以就会直接去响应键值。要使用哪种方法实现,这是一个悖论!结合Android的宏这样实现了:

diff --git a/drivers/input/remotectl/rkxx_remotectl.c b/drivers/input/remotectl/rkxx_remotectl.c

index db91516..201c5dd 100644

--- a/drivers/input/remotectl/rkxx_remotectl.c

+++ b/drivers/input/remotectl/rkxx_remotectl.c

@@ -306,6 +306,10 @@ static void remotectl_do_something(unsigned long  data)

if ((ddata->scanData&0x0ff) == ((~ddata->scanData >> 8)&0x0ff)){

if (remotectl_keycode_lookup(ddata)){

ddata->press = 1;

+#ifdef CONFIG_ANDROID // Android OS needs input event whatever suspend state

+                        input_event(ddata->input, EV_KEY, ddata->keycode, 1);

+                        input_sync(ddata->input);

+#else

if (ddata->keycode==KEY_POWER || get_suspend_state()==PM_SUSPEND_ON){

input_event(ddata->input, EV_KEY, ddata->keycode, 1);

input_sync(ddata->input);

@@ -314,6 +318,7 @@ static void remotectl_do_something(unsigned long  data)

}

//input_event(ddata->input, EV_KEY, ddata->keycode, ddata->press);

//input_sync(ddata->input);

+#endif // CONFIG_ANDROID

ddata->state = RMC_SEQUENCE;

}else{

ddata->state = RMC_PRELOAD;

@@ -437,6 +442,10 @@ static void remotectl_timer(unsigned long _data)

if(ddata->press != ddata->pre_press) {

ddata->pre_press = ddata->press = 0;

+#ifdef CONFIG_ANDROID // Android OS needs input event whatever suspend state

+        input_event(ddata->input, EV_KEY, ddata->keycode, 0);

+        input_sync(ddata->input);

+#else

if (get_suspend_state()==0){

//input_event(ddata->input, EV_KEY, ddata->keycode, 1);

//input_sync(ddata->input);

@@ -448,6 +457,7 @@ static void remotectl_timer(unsigned long _data)

input_event(ddata->input, EV_KEY, KEY_WAKEUP, 0);

input_sync(ddata->input);

}

+#endif // CONFIG_ANDROID

}

#ifdef CONFIG_PM

remotectl_wakeup(_data);

如果是Android系统,那么无论kernel处理什么样的休眠状态都实时地上报键值。这样保证在休眠播放音乐的时候可以控制音频大小。这也正是目前Android手机的实现方式

http://blog.csdn.net/kangear/article/details/40072707

还有一点:按键中的状0,并不是input_sync(ddata->input);发出的,它只会发出当前的值。它仅仅是一个「同步」,意思是数据都准备好了,可以发送了。还是没有对驱动了解的很清楚加上自己的一些瞎想像误导了自己。内核input驱动中是不区分POWER键,WAKEUP键;真是有差异了,问题一定是出在了自己的驱动代码中。

时间: 2024-10-24 20:19:40

Android底层开发之Linux输入子系统要不要判断系统休眠状态上报键值的相关文章

Android底层开发之Linux输入子系统要不要推断系统休眠状态上报键值

Android底层开发之Linux输入子系统要不要推断系统休眠状态上报键值 题外话:一个问题研究到最后,那边记录文档的前半部分基本上都是没用的,甚至是错误的. 重点在最后,前边不过一些假想猜測. http://blog.csdn.net/kangear/article/details/40072707 在调试一下红外遥控器input驱动时,直接採用的是一个半成品的驱动在上边实现的自己的设备的匹配,但同一时候遇到了一些关于input输入子系统的疑惑. 按键一般有「按下和抬起」两个状态一般使用0和1

Android底层开发之Audio HAL

http://blog.csdn.net/kangear/article/details/44939429 Android底层开发之Audio HAL 在Android音频底层调试-基于tinyalsa中以「抛开Android的天生复杂,回归嵌入式Linux的本质」的方式介绍如何调试Linux内核中的音频驱动. 这里向上再伸展一下进入HAL层,看是如何将tinyalsa封装给Frameworks使用的. 基于4.2.2版本源码进行讨论.Android官方教程是Audio Implementing

Android安全开发之Provider组件安全

Android安全开发之Provider组件安全 作者:伊樵.呆狐@阿里聚安全 1 Content Provider组件简介 Content Provider组件是Android应用的重要组件之一,管理对数据的访问,主要用于不同的应用程序之间实现数据共享的功能.Content Provider的数据源不止包括SQLite数据库,还可以是文件数据.通过将数据储存层和应用层分离,Content Provider为各种数据源提供了一个通用的接口. 创建一个自己的Content Provider需要继承

Android 安全开发之 ZIP 文件目录遍历

1.ZIP文件目录遍历简介 因为ZIP压缩包文件中允许存在"../"的字符串,攻击者可以利用多个"../"在解压时改变ZIP包中某个文件的存放位置,覆盖掉应用原有的文件.如果被覆盖掉的文件是动态链接so.dex或者odex文件,轻则产生本地拒绝服务漏洞,影响应用的可用性,重则可能造成任意代码执行漏洞,危害用户的设备安全和信息安全.比如近段时间发现的"寄生兽"漏洞.海豚浏览器远程命令执行漏洞.三星默认输入法远程代码执行漏洞等都与ZIP文件目录遍历有

Android驱动开发之Hello实例

Android驱动开发之Hello实例: 驱动部分 modified:   kernel/arch/arm/configs/msm8909-1gb_w100_hd720p-perf_defconfig modified:   kernel/arch/arm/configs/msm8909-1gb_w100_hd720p_defconfig modified:   kernel/drivers/input/misc/Kconfig modified:   kernel/drivers/input/

Linux输入子系统(转)

Linux输入子系统(Input Subsystem) 1.1.input子系统概述 输入设备(如按键,键盘,触摸屏,鼠标等)是典型的字符设备,其一般的工作机制是低层在按键,触摸等动作发生时产生一个中断(或驱动通过timer定时查询),然后cpu通过SPI,I2C或者外部存储器总线读取键值,坐标等数据,放一个缓冲区,字符设备驱动管理该缓冲区,而驱动的read()接口让用户可以读取键值,坐标等数据. 在Linux中,输入子系统是由输入子系统设备驱动层.输入子系统核心层(Input Core)和输入

linux输入子系统(input subsystem)之evdev.c事件处理过程

1.代码 input_subsys.drv.c 在linux输入子系统(input subsystem)之按键输入和LED控制的基础上有小改动,input_subsys_test.c不变. input_subsys.drv.c 1 #include <linux/module.h> 2 #include <linux/version.h> 3 4 #include <linux/init.h> 5 #include <linux/fs.h> 6 #inclu

Android网络开发之用tcpdump抓包

Android开发过程中,当涉及到网络通信的时候,有一些字段需要抓包获取.我之前因为SSDP设备发现的包头格式没有写对,经过抓包分析和标准包头对比发现了这个困扰我很久的问题.总之,掌握在Android手机里面抓包是很有必要的. 准备工作:Android系统的手机,网络环境,tcpdump,破解手机root权限,建议最好在手机里面安装RE文件管理器并且给root权限.具体步骤如下: 首先,通过adb工具将tcpdump推送到手机,tcpdump的下载地址为:http://www.strazzere

Android安全开发之ZIP文件目录遍历

1.ZIP文件目录遍历简介 因为ZIP压缩包文件中允许存在"../"的字符串,攻击者可以利用多个"../"在解压时改变ZIP包中某个文件的存放位置,覆盖掉应用原有的文件.如果被覆盖掉的文件是动态链接so.dex或者odex文件,轻则产生本地拒绝服务漏洞,影响应用的可用性,重则可能造成任意代码执行漏洞,危害用户的设备安全和信息安全.比如近段时间发现的"寄生兽"漏洞.海豚浏览器远程命令执行漏洞.三星默认输入法远程代码执行漏洞等都与ZIP文件目录遍历有