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 maximum127  report latency. This function can be called while the sensor is128  activated, in which case it must not cause any sensor measurements to129  be lost: transitioning from one sampling rate to the other cannot cause130  lost events, nor can transitioning from a high maximum report latency to131  a low maximum report latency.132  See the Batching sensor results page for details:133 http://source.android.com/devices/sensors/batching.html134 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。即用于判断该客户端是否disable191 */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 disabled230 // 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是否被disable257  * 返回未被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索引对应的BatchParams278  * 修改该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的博客中暂且忽略这些方法是使用

相关文章