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) {}
}
这里我们能很清晰地看到整个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;
当然随着科技发展,现在的ic越来越强大,出现了light sensor/ p sensor等合集的IC,那么此时,lightsensor可能需要的不光光是lux了,在这里先卖个关子,后面在详解HAL层的时候再详细解释一下如何使用这个结构体
以下是各种类
- SystemSensorManager:传感器框架中的java层Manager的实现者, 继承了java类 SensorManager
- SensorManager: 特指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方式启动Zygote
- Zygoto会将启动android中所有应用程序及运行系统关键服务的system进程,它会创建一下虚拟机实力孵化新的进程,这里主要是启动了systemService
- SystemService用于管理系统的关键服务,它的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 中读取传感器事件数据。
此时整个基础架构已经搭建完毕
好了,后面应该讲解如何建立连接了,但是时间关系,我在此便打住,会尽快将第二篇整理发出。
后言
我的想法是整个framework sensor部分分3大块解说,第一块是主体框架,第二块是源码分析,第三块是与HAL层的联系
敬请期待吧