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