Android4.4KK下遮盖p-sensor拨打电话无法自动灭屏的问题分析

简介: 一、问题现象先遮盖P-Sensor,然后拨打电话,90%的情况下屏幕无法自动关闭背光显示。关闭Settings-》Display-》Brightness-》Auto,然后再执行以上操作则100%能够正常关闭背光显示。


一、问题现象

先遮盖P-Sensor,然后拨打电话,90%的情况下屏幕无法自动关闭背光显示。关闭Settings-》Display-》Brightness-》Auto,然后再执行以上操作则100%能够正常关闭背光显示。


Platform:MT6732

Android版本:4.4KK

BuildType:user

系统软件版本:SWA1H+UM

系统RAM:1GB


参考机行为:参考机1正常,参考机2正常


二、MTK平台Android的Sensor流程框架


整个流程框架主要分为6个部分:

1,APPLICATIONS

这里主要是指Dialer/PhoneApp,他们是用户直接操作的接口,他们使用了P-Sensor来进行亮屏和灭屏的操作(通过向PowerManagerService请求PROXIMITY_SCREEN_OFF_WAKE_LOCK实现)。

2, FRAMEWORKS(JAVA)

主要包括两部分:

一、PowerManager/PowerManagerService,其作用是提供PROXIMITY_SCREEN_OFF_WAKE_LOCK,并与SensorManager/SystemSensorManager交互。

二、SensorManager/ SystemSensorManager,其作用是提供JAVA层控制sensor的接口,并透过JNI与Native的SensorManager通信。

3,FRAMEWORKS(JNI)

这里主要是是指SensorManager JNI,其主要作用是提供接口给SensorManager/SystemSensorManager与NatvieLibs的SensorManager通信。

4,FRAMEWORKS(LIBS/NativeService)

主要包括两部分:

一、SensorManager/SensorEventQueue,其属于NativeLibs,主要作用是为SensorManager JNI提供接口,请求SensorService创建SensorEventQueue(基于Binder的IPC),从而完成SensorEvent从SensorService到SensorManager JNI的传输。

二、Sensorservice/sensordevice,其属于NativeService,主要作用是为上层提供接口createSensorEventConnection,与Sensor的HAL层进行交互,控制sensor以及获取sensorEvent。

5,HAL

这里主要是指Nusensors和Hwmsen,其主要功能是为SensorService提供接口,与Sensor的Driver层进行交互,从而达到控制Sensor和获取SensorEvent的目的。

6,Driver

这里主要包括两大部分:

一、hwmsen_dev/StandardInputDevice,这部分是在具体的SensorDriver的上面又抽象出的一层,其主要功能是集中处理不同类型的sensor,包括lightsensor,proximitysensor等。

二、PROXIMITY/LIGHT(stk3x1x-new)等,这部分是指具体的SensorDriver,其主要功能是与具体的Sensor交互,包括控制、获取数据并上报等。这里有一点需要说明的是,Sensor分两种:一种是interrupt sensor,一种是polling sensor,他们的区别在于interrupt sensor是直接挂接在特定的中断上的,一旦sensor有数据就会触发中断处理(我们的PROXIMITYsensor就属于interrupt sensor),polling sensor是被动的提供数据,抽象出的hwmsen_dev会按照一定频率定时的去获取它的数据(我们的LIGHTsensor就属于polling sensor)。


三、问题分析

1、初步分析

根据问题在遮住p-sensor的情况下拨打电话无法灭屏的表面现象,我们首先考虑的是p-sensor硬件有没有产生数据并报给Driver,为了确认这一点我们首先在p-sensor的Driver中添加log:

然后执行操作,打出的log如下:

以上log中value 0x0,代表p-sensor的接近,0x1代表p-sensor的远离,所以说明硬件已经将p-sensor的数据上报到了SensorDriver中,SensorDriver又将数据上报到了driver抽象层hwmsen_dev/StandardInputDevice中,接下我们就要看driver抽象层是否将p-sensor的数据正确上报到了HAL。Nusensor.cpp中的关键代码如下:

