转自:http://blog.csdn.net/zhangjie201412/article/details/7230126

之前的几篇文章重点介绍了android中传感器模块的标准移植方法,这篇文章我主要跟大家介绍下android framework中对传感器的处理以及管理,涉及到的代码有:

/frameworks/base/services/sensorservice/SensorService.cpp

/frameworks/base/services/sensorservice/SensorDevice.cpp

/frameworks/base/services/sensorservice/SensorInterface.cpp

/frameworks/base/core/jni/android/hardware/jni/android_hardware_SensorManager.cpp

/frameworks/base/core/java/android/hardware/SensorManager.java

首先在这里我先声明下,网上关于这部分的资料很多,不过都大同小异,而且大部分是android2.2的分析,但是到了2.3之后sensor这边改了很多代码,一开始我也看的很迷糊的。这里我只是阐述了我的理解,可能是有问题的,希望有识之士可以指出,这边我也只能粗略的介绍了,能力有限。

在上一篇文章中介绍了在SensorDevice.cpp中使用hw_get_module来获得HAL层编译出来的sensor.goldfish.so:

[cpp] view plain copy
  1. SensorDevice::SensorDevice()
  2. :mSensorDevice(0),
  3. mSensorModule(0)
  4. {
  5. status_terr=hw_get_module(SENSORS_HARDWARE_MODULE_ID,
  6. (hw_module_tconst**)&mSensorModule);
  7. LOGE_IF(err,"couldn'tload%smodule(%s)",
  8. SENSORS_HARDWARE_MODULE_ID,strerror(-err));
  9. if(mSensorModule){
  10. err=sensors_open(&mSensorModule->common,&mSensorDevice);
  11. LOGE_IF(err,"couldn'topendeviceformodule%s(%s)",
  12. SENSORS_HARDWARE_MODULE_ID,strerror(-err));
  13. if(mSensorDevice){
  14. sensor_tconst*list;
  15. ssize_tcount=mSensorModule->get_sensors_list(mSensorModule,&list);
  16. mActivationCount.setCapacity(count);
  17. Infomodel;
  18. for(size_ti=0;i<size_t(count);i++){
  19. mActivationCount.add(list[i].handle,model);
  20. mSensorDevice->activate(mSensorDevice,list[i].handle,0);
  21. }
  22. }
  23. }
  24. }

这就是framework调用到HAL的最最重要的一个接口,接下来的工作可以说就是根据得到的这个地址来找到相应的HAL中定义的hw_device_t结构体中的回调函数作为framework中的api,然后进行“封装”,因为hal中只是poll数据,framework需要对数据处理,以及封装API给android app开发者使用。

[cpp] view plain copy
  1. /**Openanewinstanceofasensordeviceusingname*/
  2. staticintopen_sensors(conststructhw_module_t*module,constchar*id,
  3. structhw_device_t**device)
  4. {
  5. intstatus=-EINVAL;
  6. sensors_poll_context_t*dev=newsensors_poll_context_t();
  7. memset(&dev->device,0,sizeof(sensors_poll_device_t));
  8. dev->device.common.tag=HARDWARE_DEVICE_TAG;
  9. dev->device.common.version=0;
  10. dev->device.common.module=const_cast<hw_module_t*>(module);
  11. dev->device.common.close=poll__close;
  12. dev->device.activate=poll__activate;
  13. dev->device.setDelay=poll__setDelay;
  14. dev->device.poll=poll__poll;
  15. *device=&dev->device.common;
  16. status=0;
  17. returnstatus;
  18. }

最主要的还是open,close,activate,setDelay,poll等回调函数。

得到module之后再open,然后就是得到activate,poll等函数进行封装到SensorDevice这个类当中去。最后,service这层是通过SensorInterface.cpp把接口都封装到HardwareSensor这个类中,传送到/frameworks/base/core/jni/android_hardware_SensorManager.cpp中被使用。

大家可以看到其实/frameworks/base/core/jni/android_hardware_SensorManager.cpp就是/frameworks/base/core/java/android/hardware/SensorManager.java的原生代码,其中封装了一些native function给java文件调用,其中对于我们来说最重要的也就是poll函数。

下面是core中的jni函数:

[cpp] view plain copy
  1. staticjint
  2. sensors_data_poll(JNIEnv*env,jclassclazz,jintnativeQueue,
  3. jfloatArrayvalues,jintArraystatus,jlongArraytimestamp)
  4. {
  5. sp<SensorEventQueue>queue(reinterpret_cast<SensorEventQueue*>(nativeQueue));
  6. if(queue==0){return-1;}
  7. status_tres;
  8. ASensorEventevent;
  9. res=queue->read(&event,1);
  10. if(res==-EAGAIN){
  11. res=queue->waitForEvent();
  12. if(res!=NO_ERROR)
  13. return-1;
  14. res=queue->read(&event,1);
  15. }
  16. if(res<0)
  17. return-1;
  18. jintaccuracy=event.vector.status;
  19. env->SetFloatArrayRegion(values,0,3,event.vector.v);
  20. env->SetIntArrayRegion(status,0,1,&accuracy);
  21. env->SetLongArrayRegion(timestamp,0,1,&event.timestamp);
  22. returnevent.sensor;
  23. }

java层就是调用了这边的这个函数来得到底层的数据,其中比较重要的其实就是

[cpp] view plain copy
  1. env->SetFloatArrayRegion(values,0,3,event.vector.v);
  2. env->SetIntArrayRegion(status,0,1,&accuracy);
  3. env->SetLongArrayRegion(timestamp,0,1,&event.timestamp);

设置了value,status,timestamp这三个变量,java和应用层也就是用到了这3个参数来写android app的。

[cpp] view plain copy
  1. while(true){
  2. //waitforanevent
  3. //+++addlogbyJay
  4. Log.d(TAG,"sensordatapoll......");
  5. finalintsensor=sensors_data_poll(sQueue,values,status,timestamp);
  6. Log.d(TAG,"sensordatapoll......value:"+values[0]+values[1]+values[2]);
  7. intaccuracy=status[0];
  8. synchronized(sListeners){
  9. if(sensor==-1||sListeners.isEmpty()){
  10. //welosttheconnectiontotheeventstream.thishappens
  11. //whenthelastlistenerisremovedorifthereisanerror
  12. t;span></span>。。。

接下去我就不分析了,下面就是一些封装,封装,再封装,然后设置sensor的监听器,一般我们修改和跟踪代码就是通过以上介绍的函数中加。

ok,这边android sensor 的framework就粗略的介绍到这边。

下面介绍另外一种方法从driver打通到android framework层,其中会涉及到android server jni和driver中的uevent设置以及监听。

敬请期待。。。



更多相关文章

  1. android jni 学习笔记2
  2. Android(安卓)O Launcher3-Workspace加载
  3. Android系统启动之配置文件解析
  4. Android(安卓)Log原理分析
  5. Android(安卓)Overlay学习 一
  6. [AS3.6.1]Kotlin学习笔记3
  7. Android系统Surface机制的SurfaceFlinger服务简要介绍和学习计划
  8. Android(安卓)NDK之fseek, lseek
  9. Android(安卓)JNI 学习笔记

随机推荐

  1. MySQL REVOKE实现删除用户权限
  2. MySQL GRANT用户授权的实现
  3. 浅谈MySQL user权限表
  4. 解决mysql模糊查询索引失效问题的几种方
  5. MySQL 亿级数据导入导出及迁移笔记
  6. 如何使用分区处理MySQL的亿级数据优化
  7. 关于Mysql-connector-java驱动版本问题总
  8. MySQL ifnull的嵌套使用说明
  9. MySql中 is Null段判断无效和IFNULL()失
  10. MySql关于null的函数使用分享