android4.3-android4.4.2触摸唤醒

来源:互联网 发布:php 截取字符串后几位 编辑:程序博客网 时间:2024/05/02 14:50

http://blog.csdn.net/hbk320/article/details/49688085

触摸屏唤醒是一个挺有趣的功能,在一些特殊的应用,特殊的场合上能使用到。如一些post机、收银台等。没人的时候,系统超时进入休眠或关屏;有人操作,点击一下触摸屏把屏幕亮起来。很人性化,功能也很炫。

好,开场白说完,进入主题。触摸唤醒分两种情况:

第一种、CPU进入深度休眠

第二种、假休眠

关于第一种情况,好像市面上某家厂商的手机(没有打广告的意思),点击两下屏幕就可以进入休眠;再点击两下就实现唤醒。借这个例子来分析,首先点击两下屏幕手机休眠,CPU肯定进入了深度休眠的状态,不然手机那弱小的电池损耗不起。CPU一旦进入了深度休眠,唤醒方法只有一种:那就是外部中断唤醒。正如我们平时使用手机的POWER按键,短按进入休眠,再按,手机唤醒。所以,根据这样分析,那么这种情况下,触摸屏就当作按键来使用了。在CPU休眠的状态下触摸屏的电没有关闭,当触摸屏收到点击两下屏幕的动作(有点手势控制的韵味),就给CPU一个模拟按键的唤醒中断,然后CPU就被唤醒了,系统就被唤醒了。

对于这种情况的实现,别人是申请了专利的,而且需要硬件上的设计配合。在这里,我们的触摸屏没有这样的功能。因此,我们只能实现第二种方式了。

关于第二种休眠方式,我们先来讲假休眠。Android系统休眠的方式在android4.2.2之后就缘用了linux的wakeup source机制,所以在android4.2.2之后,假休眠做起来更加简单。详细可以查看我另外一篇关于介绍休眠唤醒的博客《Android休眠唤醒和wakeup_source机制的使用(1)》。

在假休眠的状态下,触摸屏驱动是没有进入休眠状态的,这也是我们来实现触摸唤醒的关键所在。也就是说,触摸屏还能正常地上报数据。也就是说使用getevent能获取到驱动上报到系统的数据。

做好假休眠的功能后,比较细心的人可以发现:系统进入超时休眠后,接上鼠标移动一下,发现系统能够被唤醒了。同样的,系统能获取到鼠标的上报数据,也能获取到触摸屏的上报数据。但点击触摸屏不能唤醒系统。这是因为在系统获取好input 类数据后,会把数据进行“分流”,然后给到不同的进程进行处理。具体是在:

[html] view plain copy
  1. frameworks/base/services/input/EventHub.cpp   

里面。所以,这里有一种思路,就是根据模仿USB数据的处理流程,在处理触摸屏数据的进程里面把唤醒系统的功能加上。很简单,修改几行代码即可,这种方式不详细讲述。这里主要讲讲如何在TOUCH驱动里面完成这个功能。首先来分析一下触摸驱动的大概架构,如下:

触摸屏驱动的大概架构如上面图片,知道触摸屏的架构后,在触摸屏里面做上报事件就好做。Input的类缘用触摸屏驱动本身的类就好,在这里,一般触摸屏都会做有“BTN_TOUCH”的按键类事件,所以,在这里我们只需要添加自己的“KEY_POWER”类事件即可。然后是还有初始化一个工作队列,具体表现为:

[html] view plain copy
  1. +   INIT_WORK(&work , work_fun);  

接下来就是处理中断函数了,这样是触发touch事件的条件,所以在中断函数里面去执行调度,让CPU来选择合适的处理时机。这也是中断上半部跟下半部的作用所在。

[html] view plain copy
  1. +   schedule_work(&readBlQueue);  

然后在work_fun 里面模拟并上报“KEY_POWER”事件:

[html] view plain copy
  1. +       input_event(fts_wq_data->input_dev, EV_KEY, 116, 1);  
  2. +       input_sync(fts_wq_data->input_dev);  
  3. +       input_event(fts_wq_data->input_dev, EV_KEY, 116, 0);  
  4. +       input_sync(fts_wq_data->input_dev);  

这样之后,基本把整个input上报流程整理好。但这里还有一个问题:驱动怎样知道android已经进入假休眠状态了呢?

在这里,方法有好多:touch驱动导出一个借口,在休眠的时候通知驱动;通过检测硬件的状态;获取屏幕亮度参数;显然,“获取屏幕亮度”的方法是最为方便的。屏幕亮度值会在sys文件系统里面表现出来,具体是:

/sys/class/backlight/pwm-backlight.0/brightness

具体的平台可能路径有所区别,不过都是“/sys/class/”下的背光状态。然后就可以通过去读取brightness的值来判断系统是否进入假休眠,通常进入假休眠后,这个值为“0”,但也不排除有些情况下回对系统背光亮度进行限制。所以具体情况具体考虑。下面是读取节点的方法:

[html] view plain copy
  1. +   struct file *fp;  
  2. +   mm_segment_t fs;  
  3. +   loff_t pos = 0;  
  4. +   unsigned char readValue[2];  
  5. +     
  6. +   fp = filp_open("/sys/class/backlight/pwm-backlight.0/brightness", O_RDONLY , 0444);  
  7. +    if (IS_ERR(fp)) {  
  8. +        printk("open sys/class/backlight/pwm-backlight.0/brightness file error !!!\n");  
  9. +        return -1;  
  10. +   }  
  11. +  
  12. +   fs = get_fs();  
  13. +   set_fs(KERNEL_DS);  
  14. +   vfs_read(fp, &readValue,2, &pos);  
  15. +// printk("readValue %d  %d !!!\n",readValue[0] , readValue[1]);  
  16. +   filp_close(fp, NULL);  
  17. +   set_fs(fs);  

读取背光状态也可以放在调度函数里面执行。但这里也是还有需要注意的地方,背光值读取出来的数据类型需要注意,适当转化一下即可。或许也没有转化的必要性,只需进行判断,是否是背光为0的状态。



0 0
原创粉丝点击