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 系统框架 的主要内容,如果未能解决你的问题,请参考以下文章

Android Sensor软件架构分析

Android 片段和依赖注入

Android片段和依赖注入

如何使用Android片段管理器传递变量[重复]

以编程方式将片段添加到android中的框架布局

获取Android设备的方向,Sensor和SensorManager实现手机旋转角度