在分析sensor的源码之前,先来看下sensor这个对象都包含了哪些信息?

比如拿华为honor8来说,来获取下陀螺仪对应的信息

1sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);

不着急看代码,先来个log看下。

1 {Sensor name="LSM330 Gyroscope sensor", vendor="STMicroelectronics"
2version=1, type=4, maxRange=34.906586, 
3resolution=0.0012217305, 
4power=6.1, minDelay=10000}

看起来功耗还是挺高的,达到了6.1mA.题外话哈哈

从log来看,打印出来的就这些params.

尝试一下能修改sensor的参数吗?发现不能,没有set方法。也就是说sensor的所有参数是写死的,三方应用无法修改。

Sensor源码研究(二)--Sensor初步分析_java

来从代码验证下,看看sensor参数有哪些喽

代码入口

 

看一个对象包含哪些信息,不就看这个类的成员吗?这个有很多方法啦,条条大路通罗马

如果你擅长java,那就去看Sensor.java文件代码路径/frameworks/base/core/java/android/hardware/Sensor.java

如果你擅长c/c++,那就去看Sensors.h文件,代码路径/hardware/libhardware/include/hardware/sensors.h

其实还有一个,你可以直接看types.hal文件,里边儿有sensorInfo结构体,代码路径为/hardware/interfaces/sensors/1.0/types.hal

好,接下来我直接看types.hal文件,为什么选择这个?就是喜欢,哈哈哈

Sensor源码研究(二)--Sensor初步分析_java_02

 

这个文件还包含了传感器的其他信息。不多说,看成员变量

成员变量
  • {int32_t sensorHandle}:传感器id标识,32位int型数据,sensors的唯一id标识,在hal层的api中用于代表sensor

  • {string name}:传感器名字,string类型

  • {string vendor}:传感器厂商,string类型,传感器硬件部分供应商

  • {int32_t version}:传感器硬件和软件部分的版本号,int型数据,当驱动更新时版本号必须要增加

  • {SensorType type}:传感器类型,int型数据。

  • {string typeAsString}:传感器类型的字符串描述,string类型数

  • {float maxRange}:传感器值变化的最大范围,float类型数据

  • {float resolution}:要报告的传感器数据的最小差异,float类型数据,猜测应该是比较两次事件之间的差值,如果比这个值小,就不上报数据,有待考证

  • {float power}:传感器的近似功耗,float类型数据,单位为mA

  • {int32_t minDelay}:传感器的最小延时,int类型数据。和传感器report数据的mode有关系,如果是连续报告模式,那么最小的采样周期以us微妙为单位。如果on-change也就是有改变时才report,那么最小延时为0,也就是只要有变化就上报,还有one-shot单脉冲时为-1,special为0

  • {uint32_t fifoReservedEventCount}:预留event数量,无符号整型数据

  • {uint32_t fifoMaxEventCount}:fifo存储器缓存的最大event的数量(先进先出队列存储器,存储传感器事件)

  • {string requiredPermission}:注册sensor和接收sensor数据时所需要的权限,string类型

  • {int32_t maxDelay}:传感器两组数据之间的最大延时,也就是传感器上报数据的最小频率

  • {bitfieldflags}:传感器的flag标志,比如是否属于wakeup型的传感器SENSOR_FLAG_WAKE_UP,以及表明sensor的reportmode的标志SENSOR_FLAG_CONTINUOUS_MODE等等

 

Sensor源码研究(二)--Sensor初步分析_java_03

 

分析到这儿,终于知道有哪些参数了。接下来有一些参数说明

type说明

每一个sensor都对应一个type,定义了传感器要测试的是什么,以及测量的数据如何上报等问题。

设备制造商OEM也可以定义自己的传感器type。

如果所定义的type是私有的,也就是仅仅提供给系统应用使用,那么type一定不能暴露在sdk中(必须是hide)

并且type必须是从DEVICE_PRIVATE_BASE(0x10000)位置开始,也就是说值必须大于0x10000。

除此之外,也就是除去设备私有传感器之外,oem所定义的传感器必须符合要求。有哪些要求呢?

第一,每一个sensor必须有一个typeAsString字段,也就是type的字符串描述。在Androidframework层会给从hal层获取到的字符串添加“android.sensor”前缀。

比如,如果hal层的type是“SensorType::Acclerometer”,那么,经过Androidframework之后,变成“android.sensor.accelerometer”

