Updated at http://www.cnblogs.com/hackfun/p/7327320.html
(D) How to load access. so Libraries
In the previous blog http://www.cnblogs.com/hackfun/p/7327320.html, know how to generate
A. so Library of HAL, where we will analyze how to load the HAL and how to re-encapsulate it for multi-client access.
In fact, the system finds the corresponding. so library through SENSORS_HARDWARE_MODULE_ID. Because in this library
The struct sensors_module_t structure contains a unique ID that is SENSORS_HARDWARE_MODULE_ID.
The ultimate goal is also to obtain this structure. By looking up the ID, we know that the set so is loaded in the following file.
The file path is:
frameworks/native/services/sensorservice/SensorDevice.cpp
Look at the code comments first, and then summarize.
SensorDevice.cpp
1 SensorDevice::SensorDevice() 2 : mSensorDevice(0), 3 mSensorModule(0) 4 { 5 /* Get the module (. so library) corresponding to SENSORS_HARDWARE_MODULE_ID */ 6 status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, 7 (hw_module_t const**)&mSensorModule); 8 ...... 9 /* Open module */ 10 err = sensors_open_1(&mSensorModule->common, &mSensorDevice); 11 ...... 12 /* How many sensor s are in this module list? */ 13 ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list); 14 ...... 15 /* Set container size */ 16 mActivationCount.setCapacity(count); 17 ...... 18 /* All sensors in the Activation/Enablation Module */ 19 for (size_t i=0 ; i<size_t(count) ; i++) { 20 /* Add sensor to container */ 21 mActivationCount.add(list[i].handle, model); 22 /* Activate/enable 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 /* Polling receives all events reported by sensors and fills in the buffer of sensors_event_t */ 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 /* Initialize info corresponding to handle (sensor type, such as ID_A) */ 45 status_t SensorDevice::activate(void* ident, int handle, int enabled); 46 ...... 47 if (enabled) { 48 /* If ident client does not exist */ 49 if (isClientDisabledLocked(ident)) { 50 return INVALID_OPERATION; 51 } 52 53 /* The client exists */ 54 if (info.batchParams.indexOfKey(ident) >= 0) { 55 /* Only one client, the first connected */ 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 Disabled */ 63 if (info.removeBatchParamsForIdent(ident) >= 0) { 64 /* If this is the last disable d client */ 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 /* If disable d, return directly */ 73 if (isClientDisabledLocked(ident)) { 74 return NO_ERROR; 75 } 76 } 77 78 /* If it's the first activation or the last disable sensor 79 * In this case, activate is invoked based on handle (sensor type) and enabled values 80 * To enable/disable the corresponding 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 /* Initialize info corresponding to handle (sensor type, such as ID_A) */ 92 Info& info(mActivationCount.editValueFor(handle)); 93 94 /* If this ident (key) does not exist */ 95 if (info.batchParams.indexOfKey(ident) < 0) { 96 BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs); 97 /* Add this (ident, params) (key-value) pair */ 98 info.batchParams.add(ident, params); 99 } else { 100 /* If it exists, update the 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 /* Find all minimum sampling frequencies and maximum event reporting latency for this sensor */ 107 // Find the minimum of all timeouts and batch_rates for this sensor. 108 info.selectBatchParams(); 109 110 /* If the minimum sampling frequency and maximum event reporting delay change relative to the previous one */ 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 On the role of mSensorDevice - > batch (SensorDevice::batch() based on its encapsulation of a layer, equivalent to his instance), 124 Relevant instructions are as follows: 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 This means that this is a set of parameters for each sensor, including sampling frequency, maximum event reporting delay, and this 136 Functions can be invoked when sensors are activated/enabled, in which case no sensor measurements can be made. 137 Loss of data, such as conversion from one sampling rate to another, does not result in loss of events, or from a maximum. 138 Conversion of reporting latency to another lower maximum reporting latency does not result in event loss. 139 140 That is to say, each sensor should have a batch, which is responsible for adjusting the sampling frequency and reporting the maximum. 141 The parameters of a piece delay, for example, can be adjusted once when the sensor is activated. 142 */ 143 144 status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) 145 { 146 ...... 147 Info& info( mActivationCount.editValueFor(handle)); 148 149 /* If the existing sensor does not work in continuous mode, setDelay() should return an error 150 * It's no use calling setDelay() in batch mode 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 /* Here's the continuous mode of sensor work */ 159 /* Get the corresponding index for this client */ 160 ssize_t index = info.batchParams.indexOfKey(ident); 161 /* Find the corresponding batchParams value based on this index */ 162 BatchParams& params = info.batchParams.editValueAt(index); 163 /* Set the batchDelay sampling frequency for this batchParams */ 164 params.batchDelay = samplingPeriodNs; 165 /* Save batchParams to bestBatchParams */ 166 info.selectBatchParams(); 167 /* In fact, sensors_poll_context_t::setDelay is called. */ 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 /* Brush data */ 176 return mSensorDevice->flush(mSensorDevice, handle); 177 } 178 179 180 bool SensorDevice::isClientDisabled(void* ident) { 181 /* Lock up */ 182 Mutex::Autolock _l(mLock); 183 /* Return to client status */ 184 return isClientDisabledLocked(ident); 185 } 186 187 188 bool SensorDevice::isClientDisabledLocked(void* ident) { 189 /* Get the index corresponding to ident (key-value pair). The index exists (>= 0) and returns true. 190 * Otherwise, return false. That is, it is used to determine whether the client is disable d or not. 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 /* Activate sensor_handle sensor */ 203 err = mSensorDevice->activate( 204 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), 205 sensor_handle, 1); 206 /* Setting the corresponding sampling frequency */ 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 one by one */ 217 for (size_t i = 0; i< mActivationCount.size(); ++i) { 218 /* Get an info corresponding to a sensor */ 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 /* Get the sensor type */ 223 const int sensor_handle = mActivationCount.keyAt(i); 224 ...... 225 /* Prohibit the 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 /* Prohibit all client s registered with this sensor */ 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 /* Add a sensor to mSensor Device */ 243 return mSensorDevice->inject_sensor_data(mSensorDevice, injected_sensor_event); 244 } 245 246 247 status_t SensorDevice::setMode(uint32_t mode) { 248 ...... 249 /* Operational mode settings */ 250 return mSensorModule->set_operation_mode(mode); 251 } 252 253 int SensorDevice::Info::numActiveClients() { 254 SensorDevice& device(SensorDevice::getInstance()); 255 256 /* Check that all ident s in the batchParams container are disable d 257 * Returns the number of non-disable d (i.e., active/enable) 258 */ 259 for (size_t i = 0; i < batchParams.size(); ++i) { 260 /* The ident ity is not disable d */ 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 /* Find the index corresponding to indent (key) from the container */ 275 ssize_t index = batchParams.indexOfKey(ident); 276 ...... 277 /* Find the BatchParams corresponding to the index index from the container 278 * Modify the BatchParams sampling frequency and event reporting 279 * Maximum delay 280 */ 281 BatchParams& params = batchParams.editValueAt(index); 282 params.flags = flags; 283 /* Setting Sampling Frequency */ 284 params.batchDelay = samplingPeriodNs; 285 /* Maximum Event Reporting Delay */ 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 /* Set the value of all elements (ident) in the container that are not disable d (active/enable) */ 295 for (size_t i = 0; i < batchParams.size(); ++i) { 296 /* If the element (ident) is disable d, continue looking for the next element (ident) */ 297 if (device.isClientDisabledLocked(batchParams.keyAt(i))) continue; 298 /* Get the value (batchParams) of the element corresponding to the index */ 299 BatchParams params = batchParams.valueAt(i); 300 if (bestParams.batchDelay == -1 || params.batchDelay < bestParams.batchDelay) { 301 /* If the value of the latest set sampling frequency is less than that of the previous one, the latest value is used. */ 302 bestParams.batchDelay = params.batchDelay; 303 } 304 if (bestParams.batchTimeout == -1 || params.batchTimeout < bestParams.batchTimeout) { 305 /* If the maximum latency for reporting the latest event is less than the last one, the latest value is used. */ 306 bestParams.batchTimeout = params.batchTimeout; 307 } 308 } 309 310 /* 311 * These parameters can only be minor 312 */ 313 314 /* Save to bestBatch Params */ 315 bestBatchParams = bestParams; 316 }
At this point, the basic code has been analyzed, a brief summary of the main work done in this document:
1. Loading the. so library and obtaining the relevant parameters in the sensor_module_t structure
2. On the basis of. so library, activate, setDelay and pollEvents are encapsulated again.
The aim is to support more client access. For example: struct Info structure,
Each sensor corresponds to a structure with two more important members.
Batch Params bestBatch Params and
KeyedVector < void*, BatchParams > batchParams. Each client corresponds to
A batchParams, with each client passing in a parameter to void*, and
BatchParams associations, save appropriate parameters from BatchParams to bestBatchParams
Middle.
3. This module adds some methods on the basis of. so library, but here is a serialization of the previous blog.
http://www.cnblogs.com/hackfun/p/7327320.html, not in the previous blog
There are some ways to implement flush, batch, inject_sensor_data, because
The struct sensors_poll_device_t structure weight does not provide these methods, and
The struct sensors_poll_device_1 structure provides these methods, so in the next article
Ignoring these methods in the sensor service Blog for the moment is to use