以上部分代码是HAL中轮询所有sensor并获取event,其中就包括p-sensor,另外这里有一个很关键的data type,就是SENSOR_TYPE_META_DATA,下面会具体说明它的作用,同时说明一下这里的轮询的实现代码是通过读取StandardInputDevice的节点("/dev/input/event%d", num)来实现的。

在轮询完所有的sensor之后,如果还有空间没有用完就继续poll在sensor的data_fd上去继续获取event以填充完一次获取,然后返回给上层的sensorservice。使用同样的方法再这些代码流中添加log,以获取运行时的数据状态,发现p-sensor的数据同样正确的获取到了,这里就不再赘述。

接下来继续分析sensorservice中的数据流向,看是否正确上报到了SensorManager/SensorEventQueue中,sensorservice的关键代码如下:

首先,从代码中我们看到sensorservice继承于Thread,所以其本身是一个Thread并拥有一个闭合循环的threadloop,不断的从sensor的HAL中读取数据,通过添加log信息,发现在以后代码中p-sensor的数据依然被正确的获取到。

其次,读取完数据之后它会向当前所有连接到sensorservice的client发送sensorEvent,在以上代码中加上发送之前的log打印出p-sensor的数据依然存在。

然后,是具体的发送到client之前的处理代码,我们继续再其中添加log,发现在处理之前p-sensor的数据都是存在的,具体代码如下:

最后,是最终将处理完的数据发送到client的代码,我们在发送之前添加log,最终发现打印出的log中p-sensor的数据已经不存在了,具体代码如下:

2、继续分析

根据以上分析我们发现在被sendEvents处理之前,p-sensor的数据还存在,处理之后在发送之前p-sensor的数据已经被过滤掉,我们可以初步将问题的关键定位在处理过程中。

通过阅读和分析其处理过程的代码,发现了一个关键条件,就是如果sensor的数据想要被最终发送,必须满足mSensorInfo[index].mFirstFlushPending == false的条件,而这个条件满足的前提是当前这个SensorEventConnection必须先接收到SENSOR_TYPE_META_DATA,将mSensorInfo[index].mFirstFlushPending置为false,然后再接收到的具体sensor数据才能被最终发送出去。

根据初步分析的过程中添加的log,我们发现SENSOR_TYPE_META_DATA在sensor的数据流中是存在,但是却是在具体的sensor数据之后,从而导致具体的sensor数据被忽略(这里指是p-sensor的靠近数据)。

通过分析代码我们发现SENSOR_TYPE_META_DATA是sensor被enable之后发出的第一个first flush event,应当在具体的sensor数据之前,enable的关键代码如下:

首先batch,然后setFirstFlushPending为true并flush,在alto4.5TMO中这些操作就会为BatchSensor产生SENSOR_TYPE_META_DATA奠定基础。

最终会走到activate,将sensor真正enable,enable之后sensor会马上产生中断并上报数据,这里p-sensor的数据产生的地方是来自于Hwmsen(在nusensor的sensorlist中,Hwmsen是在第一位的,也就是说在做轮询数据的时候它会被第一个处理)。

这里需要说明的是Soul4NA和Yaris3.5AT&T为什么没有这个问题,原因就在于他们不支持batch,所以在执行batch之后会返回error,不会执行到setFirstFlushPending为true并flush的这个代码分支,而且mFirstFlushPending默认是false,具体代码如下:

从BatchSensor中获取SENSOR_TYPE_META_DATA的具体代码如下:

从log中我们发现在HAL返回数据给sensorservice时,SENSOR_TYPE_META_DATA已经被放在了具体的sensor数据之后,也就是说在sensorservice执行poll获取sensor数据的时候先获取到了具体的sensor数据,后获取到的SENSOR_TYPE_META_DATA。

3、深度分析

