Android sensor 系统框架

白日放歌须纵酒,青春作伴好还乡。这篇文章主要讲述Android sensor 系统框架 相关的知识,希望能为你提供帮助。
连载上一篇http://www.cnblogs.com/hackfun/p/7327320.html
(D) 如何加载访问.so库
    在前一篇博客http://www.cnblogs.com/hackfun/p/7327320.html中,知道如何生成了
一个HAL的.so库,在这里将分析如何加载这个HAL,如何再次封装以适合多客户端访问的情况。
    实际上,系统是通过SENSORS_HARDWARE_MODULE_ID找到对应的.so库的。因为该库中的
struct sensors_module_t结构体包含了一个唯一的ID就是SENSORS_HARDWARE_MODULE_ID,
最终的目的也是要获得这个结构体。通过查找这个ID得知是在以下文件中加载设个so的。
文件路径是:

frameworks/native/services/sensorservice/SensorDevice.cpp

先看代码注释,最后再总结。
【Android sensor 系统框架】SensorDevice.cpp
1 SensorDevice::SensorDevice() 2:mSensorDevice(0), 3mSensorModule(0) 4 { 5/* 获取SENSORS_HARDWARE_MODULE_ID对应的模块(.so库) */ 6status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, 7(hw_module_t const**)& mSensorModule); 8...... 9/* 打开模块 */ 10err = sensors_open_1(& mSensorModule-> common, & mSensorDevice); 11...... 12/* 这个模块列表中有多少个sensor */ 13ssize_t count = mSensorModule-> get_sensors_list(mSensorModule, & list); 14...... 15/* 设置容器大小 */ 16mActivationCount.setCapacity(count); 17...... 18/* 激活/使能模块中所有sensors */ 19for (size_t i=0 ; i< size_t(count) ; i++) { 20/* 添加sensor到容器 */ 21mActivationCount.add(list[i].handle, model); 22/* 激活/使能sensors */ 23mSensorDevice-> activate( 24reinterpret_cast< struct sensors_poll_device_t *> (mSensorDevice), 25list[i].handle, 0); 26} 27 } 28 29 ...... 30 31 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) { 32...... 33do { 34/* 轮询接收所有sensors上报的事件,填入sensors_event_t的buffer */ 35c = mSensorDevice-> poll(reinterpret_cast< struct sensors_poll_device_t *> (mSensorDevice), 36buffer, count); 37} while (c == -EINTR); 38return c; 39} 40 41 status_t SensorDevice::activate(void* ident, int handle, int enabled) 42 { 43...... 44/* 初始化handle(sensor类型, 如ID_A)对应的info */ 45status_t SensorDevice::activate(void* ident, int handle, int enabled); 46...... 47if (enabled) { 48/* 如果ident客户端不存在 */ 49if (isClientDisabledLocked(ident)) { 50return INVALID_OPERATION; 51} 52 53/* 该客户端存在 */ 54if (info.batchParams.indexOfKey(ident) > = 0) { 55/* 只有一个客户端,第一个连接的 */ 56if (info.numActiveClients() == 1) { 57// This is the first connection, we need to activate the underlying h/w sensor. 58actuateHardware = true; 59} 60} 61} else { 62/* ident移除成功(disable) */ 63if (info.removeBatchParamsForIdent(ident) > = 0) { 64/* 如果这是最后一个移除(disable)的客户端 */ 65if (info.numActiveClients() == 0) { 66// This is the last connection, we need to de-activate the underlying h/w sensor. 67actuateHardware = true; 68} else { 69 70} 71} 72/* 如果被disable,则直接返回 */ 73if (isClientDisabledLocked(ident)) { 74return NO_ERROR; 75} 76} 77 78/* 如果是第一次激活(enable)或最后一个禁止(disable)sensor的 79* 在这种情况下就根据handle(sensor类型)和enabled值,调用activate 80* 来enable/disable对应的sensor 81*/ 82if (actuateHardware) { 83err = mSensorDevice-> activate( 84reinterpret_cast< struct sensors_poll_device_t *> (mSensorDevice), handle, enabled); 85} 86 } 87 88 status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplingPeriodNs, 89int64_t maxBatchReportLatencyNs) { 90...... 91/* 初始化handle(sensor类型, 如ID_A)对应的info */ 92Info& info(mActivationCount.editValueFor(handle)); 93 94/* 如果这个ident(key)不存在 */ 95if (info.batchParams.indexOfKey(ident) < 0) { 96BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs); 97/* 则添加添加这个(ident, params) (key-value)对 */ 98info.batchParams.add(ident, params); 99} else { 100/* 如果存在,则更新这个ident */ 101// A batch has already been called with this ident. Update the batch parameters. 102info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs); 103} 104 105BatchParams prevBestBatchParams = info.bestBatchParams; 106/* 为这个sensor找到所有最小的采样频率和事件上报最大延迟 */ 107// Find the minimum of all timeouts and batch_rates for this sensor. 108info.selectBatchParams(); 109 110/* 如果最小的采样频率和事件上报最大延迟相对于上一次发生了变化 */ 111// If the min period or min timeout has changed since the last batch call, call batch. 112if (prevBestBatchParams != info.bestBatchParams) { 113...... 114err = mSensorDevice-> batch(mSensorDevice, handle, info.bestBatchParams.flags, 115info.bestBatchParams.batchDelay, 116info.bestBatchParams.batchTimeout); 117 118} 119...... 120 } 121 122 /* 123关于mSensorDevice-> batch(SensorDevice::batch()基于它封装一层,相当于他的实例)的作用, 124相关的说明是: 125 126Sets a sensor’s parameters, including sampling frequency and maximum 127report latency. This function can be called while the sensor is 128activated, in which case it must not cause any sensor measurements to 129be lost: transitioning from one sampling rate to the other cannot cause 130lost events, nor can transitioning from a high maximum report latency to 131a low maximum report latency. 132See the Batching sensor results page for details: 133http://source.android.com/devices/sensors/batching.html 134 135意思是这是一个设置每个sensor的一些参数,包括采样频率,最大事件上报延迟,这个 136函数可以在sensor被激活/使能时被调用,在这种情况下不能造成任何的sensor的测量 137据丢失,如从一个采样率转换到另一个采样率的时候不能造成事件丢失,或从一个最大 138上报延迟转换到另一个较低的最大上报延迟都不能造成事件丢失。 139 140也就是说每个传感器都应该有一个batch,这个batch是负责调整采样频率和最大上报事 141件延迟的参数,例如,在sensor激活的时候,可以调整一次这些参数。 142 */ 143 144 status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) 145 { 146...... 147Info& info( mActivationCount.editValueFor(handle)); 148 149/* 如果存在的sensor不是工作在continuous模式,那么setDelay()应该返回一个错误 150* 在batch模式下调用setDelay()是没用的 151*/ 152// If the underlying sensor is NOT in continuous mode, setDelay() should return an error. 153// Calling setDelay() in batch mode is an invalid operation. 154if (info.bestBatchParams.batchTimeout != 0) { 155return INVALID_OPERATION; 156} 157 158/* 到了这里,说明sensor工作的continuous模式 */ 159/* 获得这个客户端对应的index */ 160ssize_t index = info.batchParams.indexOfKey(ident); 161/* 根据这个index找到对应的batchParams值 */ 162BatchParams& params = info.batchParams.editValueAt(index); 163/* 设置这个batchParams对应的batchDelay采样频率 */ 164params.batchDelay = samplingPeriodNs; 165/* 保存batchParams到bestBatchParams */ 166info.selectBatchParams(); 167/* 实际上是调用了sensors_poll_context_t::setDelay */ 168return mSensorDevice-> setDelay(reinterpret_cast< struct sensors_poll_device_t *> (mSensorDevice), 169handle, info.bestBatchParams.batchDelay); 170 } 171 172 173 status_t SensorDevice::flush(void* ident, int handle) { 174...... 175/* 刷数据 */ 176return mSensorDevice-> flush(mSensorDevice, handle); 177 } 178 179 180 bool SensorDevice::isClientDisabled(void* ident) { 181/* 上锁 */ 182Mutex::Autolock _l(mLock); 183/* 返回客户端状态 */ 184return isClientDisabledLocked(ident); 185 } 186 187 188 bool SensorDevice::isClientDisabledLocked(void* ident) { 189/* 获取ident (key-value对)对应的索引,索引存在(> =0),返回true, 190* 否则,返回false。即用于判断该客户端是否disable 191*/ 192return mDisabledClients.indexOf(ident) > = 0; 193 } 194 195 196 void SensorDevice::enableAllSensors() { 197for (size_t i = 0; i< mActivationCount.size(); ++i) { 198Info& info = mActivationCount.editValueAt(i); 199...... 200const int sensor_handle = mActivationCount.keyAt(i); 201...... 202/* 激活sensor_handle sensor */ 203err = mSensorDevice-> activate( 204reinterpret_cast< struct sensors_poll_device_t *> (mSensorDevice), 205sensor_handle, 1); 206/* 设置相应的采样频率 */ 207err = mSensorDevice-> setDelay( 208reinterpret_cast< struct sensors_poll_device_t *> (mSensorDevice), 209sensor_handle, info.bestBatchParams.batchDelay); 210} 211 } 212 213 214 void SensorDevice::disableAllSensors() { 215...... 216/* 逐个sensor disable */ 217for (size_t i = 0; i< mActivationCount.size(); ++i) { 218/* 获得一个sensor对应的info */ 219const Info& info = mActivationCount.valueAt(i); 220// Check if this sensor has been activated previously and disable it. 221if (info.batchParams.size() > 0) { 222/* 获得sensor类型 */ 223const int sensor_handle = mActivationCount.keyAt(i); 224...... 225/* 禁止该sensor */ 226mSensorDevice-> activate( 227reinterpret_cast< struct sensors_poll_device_t *> (mSensorDevice), 228sensor_handle, 0); 229// Add all the connections that were registered for this sensor to the disabled 230// clients list. 231/* 禁止所有注册了这个sensor的client */ 232for (size_t j = 0; j < info.batchParams.size(); ++j) { 233mDisabledClients.add(info.batchParams.keyAt(j)); 234} 235} 236} 237 } 238 239 240 status_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_event) { 241...... 242/* 增加一个sensor到mSensorDevice */ 243return mSensorDevice-> inject_sensor_data(mSensorDevice, injected_sensor_event); 244 } 245 246 247 status_t SensorDevice::setMode(uint32_t mode) { 248...... 249/* 操作模式设置 */ 250return mSensorModule-> set_operation_mode(mode); 251 } 252 253 int SensorDevice::Info::numActiveClients() { 254SensorDevice& device(SensorDevice::getInstance()); 255 256/* 检查batchParams容器中所有ident是否被disable 257* 返回未被disable(即active/enable)的个数 258*/ 259for (size_t i = 0; i < batchParams.size(); ++i) { 260/* 该ident未被disable */ 261if (!device.isClientDisabledLocked(batchParams.keyAt(i))) { 262++num; 263} 264} 265 266return num; 267 } 268 269 270 status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags, 271int64_t samplingPeriodNs, 272int64_t maxBatchReportLatencyNs) { 273 { 274/* 从容器中找到indent(key)对应的index */ 275ssize_t index = batchParams.indexOfKey(ident); 276...... 277/* 从容器中找到index索引对应的BatchParams 278* 修改该BatchParams的采样频率和事件上报 279* 最大延迟 280*/ 281BatchParams& params = batchParams.editValueAt(index); 282params.flags = flags; 283/* 设置采样频率 */ 284params.batchDelay = samplingPeriodNs; 285/* 事件上报最大延迟 */ 286params.batchTimeout = maxBatchReportLatencyNs; 287...... 288 } 289 290 291 void SensorDevice::Info::selectBatchParams() { 292BatchParams bestParams(0, -1, -1); 293SensorDevice& device(SensorDevice::getInstance()); 294/* 设置容器中所有未被disable(active/enable)的元素(ident)的值 */ 295for (size_t i = 0; i < batchParams.size(); ++i) { 296/* 如果该元素(ident)被disable,则继续查找下一个元素(ident) */ 297if (device.isClientDisabledLocked(batchParams.keyAt(i))) continue; 298/* 获得该索引对应的元素的value (batchParams)值 */ 299BatchParams params = batchParams.valueAt(i); 300if (bestParams.batchDelay == -1 || params.batchDelay < bestParams.batchDelay) { 301/* 如果最新设置采样频率的值小于上一次的,采用最新的值 */ 302bestParams.batchDelay = params.batchDelay; 303} 304if (bestParams.batchTimeout == -1 || params.batchTimeout < bestParams.batchTimeout) { 305/* 如果最新事件上报最大延迟的值小于上一次的,采用最新的值 */ 306bestParams.batchTimeout = params.batchTimeout; 307} 308} 309 310/* 311* 这些参数只能往小调 312*/ 313 314/* 保存到bestBatchParams */ 315bestBatchParams = bestParams; 316 }

    到这里,基本代码已经分析完了,简单总结一下这个文件主要做了什么工作:
1. 加载.so库,sensors_module_t结构体中获得相关参数
2. 在.so库的基础上,再一次封装activate,setDelay,pollEvents等方法,
    目的是为了支持更多的客户端(client)访问。如:struct Info结构体,
    每一个sensor都对应有这样一个结构体,该结构体中有两比较重要的成员
    是BatchParams bestBatchParams 和
    KeyedVector< void*, BatchParams> batchParams。每一个client对应着
    一个batchParams,每个client对应的都会传入一个参数到void *,与
    BatchParams关联,从BatchParams中选择合适的参数保存到bestBatchParams
    中。
3. 这个模块中在.so库的基础上增加了一些方法,但这里是连载前一篇博客
    http://www.cnblogs.com/hackfun/p/7327320.html, 在前一篇博客中没
    有实现一些flush,batch,inject_sensor_data的方法,因为
    struct sensors_poll_device_t结构体重没有提供这些方法,而
    struct sensors_poll_device_1结构体才提供这些方法,因此在下一篇
    关于sensor service的博客中暂且忽略这些方法是使用

    推荐阅读