Sensor framework (一)

来源:互联网 发布:软件期刊 编辑:程序博客网 时间:2024/05/17 22:10

sensor app获取

如下表,如需要获取sensor,就需要获取相关的type,这里先给大家罗列一下

那么在ap中我们是如何使用数据的呢?

导入 android.hardware 包实现 SensorEventListener 接口使用的步骤:获取SensorManager:getSystemService(SENSOR_SERVICE)获取传感器:SensorManager.getDefaultSensor()注册传感器:SensorManager.registerListener()使用完后取消注册:SensorManager.unregisterListener();

拿一个简单获取accelerometer sensor举例如下:

public class SensorActivity extends Activity, implements SensorEventListener {
private final SensorManager mSensorManager;
private final Sensor mAccelerometer;

 public SensorActivity() {     mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);     mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); } protected void onResume() {     super.onResume();     mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); } protected void onPause() {     super.onPause();     mSensorManager.unregisterListener(this); } public void onAccuracyChanged(Sensor sensor, int accuracy) {} public void onSensorChanged(SensorEvent event) {}

}

1234567891011121314151617181920212223

这里我们能很清晰地看到整个sensor监听的过程,那么sensor在这里仅仅是去拿到的sensorManager,然后对这个sensormanger进行操作,那么对于AP来讲的话,只有Manager是可见的。
sensor的manger机制

根据sensor的AP与framerwork,我大致又可以为整个sensor自ap向下分为:

在使用sensor服务前,需要先获取sensorManager,
为何要有这样的架构

由于服务进程和应用运行在不同的进程,应用必须和服务建立进程间通信,这就为应用开发增加了许多繁琐的细节,为此, 引进Manager机制达到了暴露服务接口同时又隐藏共享服务的目的。

这样的做法有助于applications层的开发人员更加方便地进行开发
sensor Framework架构简介

在这里首先我先画出整个sensor的线路,有助于大家理解。

Android对Sensor HAL及其上层作出了定义,但是对于sensorHAL以下未作出定义,因而在kernel层却可以更加的随意,当然我在这里仍然是使用event dev的方式,通过input子系统向上发送数据(后面我又想开个专栏专门讲整个linux的子系统机制)。大家可以参考Android Sensor详解(4)driver的攻防战一文,看看我是如何写驱动的。
sensor的数据流向

在了解了sensor的大体流程后,那么我们可以联系ap层看看sensor又是如何去获取数据的。
于是画图如下:

当一个ap注册了传感器监听后,获取相关type的systemSensorManger,通过注册监听sensoreventqueue的数据变化,而这些变化又是由sensorService从sensor的hal层拿到的,而hal层通过input子系统,从kernel拿到了数据。
可以看到以下为sensor在hal层的event格式

typedef struct sensors_event_t {
int32_t version;
int32_t sensor; //标识符
int32_t type; //传感器类型
int32_t reserved0;
int64_t timestamp; //时间戳
union {
float data[16];
sensors_vec_t acceleration; //加速度
sensors_vec_t magnetic; //磁矢量
sensors_vec_t orientation; //方向
sensors_vec_t gyro; //陀螺仪
float temperature; //温度
float distance; //距离
float light; //光照
float pressure; //压力
float relative_humidity; //相对湿度
};
uint32_t reserved1[4];
} sensors_event_t;

123456789101112131415161718192021

当然随着科技发展,现在的ic越来越强大,出现了light sensor/ p sensor等合集的IC,那么此时,lightsensor可能需要的不光光是lux了,在这里先卖个关子,后面在详解HAL层的时候再详细解释一下如何使用这个结构体

以下是各种类

SystemSensorManager:传感器框架中的java层Manager的实现者, 继承了java类 SensorManagerSensorManager: 特指native代码中的SensorManager类, 其提供了从SensorService获取传感器列表,建立连接通道的功能SensorService:传感器框架中的 Service的实现者SensorDevice:封装了Sensor HAL,并提供相应接口SensorFusion:虚拟传感器的实现,根据所依赖的硬件传感器的值, 计算出虚拟传感器的值SensorEventQueue,SensorEventConnnection:Service和Manager之间的连接而者之间具有层级关系

sensor框架初始化

大致上sensor的框架可以分为3个阶段
* sensorService实例化
* SensorManager初始化
* 建立Service与Manager之间的连接

sensorService实例化

andorid启动到Init调用init.rc文件以service方式启动ZygoteZygoto会将启动android中所有应用程序及运行系统关键服务的system进程,它会创建一下虚拟机实力孵化新的进程,这里主要是启动了systemServiceSystemService用于管理系统的关键服务,它的main 方法中调用了init1(), 这是一个native 方法, 在其实现中, 间接调用了SensorService::instantiate()方法,导致了SensorService的实例化SensorService实现具体的方法如下图