带着上面的问题,先获取到了sensor的数据,后获取到的SENSOR_TYPE_META_DATA,这是不正常的。对比关闭AUTO调节背光之后的正常log,我们发现一个关键现象,就是在打开AUTO调节背光的情况下,LIGHT sensor已经在工作,90%的情况下执行enable会阻塞sensorservice被系统调度,也就是执行的poll的thread不会被调度,直观的现象就是看到log中enable执行完才会调度sensorservice的poll的thread去获取事件,在这种情况下问题是必现的,另外10%的情况就是在enable执行的过程中batch刚刚执行完,满足产生SENSOR_TYPE_META_DATA的时候会先发生调度,这样sensorservice的poll的thread就先获取到了SENSOR_TYPE_META_DATA,这种情况下就没有此问题,屏幕可以正常熄灭。

根据这个关键现象我们又深入分析了enable的代码,然后再结合LIGHT sensor开和关的情况下,我们发现Driver中的执行流程存在一个条件差异:

100%可以正常熄灭屏幕的情况:

关闭AUTO调节背光,也就是关闭LIGHT sensor的情况下,在hwmsen_get_interrupt_data函数中obj->dc->polling_running的值为0,所以p-sensor上报数据时不会走hwmsen_work_func,具体代码如下:

在enable的IOCTL还没有执行完,并且没有其他活动的sensor时obj->dc->polling_running的值就会为0,enable的IOCTL执行完之后就会将obj->dc->polling_running的值置为1,同时开启polling的timer,按照一定的频率去polling sensor的数据

90%不能熄灭屏幕的情况以及10%可以熄灭屏幕的情况:

打开AUTO调节背光,也就是LIGHT sensor打开的情况下,在hwmsen_get_interrupt_data函数中obj->dc->polling_running的值为1,p-sensor上报数据时就会走hwmsen_work_func,具体代码如下:

在hwmsen_work_func中就会循环遍历所有sensor的driver,同时会区分interrupt sensor和polling sensor,然后获取它们的数据并上报。

1、90%不能熄灭的情况

由于p-sensor是interrupt sensor,所以这些调用都是在中断服务程序中处理的,由于正常情况下中断服务程序是不会被打断和抢占的,所以CPU会被其hold住直到中断服务器程序处理完毕并返回。如果在执行完enable中的batch和flush之后,系统没有发生调度并调度到sensorservice并先获取到SENSOR_TYPE_META_DATA,那么就会被activate的IOCTL触发p-sensor的数据中断,并将p-sensor的数据先上报,从而导致sensorservice被这个上报过程阻塞,最终影响到sensorservice获取数据的正常流程。

2、10%可以熄灭的情况

在执行完enable中的batch和flush之后,系统发生了调度并调度到sensorservice并先获取到SENSOR_TYPE_META_DATA,然后activate的IOCTL再触发p-sensor的数据中断,再将p-sensor的数据上报,这时就不会影响sensorservice获取数据的正常流程。

4、根本原因

在无法保证系统调度的情况下,我们发现问题的根本原因在于p-sensor的中断服务程序在LIGHT sensor打开时(obj->dc->polling_running的值为1)没有分上下段执行,而是将所有处理都放在了中断服务程序里面,从而影响了sensorservice的正常执行及数据流的正常顺序。


四、解决方案

通过以上分析,我们可以知道造成最终问题的原因是中断服务程序在LIGHT sensor打开时(obj->dc->polling_running1)没有分上执行

通过详细分析当前的代码逻辑、结构以及测试,我们给出以下改动和影响尽可能小的解决方案:

1、在Sensor的抽象Driver中(hwmsen_dev),将interrupt sensor(即p-sensor)的中断服务程序调用的函数:hwmsen_get_interrupt_data中的中断下半部处理的代码移除,只执行中断的上半部分处理,将关键数据和状态保存,即将以下代码移除:

中断的下半部分的操作放在固定频率的timer中执行,因为代码原来的逻辑就是在enable sensor的时候开启timer,去完成interrupt sensor的work,具体代码如下:

 


五、结论及后续动作

Sensor的抽象Driver中(hwmsen_dev)的中断服务程序不分上下段执行的问题在Yaris3.5AT&T以及SOUL4NA中都是存在的,但是由于没有BatchSensor的SENSOR_TYPE_META_DATA的影响,所有并没有出现这个问题。因此在以后的MTK的平台上我们都要检查是否存在此问题,以提前避免,Qualcomm平台也会同时关注。


#analyzed by vincent.song from SWD2 Framework team.

