Android应用开发之Android Framework SensorService 分析
凌雪 2018-10-24 来源 :网络 阅读 1688 评论 0

摘要:本文将带你了解Android应用开发之Android Framework SensorService 分析,希望本文对大家学Android有所帮助。

本文将带你了解Android应用开发之Android Framework SensorService 分析,希望本文对大家学Android有所帮助。


Android   Framework SensorService 分析
1 SensorService 的启动
1.1 SensorService:onFirsrRef()
SensorService 运行在 system_server 里边,在
android/frameworks/base/services/core/jni/com_android_server_SystemServer.cpp
通过实例化一个 SensorService   对象启动,如下:
?1234567891. static void   android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /*   clazz */){2. char propBuf[PROPERTY_VALUE_MAX];3.   property_get("system_init.startsensorservice", propBuf,   "1");4. if (strcmp(propBuf, "1") == 0) {5.   SensorService::instantiate();6. }7.8. }
SensorService 继承关系为:
   
    该 instantiate()方法为 BinderService 的方法,如下:
?12345671. static void instantiate() {   publish(); }2. static status_t publish(bool allowIsolated = false) {3.   sp<iservicemanager> sm(defaultServiceManager());4. return   sm->addService(5. String16(SERVICE::getServiceName()),6. new SERVICE(),   allowIsolated);7. }</iservicemanager>
   
    即 new 一个 SensorService 后向 ServiceManager 进行注册,
