MyException - 我的异常网
当前位置:我的异常网» Android » Android sensor 系统框架 (2)

Android sensor 系统框架 (2)

www.MyException.Cn  网友分享于:2013-08-16  浏览:0次
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的博客中暂且忽略这些方法是使用

文章评论

总结2014中国互联网十大段子
总结2014中国互联网十大段子
程序员和编码员之间的区别
程序员和编码员之间的区别
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
程序员应该关注的一些事儿
程序员应该关注的一些事儿
为什么程序员都是夜猫子
为什么程序员都是夜猫子
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
鲜为人知的编程真相
鲜为人知的编程真相
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
编程语言是女人
编程语言是女人
代码女神横空出世
代码女神横空出世
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
Java程序员必看电影
Java程序员必看电影
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
漫画:程序员的工作
漫画:程序员的工作
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
旅行,写作,编程
旅行,写作,编程
我的丈夫是个程序员
我的丈夫是个程序员
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
10个调试和排错的小建议
10个调试和排错的小建议
我是如何打败拖延症的
我是如何打败拖延症的
中美印日四国程序员比较
中美印日四国程序员比较
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
如何成为一名黑客
如何成为一名黑客
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
 程序员的样子
程序员的样子
那些争议最大的编程观点
那些争议最大的编程观点
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
程序员都该阅读的书
程序员都该阅读的书
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
老程序员的下场
老程序员的下场
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
程序员的鄙视链
程序员的鄙视链
程序员必看的十大电影
程序员必看的十大电影
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有