1. 程式人生 > >Android sensor 系統框架 (二)

Android sensor 系統框架 (二)

port amp cap 錯誤 str 註釋 hardware war cas

連載上一篇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 系統框架 (二)