Android sensor System Framework (II)

Posted by 4rxsid on Wed, 05 Jun 2019 22:53:22 +0200

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

Topics: Android less