第二,当Android发布了一个新的sensor类型,如果该sensor可以代替oem自定义的sensor类型,那么一定要用Android官方的sensor类型

wake-up说明

 

这个wake-up是说什么?当数据可用时,是否要将手机从suspend睡眠状态中唤醒。

这句话交代两个概念,一个是动作,那就是唤醒手机,一个是条件也就是唤醒时机

sensor分为两大类,一类是wake-up,另一类没得选了那就只能是non-wake了。

作为wake-up的sensor,如果有传感器事件上报,那么当fifo传感器事件缓存区存满时会唤醒屏幕

但如果sensor事件上报超时了也会唤醒手机。如果没有事件上报,当然也就不会唤醒了。

也就是如果event是来自于wake-up类型的传感器,那么driver就会一直持电源锁禁止手机休眠,直到sensorservie轮询了event。

一旦sensorservice轮询了事件,driver就会释放电源锁,但此时sensorservice会持锁,直到app读取了event才会释放。

而作为non-wake的sensor,传感器事件不会上报

这就会出现一个问题,如果注册了传感器,也就是传感器被激活之后,那么底层就会一直有传感器事件

而此时如果系统休眠,event只存在与缓冲区Fifo,无法上报给上层

缓冲区的存储有限,所以最终缓存区满了之后,新的event事件会覆盖旧的event事件,事件就会丢失了。

这个有待验证,也就是在系统休眠后,event事件是否是会被覆盖,并且不再上报

当然,以上分析都是针对连续上报事件的传感器来说的。

每个sensor传感器都可以注册这两种类型,比如一个陀螺仪type类型的传感器可以能会有两个传感器,一个是wake-up的,一个是non-wake的。

这个在sensorManager提供的api中也可以看到

1//如果是特定的wake-up类型,那就返回wake-up的传感器,否则就返回non-wake的传感器
2sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
3//获取对应type的wake-up的传感器
4sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE, true);

代码中说的也很详细,可以看下注释,代码路径:/frameworks/base/core/java/android/hardware/SensorManager.java

那么这些sensor都是哪儿来的呢?sensor的参数是在哪儿写的呢?

sensor来源

 

sensor的种类有很多,不同手机也有所不同。这些sensor都是哪儿来的呢?三个方面

Sensor源码研究(二)--Sensor初步分析_java_04

  • sensor硬件芯片供应商,各种硬件传感器以及借助硬件传感器融合出的sensor

  • google源码中借助陀螺仪|加速度|磁力等硬件传感器融合的虚拟sensor,但都是作为debug调试使用

  • OEM设备厂商比如小米,Smartisan之类,也会借助硬件传感器的数据融合自己的sensor,有私有的sensor只供自己使用,也有可能开发的sensor供三方应用使用

前文说过,sensor的参数三方应用无法修改,那么系统能修改吗?全凭你一句话!

如果是硬件芯片供应商提供的sensor,那么就相当于sensor是一个硬件芯片,需要driver接入。

运气好的话或者说传感器性能差融合度差没啥高级算法的话,这块儿驱动程序直接给你,你自己接入。相当于传感器参数完全暴露出来,想改什么改什么

运气不好的呢?省事儿一点儿,直接给你个so包,这样可以保护硬件厂商自己的传感器算法

对hal层来说,反正就是加载硬件module,并获取到sensor参数信息.

hal层的话关于数据的delay还是可以修改滴setDelay就可以。

如果是google或者是OEM自己定义的虚拟sensor,参数是可以自己修改滴。

sensor流程

那么整个sensor的流程是怎么样的呢

对于Android系统来说,在系统开机之后,就会加载framework层的sensor服务

在加载sensor服务时就会通过hal层加载sensor的module,获取到驱动层的传感器列表。

之后也会加载google的用于调试的虚拟传感器以及系统自己添加的传感器。

加载完成之后,以sensorList列表的形式提供给application上层应用使用,也就是getDefaultSensor所获取到的sensor。

sensorservice在sensor加载完成后会开启线程,监听来自于hal层的event事件。

不论有没有应用监听注册sensor,线程都会一直监听hal层的传感器event事件上报。

一旦有应用监听sensor,那么sensor就会被activate激活,激活之后驱动层就会有事件上报。

整个布局就是这么个布局,具体数据的处理和上报就需要代码分析了

Sensor源码研究(二)--Sensor初步分析_java_05

 

https://mp.weixin.qq.com/s/oDgHSpYd-DuyGNbecnVIrQ