#vincent.song@tcl.com

#201501071718


目录
相关文章
|
28天前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
108 4
|
1月前
|
安全 Android开发 数据安全/隐私保护
深入探讨iOS与Android系统安全性对比分析
在移动操作系统领域,iOS和Android无疑是两大巨头。本文从技术角度出发,对这两个系统的架构、安全机制以及用户隐私保护等方面进行了详细的比较分析。通过深入探讨,我们旨在揭示两个系统在安全性方面的差异,并为用户提供一些实用的安全建议。
|
3月前
|
开发工具 Android开发 Swift
安卓与iOS开发环境对比分析
在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统无疑是主角。它们各自拥有独特的特点和优势,为开发者提供了不同的开发环境和工具。本文将深入浅出地探讨安卓和iOS开发环境的主要差异,包括开发工具、编程语言、用户界面设计、性能优化以及市场覆盖等方面,旨在帮助初学者更好地理解两大平台的开发特点,并为他们选择合适的开发路径提供参考。通过比较分析,我们将揭示不同环境下的开发实践,以及如何根据项目需求和目标受众来选择最合适的开发平台。
52 2
|
20天前
|
Java 开发工具 Android开发
安卓与iOS开发环境对比分析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自占据半壁江山。本文深入探讨了这两个平台的开发环境,从编程语言、开发工具到用户界面设计等多个角度进行比较。通过实际案例分析和代码示例,我们旨在为开发者提供一个清晰的指南,帮助他们根据项目需求和个人偏好做出明智的选择。无论你是初涉移动开发领域的新手,还是寻求跨平台解决方案的资深开发者,这篇文章都将为你提供宝贵的信息和启示。
26 8
|
2月前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
80 15
Android 系统缓存扫描与清理方法分析
|
23天前
|
安全 Android开发 数据安全/隐私保护
深入探索Android与iOS系统安全性的对比分析
在当今数字化时代,移动操作系统的安全已成为用户和开发者共同关注的重点。本文旨在通过比较Android与iOS两大主流操作系统在安全性方面的差异,揭示两者在设计理念、权限管理、应用审核机制等方面的不同之处。我们将探讨这些差异如何影响用户的安全体验以及可能带来的风险。
30 1
|
2月前
|
存储 Linux Android开发
Android底层:通熟易懂分析binder:1.binder准备工作
本文详细介绍了Android Binder机制的准备工作,包括打开Binder驱动、内存映射(mmap)、启动Binder主线程等内容。通过分析系统调用和进程与驱动层的通信,解释了Binder如何实现进程间通信。文章还探讨了Binder主线程的启动流程及其在进程通信中的作用,最后总结了Binder准备工作的调用时机和重要性。
Android底层:通熟易懂分析binder:1.binder准备工作
|
3月前
|
安全 Android开发 数据安全/隐私保护
探索安卓与iOS的安全性差异:技术深度分析与实践建议
本文旨在深入探讨并比较Android和iOS两大移动操作系统在安全性方面的不同之处。通过详细的技术分析,揭示两者在架构设计、权限管理、应用生态及更新机制等方面的安全特性。同时,针对这些差异提出针对性的实践建议,旨在为开发者和用户提供增强移动设备安全性的参考。
151 3
|
2月前
|
开发工具 Android开发 Swift
安卓与iOS开发环境的差异性分析
【10月更文挑战第8天】 本文旨在探讨Android和iOS两大移动操作系统在开发环境上的不同,包括开发语言、工具、平台特性等方面。通过对这些差异性的分析,帮助开发者更好地理解两大平台,以便在项目开发中做出更合适的技术选择。
|
3月前
|
安全 Linux Android开发
探索安卓与iOS的安全性差异:技术深度分析
本文深入探讨了安卓(Android)和iOS两个主流操作系统平台在安全性方面的不同之处。通过比较它们在架构设计、系统更新机制、应用程序生态和隐私保护策略等方面的差异,揭示了每个平台独特的安全优势及潜在风险。此外,文章还讨论了用户在使用这些设备时可以采取的一些最佳实践,以增强个人数据的安全。