SensorService启动后,通过defaultServiceManager::addService() 将自己添加到了系统服务管理中,然后等来自SensorManager的连接。

后续的SensorManager就可以使用defaultServiceManager:getService() 来获取 SensorService的实例来建立连接。
这就与前面讲到的ap串起来了。
SensorManager初始化

当在Ap中获取SensorManager的时候, 就会导致初始化流程进入第二个阶段。
setp1 获取SensorManager实例

初始化SensorManager时, java层的Manager(SystemSensorManager)在每个Context的实例注册时实例化一次,native层的Manager(SensorManager),在整个系统中只有唯一个一个实例

你通过同一个Context的实例只会获取到同一个SystemSensorService的实例
调用native_class_init

native_class_init 在native层实现,它仅仅只是将java层中Sensor 类的成员变量 的ID保存起来, 这样就可以在native代码中修改java中对象的值了。

保存的ID 后面将用于初始化java层的Sensor列表在JNI机制中,native层无论是访问java层的变量还是方法,都需要先获取他们的ID值,然后再使用JNI机制提供的方法来调用方法或访问类对象的成员变量。

调用Sensor_module_init

Sensor_module_init()内部仅仅只是调用了
SensorManager::getInstance(),在系统中如果不存在Sensoranager的实例时,这将导致构造一个SensorManager对象
setp2 SensorManager初始化
mSensorList(0)调用

SensorManager的构造函数中将mSensorList初始化为空。

在HAL层中保存所有硬件上实现的传感器。

native层在HAL的基础上还会添加一些虚拟传感器。

java层保存的传感器列表在native层基础上有所删减
getService()调用

从defaultServiceManager处获取SensorService的指针,最多尝试4次

回想一下,SensorService在启动后将自己注册到defaultServiceManager现在,SensorManager直接找到组织,和SensorService接上头了。

这一过程将导致 SensorService的 OnFirstRef方法被调用,执行SensorService的初始化

获取的SensorService指针被保存在一个强引用对象中,自动强引用SensorService,调用SensorService的 OnFirstRef方法

setp3 SensorService初始化
调用SensorDevice:getInstance()

step4 SensorDevice初始化
调用hw_get_module/sensor_open/activate

调用hw_get_module加载Sensor模块的共享库文件(在system/lib64/)
调用sensors_open打开设备
调用activate 使能sensor模块
step5 SensorService初始化继续
调用getSensorList

通过SensorDevice.getSensorList向HAL层请求传感器列表并在Sensorervice中注册:
* 添加到mSensorList中去;
* 添加到sensorMap中去,传感器的Handle相关连;
* 新建一个传感器事件数据对象event 到mLastEventSeen中,和传感器的handle相关连
调用SensorFusion::getInstance实例化

SensorDevice封装了所有的 hardware sensor;SensorFusion则是封装了所有虚拟传感器,实现了它们的操作接口
调用registerVirtualSensor

虚拟传感器的注册过程和hardware sensor 的注册过程相同,在此基础上,还将其添加到了mVirtualSensorList中

旋转矢量传感器重力传感器线性加速度传感器方向传感器真实的陀螺仪

step6 SensorService启动工作线程

调用run
SensorService的初始化已经完成, 现在,启动它的工作线程, 然后返回到调用它的SensorManager的构造函数中,继续执行。
SensorService进入工作线程循环后的细节, 等到整个Sensor framwork都初始化完毕
step7 SensorManger初始化
调用linkTodeath

注册一个到 SensorService的死亡监听器

SensorService异常退出时,sensorManager会自行死亡通过systemService申请了某个service的Binder后,可以调用这个IBinder的linkToDeath函数注册一个Ibinder.DeathRecipient类型的对象。Ibinder.DeathRecipient是IBinder类中定义的一个嵌入类。当这个IBinder所对应的Service进程被异常的退出时,比如被kill掉,这时系统会调用这个Ibinder之前通过linkToDeath注册的DeathRecipient类对象的binderDied函数。

调用SensorService.getSensorList

又是获取传感器列表, 每一层都会从下层获取传感器列表并保存
step8 SystemSensorManager初始化

进一步调用Sensors_Module_get_next_sensor

回忆一下 native_class_init 中,将java层的Sensor类的成员变量保存在 native层SensorManager中。
这一步调用native层的 Sensor_module_get_next_sensor, 利用保存在SensorManager中的传感器列表来初始化SystemSensorManager 中的Sensor列表
new SensorThread

创建SystemSensorManager 的工作线程,负责从 native 层 的 SensorEventQueue 中读取传感器事件数据。

原创粉丝点击