Android模拟器学framework和driver之传感器篇5(Android framework)

时间:2024-03-04 16:00:13

之前的几篇文章重点介绍了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:

 

  1. SensorDevice::SensorDevice()  
  2.     :  mSensorDevice(0),  
  3.        mSensorModule(0)  
  4. {  
  5.     status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,  
  6.             (hw_module_t const**)&mSensorModule);  
  7.   
  8.     LOGE_IF(err, "couldn\'t load %s module (%s)",  
  9.             SENSORS_HARDWARE_MODULE_ID, strerror(-err));  
  10.   
  11.     if (mSensorModule) {  
  12.         err = sensors_open(&mSensorModule->common, &mSensorDevice);  
  13.   
  14.         LOGE_IF(err, "couldn\'t open device for module %s (%s)",  
  15.                 SENSORS_HARDWARE_MODULE_ID, strerror(-err));  
  16.   
  17.         if (mSensorDevice) {  
  18.             sensor_t const* list;  
  19.             ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);  
  20.             mActivationCount.setCapacity(count);  
  21.             Info model;  
  22.             for (size_t i=0 ; i<size_t(count) ; i++) {  
  23.                 mActivationCount.add(list[i].handle, model);  
  24.                 mSensorDevice->activate(mSensorDevice, list[i].handle, 0);  
  25.             }  
  26.         }  
  27.     }  
  28. }  

 

 

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

 

  1. /** Open a new instance of a sensor device using name */  
  2. static int open_sensors(const struct hw_module_t* module, const char* id,  
  3.                         struct hw_device_t** device)  
  4. {  
  5.         int status = -EINVAL;  
  6.       
  7.         sensors_poll_context_t *dev = new sensors_poll_context_t();  
  8.   
  9.         memset(&dev->device, 0, sizeof(sensors_poll_device_t));  
  10.   
  11.         dev->device.common.tag = HARDWARE_DEVICE_TAG;  
  12.         dev->device.common.version  = 0;  
  13.         dev->device.common.module   = const_cast<hw_module_t*>(module);  
  14.         dev->device.common.close    = poll__close;  
  15.         dev->device.activate        = poll__activate;  
  16.         dev->device.setDelay        = poll__setDelay;  
  17.         dev->device.poll            = poll__poll;  
  18.   
  19.         *device = &dev->device.common;  
  20.         status = 0;  
  21.         return status;  
  22. }  


最主要的还是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函数:

 

  1. static jint  
  2. sensors_data_poll(JNIEnv *env, jclass clazz, jint nativeQueue,  
  3.         jfloatArray values, jintArray status, jlongArray timestamp)  
  4. {  
  5.     sp<SensorEventQueue> queue(reinterpret_cast<SensorEventQueue *>(nativeQueue));  
  6.     if (queue == 0) {return -1;}  
  7.   
  8.     status_t res;  
  9.     ASensorEvent event;  
  10.   
  11.     res = queue->read(&event, 1);  
  12.     if (res == -EAGAIN) {  
  13.         res = queue->waitForEvent();  
  14.         if (res != NO_ERROR)  
  15.             return -1;  
  16.         res = queue->read(&event, 1);  
  17.     }  
  18.     if (res < 0)  
  19.         return -1;  
  20.   
  21.     jint accuracy = event.vector.status;  
  22.     env->SetFloatArrayRegion(values, 0, 3, event.vector.v);  
  23.     env->SetIntArrayRegion(status, 0, 1, &accuracy);  
  24.     env->SetLongArrayRegion(timestamp, 0, 1, &event.timestamp);  
  25.     return event.sensor;  
  26. }  


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

 

 

  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的。

 

 

  1.               while (true) {  
  2.                   // wait for an event  
  3. //+++add log by Jay  
  4.         Log.d(TAG, "sensor data poll......");  
  5.                   final int sensor = sensors_data_poll(sQueue, values, status, timestamp);  
  6.         Log.d(TAG, "sensor data poll......value:"+values[0]+values[1]+values[2]);  
  7.   
  8.                   int accuracy = status[0];  
  9.                   synchronized (sListeners) {  
  10.                       if (sensor == -1 || sListeners.isEmpty()) {  
  11.                           // we lost the connection to the event stream. this happens  
  12.                           // when the last listener is removed or if there is an error  
  13. t;span>      </span>。。。  


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

 

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

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

敬请期待。。。