由于 SensorService 是 RefBase 的子类,
   
    . void RefBase::incStrong(const void* id)   const2. {3. weakref_impl* const refs = mRefs;4. refs->incWeak(id);5.6.   refs->addStrongRef(id);7. const int32_t c = refs->mStrong.fetch_add(1,   std::memory_order_relaxed);8. ALOG_ASSERT(c > 0, "incStrong() called   on %p after last strong ref", refs);9. #if PRINT_REFS10.   ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);11.   #endif12. if (c != INITIAL_STRONG_VALUE) {13. return;14. }15.16. int32_t old   = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE,17.   std::memory_order_relaxed);18. // A decStrong() must still happen after   us.19. ALOG_ASSERT(old > INITIAL_STRONG_VALUE, "0x%x too small",   old);20. refs->mBase->onFirstRef();21. }
会在类 RefBase 里边调用 SensorService 的 onFirstRef()方法,开始进行 SensorService 的初始化工作,(这个调用应该
是 Binder 的一个通用机制,通过重载该 onFirstRef()方法进行一个各自的初始化工作),
从 onFirstRef()开始启动,
SensorDevice&   dev(SensorDevice::getInstance());
//这边取得 SensorDevice 实例,to do1:Sensordevice 类是什麽、用来做什么的后面分析,
1. ssize_t count =   dev.getSensorList(&list);2. for (ssize_t i=0 ; i<count   10.="" 11.="" 12.="" 13.=""   14.="" 15.="" 16.="" 17.=""   18.="" 19.="" 20.="" 21.=""   22.="" 23.="" 24.="" 25.=""   26.="" 27.="" 28.="" 29.=""   3.="" 30.="" 31.="" 32.=""   33.="" 34.="" 5.="" 6.=""   7.="" 8.="" 9.="" bool=""   case="" else="" hasaccel="true;"   hasgyro="true;" hasmag="true;" if="" new=""   orientationindex="i;" pre=""   sensor_type_accelerometer:=""   sensor_type_game_rotation_vector:=""   sensor_type_geomagnetic_rotation_vector:=""   sensor_type_gravity:="" sensor_type_gyroscope:=""   sensor_type_gyroscope_uncalibrated:=""   sensor_type_linear_acceleration:=""   sensor_type_magnetic_field:=""   sensor_type_orientation:=""   sensor_type_rotation_vector:="" switch="" usethissensor="true;"   virtualsensorsneeds="">遍历 sensorlist ,创建里边每个 sensor 成员对应的一个 HardwareSensor 放到 sensorservice 层的 sensorList,to do2:<p>HardwareSensor   类是什麽、用来干嘛的后面分析,</p><pre   class="brush:java;">1. if (hasGyro && hasAccel   && hasMag) {2. // Add Android virtual sensors if they're not   already3. // available in the HAL4. bool needRotationVector =   (virtualSensorsNeeds & (1<<sensor_type_rotati 10.=""   11.="" 12.="" 13.="" 14.=""   15.="" 16.="" 17.="" 18.=""   19.="" 20.="" 21.="" 23.=""   24.="" 25.="" 26.="" 27.=""   29.="" 30.="" 5.="" 6.=""   7.="" 8.="" are="" bool=""   debugging="" for="" hasaccel="" if=""   needgamerotationvector="22." needgeomagrotation=""   needgeomagrotationvector="28."   needgravitysensor="(virtualSensorsNeeds"   needlinearacceleration="9." new="" not="" pre=""   sensor_type_gravity="" sensors="" user=""   virtual="" virtualsensorsneeds=""><p>若有对应物理 sensor 能够支持的虚拟 sensor,注册虚拟 sensor,</p><pre   class="brush:java;">1. mLooper = new Looper(false);//ques1:这个 Looper 目前还不知到拿来干嘛2. mCurrentOperatingMode = NORMAL;3. mNextSensorRegIndex = 0;4.   for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {5.   mLastNSensorRegistrations.push();6. }7.8. mInitCheck = NO_ERROR;9. //创建一个 SensorEventAckReceiver 对象10. mAckReceiver = new   SensorEventAckReceiver(this);//把自己扔进去给对方的11. mAckReceiver->run("SensorEventAckReceiver",   PRIORITY_URGENT_DISPLAY);12. run("SensorService",   PRIORITY_URGENT_DISPLAY);//这边进入 threadLoop</pre>new 了几个对象后,调用 SensorEventAckReceiver:run()以及 SensorService:run(),进入它们各自实现其父类 Thread 的<br><p>threadLoop   方法里边,先看   SensorEventAckReceiver:threadLoop(),</p><pre   class="brush:java;">1. bool   SensorService::SensorEventAckReceiver::threadLoop() {2. ALOGD("new   thread SensorEventAckReceiver");3. sp<looper> looper =   mService->getLooper();//获取 SennsorService 的 mLooper4. do {5. bool wakeLockAcquired =   mService->isWakeLockAcquired();6. int timeout = -1;7. if   (wakeLockAcquired) timeout = 5000;8. int ret =   looper->pollOnce(timeout);9. if (ret == ALOOPER_POLL_TIMEOUT) {10.   mService->resetAllWakeLockRefCounts();11. }12. }   while(!Thread::exitPending());13. return false;14.   }</looper></pre>这边目前没有看见什么信息,主要是对 SensorService:onFirsrRef()里边创建的 mLooper 的<br>通过调用其 pollOnece()方法进行不断的等待、唤醒。<br><p>看   SensorService:threadLoop()</p><h3>1.2   SensorService:threadLoop()</h3><p>SensorDevice&   device(SensorDevice::getInstance());</p><p>首先获取一个 SensorDevice 实例,</p><pre   class="brush:java;">1. ssize_t count =   device.poll(mSensorEventBuffer, numEventMax);2. if (count < 0) {3.   ALOGE("sensor poll failed (%s)", strerror(-count));4. break;5. }6.   // Reset sensors_event_t.flags to zero for all events in the buffer.7. for   (int i = 0; i < count; i++) {8. mSensorEventBuffer[i].flags = 0;9.   }</pre>SensorDevice::poll() 大致是通过 hidl 调用   google-hal 的 poll 后,将 hal 层数据装到 sensors_event_t 类型的<br>mSensorEventBuffer 里边,返回可读取 event 的数目。其中 sensors_event_t 类型是在 hal 层定义的。<br>SensorService   主要是通过 SensorDevice 与 google-hal 的交互<br>接着看,<br><pre   class="brush:java;">1. // Make a copy of the connection vector   as some connections may be removed during the course2. // of this loop   (especially when one-shot sensor events are present in the sensor_event3. //   buffer). Promote all connections to StrongPointers before the lock is   acquired. If the4. // destructor of the sp gets called when the lock is   acquired, it may result in a deadlock5. // as ~SensorEventConnection() needs   to acquire mLock again for cleanup. So copy all the6. // strongPointers to a   vector before the lock is acquired.7. SortedVector<   sp<sensoreventconnection> > activeConnections;8.   populateActiveConnections(&activeConnections);</sensoreventconnection></pre><br><p>注释已经说了,就是将 mActiveConnections 做一份拷贝,拷贝到 activeConnections 里边,<br>继续看,</p><pre   class="brush:java;">1.  // handle virtual sensors2. if   (count && vcount) {3. sensors_event_t const * const event =   mSensorEventBuffer;4. if (!mActiveVirtualSensors.empty()) {5. size_t k = 0;6.   SensorFusion& fusion(SensorFusion::getInstance());//获取一个 SensorFusion7. if   (fusion.isEnabled()) {8. for (size_t i=0 ; i<size_t(count)   10.="" 11.="" 12.="" 13.=""   14.="" 9.="" :="" count=""   for="" handle="" i="0" if=""   int="" k="" minbuffersize=""   size_t="">= minBufferSize) {15. ALOGE("buffer too small to   hold all events: "16. "count=%zd, k=%zu, size=%zu",17. count,   k, minBufferSize);18. break;19. }20. sensors_event_t out;21. // 根据 handle 获取到在22. //SensorService::onFirstRef 里边注册的 SensorInterface23. sp<sensorinterface> si =   mSensors.getInterface(handle);24. if (si == nullptr) {25. ALOGE("handle   %d is not an valid virtual sensor", handle);26. continue;27. }28. //看看这边做了什么,估计是取数据后存数据29. //调用对应 SensorInterface 实例的 process 方法30. if (si->process(&out,   event[i])) {31. mSensorEventBuffer[count + k] = out;32. k++;33. }34. }35.   }36. if (k) {37. // record the last synthesized values38.   recordLastValueLocked(&mSensorEventBuffer[count], k);39. count += k;40.   // sort the buffer by time-stamps41. sortEventBuffer(mSensorEventBuffer,   count);42. }43. }44.   }</sensorinterface></size_t(count)></pre>那么,接下来,先回过头去将 onFirstRef 里边的<br><p>registerSensor(   new HardwareSensor(list[i]) );</p><pre   class="brush:java;">1. const Sensor&   SensorService::registerSensor(SensorInterface* s, bool isDebug, bool   isVirtual) {2. int handle = s->getSensor().getHandle();3. int type =   s->getSensor().getType();4. if (mSensors.add(handle, s, isDebug,   isVirtual)){5. mRecentEvent.emplace(handle, new RecentEventLogger(type));6.   return s->getSensor();7. } else {8. return mSensors.getNonSensor();9. }10.   }</pre>,将每个sensor_t类型的sensor初始化一个对应的HardwareSensor对象后和对应的handle一起放到mSensors里边,<br>这个 mSensor 对象为 SensorList 类型。<br>这样的话,前边<br><p>sp<sensorinterface> si =   mSensors.getInterface(handle);</sensorinterface></p>通过 handle 获取 SensorInterface,就是将前面装进去的 HardwareSensor 对象取出来,进而调用其 si->process(&out,<br>event[i])函数,那么看看 HardwareSensor 的 process()方法咯<br><pre class="brush:java;">1. bool   HardwareSensor::process(sensors_event_t* outEvent,2. const   sensors_event_t& event) {3. *outEvent = event;4. return true;5.   }</pre>,那么   event[i]呢,看看这东西是在哪儿被赋值的,为<pre   class="brush:java;">1. ssize_t count =   device.poll(mSensorEventBuffer, numEventMax);2. sensors_event_t const * const   event = mSensorEventBuffer;</pre>mSensorEventBuffer 就是在前边通过 device.poll 获取 hal 层的数据的嘛,是作为指针指向底层的一个数组的,再传给<br>event,event再转给这边的out,饶了一大圈,原来只不过si->process(&out,   event[i])是 将hal层的各个sensors_event_t<br>的 sensor 内容装到 out 里边。<br><p>继续看 SensorService:threadLoop()方法,</p><pre   class="brush:java;">1. if (si->process(&out, event[i]))   {2. mSensorEventBuffer[count + k] = out;3. k++;4. }</pre><p>又把 out 装到 mSensorEventBuffer 的空余的下一个单元</p><p>,</p><pre   class="brush:java;">1. // Send our events to clients. Check the   state of wake lock for each client and release the2. // lock if none of the   clients need it.3. bool needsWakeLock = false;4. size_t numConnections =   activeConnections.size();5. for (size_t i=0 ; i < numConnections; ++i) {6.   if (activeConnections[i] != 0) {7.   activeConnections[i]->sendEvents(mSensorEventBuffer, count,8.   mSensorEventScratch,mMapFlushEventsToConnections);9. needsWakeLock |=   activeConnections[i]->needsWakeLock();10. // If the connection has   one-shot sensors, it may be cleaned up after first trigger.11. // Early check   for one-shot sensors.12. if (activeConnections[i]->hasOneShotSensors())   {13. cleanupAutoDisabledSensorLocked(activeConnections[i],14.   mSensorEventBuffer,count);15. }16. }17. }</pre>通过   activeConnections[i]->sendEvents() 将数据发送出去,然后继续循环,<br>ssize_t size =   SensorEventQueue::write(mChannel,<br>reinterpret_cast(scratch),   count);<br>这边发送的话最后是通过一个通过 unix socket 发出去的,<br>这边接收的就不分析了,估计是 SensorManager 读取到数据后给应用,取数据的方式设计思想应该和这边与 hal 层<br>交互一样,留到后面分析 SensorManager 再分析。<br>小总结一下,SensorService 通过 SensorService::onFirstRef() 执行一些初始化后,就在   SensorService::threadLoop()里<br><p>边不断通过 poll 从   hal 层取数据然后通过 unix   socket 发送出去.</p><h2>2   主要类分析</h2><h3>2.1   SensorList 类</h3><p>里边的 mHandleMap 成员为 map 类型,主要是用来装 SensorInterface 和 handle 的,</p><p><img   style="width: 630px; height: 127.729px;" alt="\"   src="/uploadfile/Collfiles/20180510/20180510092639772.png"></p><p>对于 SensorService::registerSensor()方法,注册一个 sensor,也就是将<br>从 google-hal 层获取到的 sensor_t 初始化一个 HardwareSensor 对象后,将其与其对应的 handle 添加进一个 map 里</p><p>边.</p><pre class="brush:java;">1. const   Sensor& SensorService::registerSensor(SensorInterface* s, bool isDebug,   bool isVirtual) {2. int handle = s->getSensor().getHandle();3. int type =   s->getSensor().getType();4. if (mSensors.add(handle, s, isDebug,   isVirtual)){5. mRecentEvent.emplace(handle, new RecentEventLogger(type));6.   return s->getSensor();7. } else {8. return mSensors.getNonSensor();9. }10.   }11.12. mSensors 为   SensorList 类型,看其 add()方法,13. bool SensorList::add(14. int   handle, SensorInterface* si, bool isForDebug, bool isVirtual) {15.   std::lock_guard<std::mutex> lk(mLock);16. if (handle ==   si->getSensor().getHandle() &&17.   mUsedHandle.insert(handle).second) {18. // will succeed as the mUsedHandle   does not have this handle19. mHandleMap.emplace(handle, Entry(si, isForDebug,   isVirtual));20. return true;21. }22. // handle exist already or handle   mismatch23. return false;24. }</std::mutex></pre>用 si 初始化一个匿名 Entry 类型后,与 handle 一起添加进 mHandleMap<br><h3>2.2   sensors_event_t</h3><p>由 google-hal 定义在/android/hardware/libhardware/include/hardware/sensors.h 里边</p><p><img   style="width: 238px; height: 68px;" alt="\"   src="/uploadfile/Collfiles/20180510/20180510092639773.png"></p><h3>2.3   SensorEventConnection</h3><p><img style="width: 630px;   height: 260.588px;" alt="\"   src="/uploadfile/Collfiles/20180510/20180510092639774.png"></p><h2>3   遗留问题分析</h2><p>/************************************************/<br>to   do1:Sensordevice 类是什麽、用来做什么的后面分析,<br>to do2:harwareSensor 类是什麽、用来干嘛的后面分析,<br>好了,接下来对前面遗留的疑问做个分析,<br>3.1 to do1:SensorDevice 类 是什麽、 用来做什么 的<br>ans:SensorDevice 主要是获取到 hal 层的对象   sp mSensors 后,利用<br>mSensors   通过 hidl 机制调用 hal 层的方法。<br>该   ISensors 类型定义在   android/hardware/interfaces/sensors/1.0/ISensors.hal<br>SensorDevice 类<br>SensorDevice 继承了   BinderService<sensorservice>,BnSensorServer,Thread<br>先看构造函数</sensorservice></android::hardware::sensors::v1_0::isensors></p><pre   class="brush:java;">1. SensorDevice::SensorDevice() :   mHidlTransportErrors(20) {2. if (!connectHidlService()) {3. return;4. }5.6.   float minPowerMa = 0.001; // 1 microAmp7.8.   checkReturn(mSensors->getSensorsList(9. [&](const auto &list) {10.   const size_t count = list.size();11.12.   mActivationCount.setCapacity(count);13. Info model;14. for (size_t i=0 ; i   < count; i++) {15. sensor_t sensor;16. convertToSensor(list[i],   &sensor);17. // Sanity check and clamp power if it is 0 (or close)18. if   (sensor.power < minPowerMa) {19. ALOGE("Reported power %f not deemed   sane, clamping to %f",20. sensor.power, minPowerMa);21. sensor.power =   minPowerMa;22. }23. mSensorList.push_back(sensor);24.25.   mActivationCount.add(list[i].sensorHandle, model);26.27.   checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* enabled */));28.   }29. }));30.31. mIsDirectReportSupported =32. (checkReturn(mSensors->unregisterDirectChannel(-1))   != Result::INVALID_OPERATION);33. }</pre>对于变量类型 sensor_t,sensor_t   是在 google-hal 里边定义的,<br><p>路径:   android/hardware/libhardware/include/hardware/sensors.h</p><p><img   style="width: 238px; height: 156px;" alt="\"   src="/uploadfile/Collfiles/20180510/20180510092640775.png"></p><p>先调用 connectHidlService ()方法,在这里边通过 hidl 机制获取 mSensors,<br>mSensors =   ISensors::getService();<br>//获取 hal 层对象实例,这样的话接下来就能够通过该 mSensors 来调用 hal 层的服务了。<br>mSensors   类型为 sp mSensors,<br>接着通过 mSensors(sp   mSensors)调用 hal 层的 getSensorsList,然后通<br>过 convertToSensor(list[i],   &sensor)获取 sensor 后装进 mSensorList 里边;<br>这边获取到 hal 层的 sensor 为   sensor_t 类型,定义在<br>android/hardware/libhardware/include/hardware/sensors.h<br>里边,</android::hardware::sensors::v1_0::isensors></android::hardware::sensors::v1_0::isensors></p><p>一句话概括构造函数,就是: 通过 connectHidlService ()与 hal 层建立联系后获取 hal 层的   SensorList</p><h3>3.2 to do2: harwareSensor 类 是什麽、用来干嘛的</h3>要分析 HardwareSensor 类,首先要去分析<br>dev.getSensorList(&list)<br>以及变量类型 sensor_t,<br>那就要先分析 SensorDevice 了<br>通过 dev.getSensorList(&list)获取到的 hal 层的   sensor_t 的变量,用来初始化   HardwareSensor 对象,其实就是对其父<br>类 BaseSensor 的 mSensor(Sensor mSensor)成员进行初始化,该 Sensor 类我目前估计就是 framework 层的 Sensor<br>类通用表示了,定义在 frameworks/native/libs/sensor/include/sensor 里边,也就是将 hal 层获取到的 sensor_t 类型<br>变量转换层 framework 层的 Sensor 类型变量。</asensorevent></sensor_type_rotati><br></pre></count>    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!

本文由 @凌雪 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved