传感器SensorService详细分析_第1页
传感器SensorService详细分析_第2页
传感器SensorService详细分析_第3页
传感器SensorService详细分析_第4页
传感器SensorService详细分析_第5页
已阅读5页,还剩12页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、SensorService相关架构和流程指导1.整体架构ZPf*UCAT10NS,Applica'ionAPPUCAnOHFRAMEWOftK|SensorManagerVenwrJNiLIBRARIESSerTOrMsnijerl*inputSub3YmmEvant&ev5e?nsFrIALApplications层是使用传感器实现各种功能的具体应用程序,用来接收Sensor返回的数据,并处理实现对应的UI效果和特定功能,比如翻转静音、体感通话等功能。Framework层为应用层提供registerunRegister等接口,同时通过JNI建立与Native层的联系,主要代码

2、有SensorManager.jav4口SystemSensorManager.java另外,自动转屏、自动调节亮度、距离传感器控制亮屏和灭屏等功能也是在framework层实现。如果想用现有传感器通过算法合成其他传感器功能,也可以在本层添加,但由于不是Android原有接口,外部第三方APK无法使用。主要代码路径为:framework/base/core/java/android/hardware/framework/base/core/jni/android_hardware_SensorManager.cppLibraries表示动态库,它封装了整个Sensor的IPC机制,如Senso

3、rManager是客户端,SensorService是服务端,而HAL部分是封装了服务端对Kernel的直接访问。主要代码路径为:framework/native/libs/gui(生成libgui.so)framework/native/services/sensorservice生成libsensorservice.so)hardware/qcom/sensor减hardware/hisense/sensors生成sensor.xxx.so)驱动注册到Kernel的InputSubsystem上,然后通过EventDevice把Sensor数据传到HAL层,准确说是HAL从Event读。硬

4、件挂在I2C总线上。2. 类图SensorClassDiagram.jpgSensor框架分为三个层次,客户度、服务端、HAL层,服务端负责从HAL读取数据,并将数据写到管道中,客户端通过管道读取服务端数据。客户端主要类SensorManager.java从android4.1开始,SensorManage儆定义为一个抽象类,定义了一些主要的方法,该类是应用层直接使用的类,提供给应用层的接口。SystemSensorManager.java继承于SensorManager.java,是客户端消息处理的实体,应用程序调用getSystemService(Context.SENSOR_SERVIC

5、E)方法获取SensorService时,实际上获取的就是SystemSensorManage的实例。SensorEventListener接口:用于注册监听的接口,应用层必须实现该接口,并重写接口的两个方法,实现对获取到的Sensor数据的处理。android_hardware_SensorManager.cpp提供在Java层和Native层之间通信的JNI接口。Receiverandroid_hardware_SensorManager.cpp勺内部类,保存了个指向SensorEventQueue的指针,利用消息队列监听服务端事件上报,可以将消息队列中获取的数据回调到Java层。Sens

6、orManager.cppsensor在Native层的客户端,负责与服务端SensorService.cppffi信SenorEventQueue.cpp消息队歹!J,保存了指向SensorEventConnection对象的指针,实现与SensorService之间的命令传输和数据读取。服务端主要类SensorService.cpp服务端数据处理中心SensorEventConnection:SensorService.cpp的内部类,从BnSensorEventConnection昧承来,实现接口ISensorEventConnection的些方法,ISensorEventConnect

7、ion在SensorEventQueu必保存一个指针,指向调用服务接口创建的SensorEventConnection寸象BitTube.cpp:在这个类中创建了管道,用于服务端与客户端读写数据SensorDevice负责与HAL进行通信,传递命令和数据。HAL层Sensor.hHgoogle为Sensor定义的Hal接口,单独提出去3. API调用流程当界面onResume(域者APP需要接收传感器数据的时候,应用层通过如下调用流程enable传感器,并指定接收到数据后的处理。jn5eE.3orMar.aqai=fnsorManager)cantent.g=15yaten?ervieb(Co

8、ntext.SENSCRSERVICE);醯口=2。二=g片工工,got火片匚二二二七0n。!;,匚口才;if(jnensor!=hull)1工卜6口口口号二i二egint9二二igtenv工(工Smkhq工二口:工j濡片nn口:1ra?47£);F其中mSensorEventListener是实现SensorEventListener接口的子类对象,在该子类中必须重写onSensorChange()和onAccuracyChanged(),对驱动上报的传感器数据进行处理。这两个方法的实现可以为空,表示对收到的数据不做任何处理。publiciirterfaceSensoizEvent

9、Listenerpublicoid(SensoxE?entevrent);publicvoidonAccuizaGyChaaged(Sensorsensortintaccuracy);当界面切到后台或不再需要接收传感器数据时,通过调用以下方法停止接收数据,并尝试将该Sensor关闭。inSensoxMansger.unrsgisterListener(mSensorEventxistener);4. SensorServicOfl动应用层通过getSystemService(获取注册到ServiceManager中的系统服务,SENSOR_SERVICE返回白是SystemSensorMana

10、ge类的对象,该类最终会通过Binder方式连接到Native层的SensorService旧但kEincerAi>/£h,也旧-*k«ca.lBrr-ds1).tox;7*0:*mwoj:)gid36"f-11r就46奠就必ABll归Rwcf寸。田0耳.:Ed+dinsatf&ngAlz&nFiplE二va。干心礼bsIStwngR-Kiwild40MJUfA'c:业郎gidIIHTffiFATFIWitrrfM“W二日例轲-二口力*>0:1口。voe+el£"E:i313rLoL".edSens

11、orService.cpp勺继承关系如上图所示,它的直接父类是BnSensorServerBinderService和Thread,SensorManager.cppffi过Binder机制与SensorService.cpp进行通信。SensorService的启动调用流程如下。SystBiriServerc口m_and口id_seweSu3tBmSetveSensorSefwice1*:1一呼):;<-1;:nativelnit_、,:、一I-sensorinitI:<instantiate2instantiate。方法是SensorService从BinderService类

12、中继承的,具体实现如下图所示,该方法实际上就是生成了一个SensorService对象,并将其添加到ServiceManager中。public;子t&tvoid()publish(;staticstatu3_tpidbliah(boolallowlsolared=false)ap<r3erviGeMaDager>am(defaultServiceManager()>rst.umsttk->add£arvi_ce(吕tuingl6(SERVICE:getServiceWame(J),newSERVICE(),a_HowTa&lateci);从a

13、ddService的函数声明可以看出,第二个参数是对newSensorService(对象的强引用,因此当第一次构建sp强引用计数时,会调用SensorService:onFirstRef()函数。virtualstatus_taddService(conatStringl6&name,uona七曰p(工目J-IlTe工seizvj_cefboolallowlsolated=false)-=onFirstRef()函数主要完成以下工作:初始化SensorDevicq获取HAL层传感器列表,根据支持的HardwareSensor初始化VirtualSensor列表,最终形成可支持的完整传

14、感器列表;调用run()函数启动线程。SensorDevice是一个单实例类,当调用getInstance(时,创建对象的工作由其父类Singleton<SensorDevice优成。SensorDevice的构造函数中首先加载HAL的库文件,并创建SensorModule的对象。加载库文件时会依次获取"ro.hardware.sensors:"ro.hardware","duct.board","ro.board.platform","ro.arch”对应的属性值,然后分别在vendor/lib

15、/hw和system/lib/hw下查找名为sensors.xxx.so的库文件(xxx为属性值),如果这些文件都找不到,则查找sensors.default.so按此顺序最先找到的库文件会最终被加载。21HDR313_SIKGLET0M_5TXTIC_INST7k>ICE(ScEnoxOevicc);iSenssrDevice(>inJEiLacrEevicr-_)rei:acxEdadule)fscavnsterr=nw_qe_iuo3uie(5EN5aR5_ARwAKE_MCDUL.E_iDP(hw_niDiuie_t;const*!inseEorMoa3ie:if(nSen

16、aorM3d'jle)err导EnmoF3_c)0en_1t&n5enm灯工lModiiilE->comcin.ftmSensoiDevie®)?ifir:S金门尊srD*v1之m)(if(fnSorD&V3L->anmcK.vesian=SENSOaS_DEVICE_2LPIJZERSICiK_l_l|3iSensazr,ev3-cB->coirzicTLavers±.oz.=£ENSORSDEVICEZlPTTRSIGKJL2)A1OSEr>>»a!ANZNG<«Upgradese

17、nsorHALtcveirsion二Sr,1;Jscnssr_tcoirat*lint;531zs_iGouxit=5en3axHcdule->get_3eri3ax3_Li31iLSenaorModulef;xiAct>3/6c二aoCcunt«3±i>Capaci&Y()=mat);IjflXQnulel;lor(3ize_ti=j;i<size_t(count|:i+)3flA*11vat;-aani±iscix.najiaieFrooael);zlSensarDevics->actzvate(reinterpretca

18、st<=:rctsensor3_r01ldevi*XnSens3r3evice)rlist1,handle,)")如果加载成功会调用sensors_open_1()S数去打开传感器设备,该函数的最终实现是在multihal.cpp或者sensors.cpp的open_sensors(加。接着通过get_sensors_list®数获取NativeSensorManager中的传感器歹U表,并依次将列表中的传感器置为非活跃状态。SensorDevice的初始化工作完成后,SensorService的构造函数会获取HAL层的传感器列表,并将列表中的传感器逐个进行注册。其中

19、mSensorList用于保存SensorService中支持的全部传感器列表,mSensorMap中保存SensorHandle与Sensor对象指针白勺映射,mLastEventSeen保存SensorHandle与SensorEvent的映射,每接收到一次传感器事件,就会将对应的event更新一次。SenserSensorService:regiJi:eiSensor(Sensarlnt&rfa.ce*s)(Bensorseventtevent;mertsecSevenrt一,sizeof(evenL)j;凸工m世立白白士f且一内世七§世九自©7t):/add

20、tothegensoTlist(Tevumed.toclients'mSensorLisu.add(sensor):/addroourhandla->SenaorInuerfac&iLappingmSensorHap-add(sensQT«-tH4ndle()t;/creaceanentryintheitLasL£ven.u5eenarr4ylaLasEventSeen.add(senscu.getHandle(JTevent);=已七口rnsensoi;注册完从HAL层获取的传感器列表后,根据是否支持陀螺仪,将旋转矢量、重力、线性加速度、方向传感器注

21、册到VirtualSensor。除了会将这些虚拟传感器类型添加到上面的三个集合外,还需要添加到mVirtualSensorList中。最终,mSensorList中就保存了包含HardwareSenso洋口VirtualSensor在内的,系统所能支持的全部传感器类型,SensorSensorSerj-ce:registerVutLualSensciT(SensozrTnteiface*aSensorsensor-registerSensor(m,;itiVirenalSensorList.add(s);returnmensarr1onFirstRef()函数最后调用run()函数来启动thr

22、eadLooper()。threadLooper函数的核心功能就是不断循环等待获取HAL层传过来的传感器事件,对事件进行处理后分发给客户端。33izetcaujir=devlca.pollCir5ensarEvenrBLiffer,nurrEventHax);/ResetsensorseTr&ntt.flags七0zero/forallETrentffLnthebuffer«for(inti=:L<count;L+>(irSerLserEvent-Suf£erj_J.flags=;n循环体中首先通过device.poll()方法等待HAL层数据,数据到来

23、后读取到mSensorEventBuffer中。该方法的最终实现在sensor_poll_context_t:pollEvents()方法中。SortedVector<sp<Ssn3orEvtnTConnection>>activeCennecriona;(Hutex:支atci工cick_1(niock;for(sizeti=:i<mActiveConnections.size(J:+i)spOensorEventConection>connection(mActiveConneecionsipromote();if(connection!=)aGTiiv

24、eConrLeGtions.addtconnecElon);Jn然后对当前所有的ActiveConnections做一个备份,并保存到有序Vector中。这样做是因为在本次循环尚未执行完时,有可能其中的一些Connection就已经被移除了,特别是One-Shot类型的事件。接下来,如果poll到的事件中存在wake-upSensorEventM申请一个PARTIAL_WAKE_LOCK类型的锁,阻止CPU进入休眠。然后用mSensorEventBuffer中最新的事件更新registerSensor(时初始化的mLastEventSeen每个handle都只保留最新的一个事件。如果有虚拟传感

25、器被启用,则会将Buffer中的传感器事件先传到SensorFusion中做一些处理,然后调用具体的虚拟传感器融合生成一个新的事件添加到Buffer中。如果事件生成成功,则重新更新mLastEventSeen中对应虚拟传感器的最后一次event/handlevirtualsensars1t(countvcovnt)fsenBorseventtconst*constevent=mSensorEvetBuf£ex:caiist:sizeeacniveVrrcuaISensarCountitActiveVitLualSengors.size();if(activeViitualSen?or

26、Count)f与工工殳_七k-0;SenBarFiisiorLtfusion(SensorFiiBion::getlnstance0;if(fusion.isEnableci()>ffor(aize_t1=J;i<size_t(count);1+)(tisian.precess(eventi):I)for(sizeci"Ksizeccount&&KminBufferSize;1+)(for(size_Dj=;j<ac11veV±rzua1SensrCcunc;j+)i£(counc+k>=minBufferSize)(ALO

27、GE("buffertoesirlltaholdallevents:"ncaunc=%4,兔也工蔻”,coutyK.irinBufferSise);break.;jsen3ors_&vent_tout;SensorInterface*si-nActivaVirtualSensoza,va2ueAt(j>if(Bi->procefls(tour,event1)luSensQTEventBuffercount+kzj=0七;k+;ifm/recordEh&lastsynLhesizedvaluesrecoTdlasWaiue-ocked(tmSens

28、orEventBuffezcountJfK);count+-)c:/sortrh.fikiLifferbytirreStairpflaortEvcntBuf(mSensorEventafferfcont>|1)!1J最后,通过SensorEventConnection:sendEvents(方法将Buffer中的传感器事件传输到客户端。sendEvents函数会过滤出只属于该Connection的事件进行上报,具体处理在传感器事件获取一节再详细讨论。至此,SensorService的启动完成。当应用层调用getSystemService献取传感器服务时,就能够连接到Native层的Sen

29、sorService对传感器进行控制。getSystemService.jpg5. getDefaultSensor1TYPE_ACCELEROMETER14TYPE_MAGNETIC_FIELD_UNCALIBRATE2TYPE_MAGNETIC_FIELD15DYPE_GAME_ROTATION_VECTOR3TYPE_ORIENTATION16TYPE_GYROSCOPE_UNCALIBRATED4TYPE_GYROSCOPE17TYPE_SIGNIFICANT_MOTION5TYPE_LIGHT18TYPE_STEP_DETECTOR6TYPE_PRESSURE19TYPE_STEP_

30、COUNTER7TYPE_TEMPERATURE20TYPE_GEOMAGNETIC_ROTATION_VECT8TYPE_PROXIMITY21TYPE_HEART_RATE9TYPE_GRAVITY22TYPE_TILT_DETECTOR10TYPE_LINEAR_ACCELERATIO23TYPE_WAKE_GESTURE11NYPE_ROTATION_VECTOR24TYPE_GLANCE_GESTURE12TYPE_RELATIVE_HUMIDITY25TYPE_PICK_UP_GESTURE13TYPE_AMBIENT_TEMPERATU33171011TYPE_MOTION_AC

31、CLFRlmework层一共定义了26种传感器的整型常量,其中21至25是AndroidL新增的支持类型。应用层可以通过引用这些字符串获得对应的传感器对象。如果想获得这26种之外的传感器对象,可以通过在getDefaultSensor方法中直接传入该Sensor对应的type数值获取,但这种方法不便于应用层使用。最佳方案是在Sensor.java中添加整型常量,应用层只需要引用相应的常量名,而不需要关心具体的type数值。但Sensor.java必须确保定义的常量与所代表的传感器type值相对应,不能随便赋值publicsannszgotDofBiiltsmiar(int鼻yp*卜I/Z

32、9;ODO-!owedtobwtitr*f£llCWruxL£«tU££lthe*工工:耳七3力河口工1-getSenssrList(type_;bo&leanwalteUpgensor-falserfiftiTO-ganir已金.工¥PE_口口。乂工RIP¥IItype-floJiasr,I?¥PE_SIGN1FICANF_MOT1OtiI|ltype3>n»9r.TPE_TIL.r_D£TSCTORIIIItyp3»nB0Z.r¥PE_W2ULE_G*STU

33、RE|Itype=sensor.TYPELANEGEsrcRE|type.TYPE_prcK_UF_GE3TURE)wakeUtsflensor-true;JforScn.oornGnjrofe1)(If'口口K"上HiikDp3m工()<=,0)£*%口11110上|rMtuXKi>0.£;)returnnullgetDefaultSensor方法用于获取指定类型的传感器对象。如果存在多个相同类型的传感器,只返回列表中满足条件的第一个。getDefaultSensor(int)方法在5.0之前就一直存在,但AndroidL上对该方法的实现进行

34、了修改,增加了对wakeUpSensor类型的处理。TYPE_PROXIMITY、TYPE_SIGNIFICANT_MOTION、TYPE_TILT_DETECTOR、TYPE_WAKE_GESTURE、TYPE_GLANCE_GESTURE、TYPE_PICK_UP_GESTURE这六种类型应默认为wake-upSensor如果驱动侧没有为这六种传感器添力口wake-up标识(SENSOR_FLAG_WAKE_UP_SENSOR),或者为其他传感器添加了wake-up标识,通过getDefaultSensor(int)方法都无法返回该传感器对象。publicSensorgetDefaultS

35、enAor(inttypebooleanwakeUp)Li5t<SensQi>1=gatS曰七(type);foj?(Sensorsensor11)(if(sensorIsWakeUpSensar()wakeUp)retutnsn_3&i7T?etnni.mi11;getDefaultSensor(int,boolean是5.0上新增的方法,可用于获取指定type和wakeUp标识的传感器对象。比如8952上同时存在两种TYPE_PROXIMITY类型传感器,一个是可唤醒,一个不可唤醒。如果用getDefaultSensor(int)只能获取可唤醒的。但使用getDefau

36、ltSensor(int,false就可以获取到非唤醒类型的距离传感器对象。由于AndroidL之前的平台都只有getDefaultSensor(int酸口,为兼容以前的项目,应用层基本都是使用该方法获取指定类型传感器对象。为保证应用层能够正确获取到传感器对象,驱动在配置wakeUpSensor标识时应按照该方法指定的六种传感器实施。6. registerSensorListenerRegister.jpgRegister执行时主要有两大步骤:一是创建framework与SensorService之间的数据通道,通过newSensorEventQueue供现;二是将对应类型的传感器使能,通过a

37、ddSensor(发现。对于应用层而言,调用的API接口是SensorManager中白registerListener()方法,但SensorManagerH一个abstractClass,主要负责将API接口提供给应用层调用,SystemSensorManager是其子类,该类中提供了方法的具体实现。Swa1yhEwerLOu修uequ9UH-二3七门屈口工La4七二七工丛.gmL(上£$1&口也/|丁if(queuenull)Locpox1口叩口£=1=null)7handler«getzoopsf():nQ-uinLoop;qu9ue=SeozEv

38、«i31Quouw(1ist9nor,11gf*匚/this)jif(*曰口咱耳日口r小岭n尊口1rli1AylJafesixR三七门hReportLatiGCbyU霖#n/iprip1)Jqu号.diajzDse(retiurnfalse;oSensarLisZeners.put'(listenerrqueue);returnTrue:卜uIsq1|return.ssicLSensQXsenjB0rfdelayUstrri&xB&tchHjBportLatany*U9j.resarvecLFlags)/mSensorListeners是一个HashMap,保

39、存了SensorEventListener对象与SensorEventQueue寸象的对应关系。privatfr-,HasliMflrr"F*nLi.3Terr,ciescrEven-QijmRensorListeneranewHachM<sgheoievonrlitoner»scnEorEvortucnoX);|Register开始执行时首先从mSensorListeners中检查该listener是否之前已经注册过,如果已经注册过直接调用addSensor启用Sensor,否则先创建一个SensorEventQueue寸象,建立framework到Native的数

40、据传输管道,然后再启用传感器。因为同一个SensorEventListene对象中有可能会处理多种类型传感器的数据,所以同一个listener有可能会同多个Sensor进行绑定。Registerlistener时如果发现mSensorListener表中已经存在该listener对象,则直接调用addSensor方法检查listener本次绑定的Sensor是否已启用,如果已启用则结束本次操作,否则继续启用本次要绑定的Sensor,但不会创建新的数据管道。也就是说同一个listener可以被绑定到多种传感器上,但不可以被绑定到同一种类型的传感器上两次;一个Listener只能对应一个数据通道。

41、BaSEVCntQueLie二一l;仝=sLeSfcn=c.zM=n.=crmanaqer-frseitsorEventQueue=nativeInit.BaseEventQaeneft.hi3r1ooper.gettjueueJ,hiecratch);mCIdseGuard.、opsr-("dj_epose*");=managersSensorEventQueueHBaseEventQueuefl勺子类,在SensorEventQueuefl勺构造函数中会首先构造BaseEventQueue通过JNI调用将该BaseEventQueueX寸象与Native层进行关联,同时

42、SensorEventQueue寸象中也会保存一个对listener对象的引用。nativelnitSensorEventQueuestaticjlongHl3lttVCIHlIltSGlHSOTEV6HltQU6LlB£nv*eiwFjclassclazzfobjecteyent,L;ensorManagerngi:EensorKana5er:get;mstan-ref);sp<£enaorventQ_«u_ie>queue*(mgz.createEv1Q-e:()jJ与pQl目与巨aq号g口口曰>rw不匕39号Quiquo=/ndrgid口给

43、Mqf菱同号g9mnsgrO);1fnoessageUieue=NUL.Zj)jniTh.zcwRuntineExceptz_on(envP"XessageQueueisnotizi£t£a_ized,a8,1;returnOisp<flece:i¥6r>raceiver=newRecei.vex(ctlleuejzn诂mEagmOuBU仁,ewbuJL。#Eciratch)?receiver->znc51rng(void*)nat:±velnitserLSOTEventQueue);ret.uniijlongfreceivi

44、tr,get()j该方法首先调用SensorManager.cpp中的createEventQueue(儿建同SensorService之间的数据传输通道。sp<SensorEventQueue>SensorManager:CrCdt&EVCntQUCUC()sp<Sensoj:EventQi2eLie>queue;Mutex:Autolock_1(mLock);while(asser'tSta'teLocked()=NO_ERROR)sp<I£ensorEvent.Connec11n>connection=mSensQrS

45、erver->createSensorEvrentConnection();if(connection-NULL)continueyqueue=newSenserEventQueue(connectLon);break;retuirnqueueyImSensorServeiz1tISensorServer对象的强弓I用,在SensorManager初始化时通过getService()方法在ServiceManager中查找“sensorservice'对应的服务,并赋值给mSensorServer由第4小节可知,ServiceManager中返回的就是SensorService实

46、例。从SensorService的类图也能看出,SensorService是ISensorServer的子类。statusterr三getServicesmSensorServer);CreateSensorEventConnection()r法仓建了个SensorEventConnectioM象,并将该对象的强引用返回给SensorManagersor£ventConnection>SensorService:createSensorEventConnectlon(.uid_*u±d-IPCThre:ad£*a*e:self(->getCalling

47、Uicl()/sp<er:3arEvenCcnection>result(newBmnscrEn弓二七C白白匚1th二131ruid);returnreLLlt.;)SensorEventConnection是SensorService的内部类,该类在构造时主要进行了一些初始化参数列表工作,其中最主要的操作是newBitTube(),创建完成后,SensorEventConnection中会保存一个对BitTube对象的强引用。::三士仁二三.<=nt,zcnrll_ji.:.ScnsorEvontConnoctloriconstsp<Sensdr5ervice>

48、4service,"aidtnld.):(si*rvlc&)fmtJid(uid)rmBakeLkaefc_eiint(0)1rjnMaaLonperca1It:as(fala&)mDead(false)f血Ey电的tc31ch。INULI).mCacheSize(0),inHaxCacheSize(0)DEBUGCONNEC'ZIONSmEventsReere=mEvent:sSentFromCacihe=ieEsnts5enT=C;mTota1AcksNeeded=nfTotalAcksReceived=Or.工巫£BitTube是一个字节管道,

49、可以在进程间进行数据传递。在构造BiTube对象时,首先创建一对匿名的、互相连接的Unix域套接字,然后将用于数据接收的Socket赋给mReciveFd,将用于数据发送的Socket赋给mSensorFdvcici门i七七二be二:Inltlmf.hwtrCTFtiuffsizetsndbuf:intsccXets21,if(sccietpair(AF_JMIXr£OCK_SEQPACKET,J,sockets)=0)(sizetsize="DEFAULT_SOCKE.TBUFFER_SIZErsetscckapt(sockets0rSOLSOCKETfSO_RCVBUF

50、jfi:r-cvbu£rsizec£(rcvfcu£);setsCCkapt(sockstsL,SOL_SOCKET/SO_SNDBUh&吕ndbuf.sizeefsndbuf);/sinewedon'tusethe*relurnchannel",wekeepIt5mHlIsetaacJcapt(sseicfrta0JrSOL_SOCKETfSO_SMDBUFT£.si;Sdtsockcipt,(=,%iL=二rS0_R-2VBUF三-XTIt=_;fentlGckuL£0,F_5ETFL,C1_NOWBLOCKJ;f

51、cntlUckvtG1,F2SETFL,cTjgONBLOCKJ;v«Fd=Rackets0«rt5atidFd=t口广kf一k:1.elseiineft-ivgr1d=-errno;|ALOCE("'HitTijfcezpipecnestz.c.niled(%s)"fsrert&t(-tnReczeiviePcl);)现在SensorService中的这部分工彳已经完成,mSensorEventConnection中保存了对BitTube对象的强引用,SensorManage保存了对mSensorEventConnection的强引用。

52、接着SensorManager将mSensorEventConnection作为参数构造SensorEventQueue寸象。coD.nec:tion1ZLConsuzsed-3),EsnaorEvent,二;SIlSOrEVOHltQlLlGUcnstsp<ISenseZvenLCor-r.ec11.n>i:m3ezisorEventCocinesticnconnectionoiFLecBu±-&r(5JUL1L)rmAvaiLa±)1e(0rmMuniAcksT02and(0)(jnRecBuEfaiE.nmrAS.ru"XHnrbMAXJ

53、RmXVE_B|jFirOEVEN_COUNTfSensorEventQueue勺构造函数中主要工作是初始化mRecBuffer数组,其中ASensorEven毋构体定义与hardware/sensors.曲sensors_event_构体完全致。由于SensorManager中生成的是SensorEventQueue的强弓I用,onFirstRef()函数会被调用。该函数的执行结果就是得到了mSensorEventConnection中保存的mBitTube对象引用。voidSensorEventQueue:OF1FlfStRof()(mSensorChannel=mS&nsorEv

54、entConTiection->getSensorChannel();由止匕,createSensorEventQueue(p数执行完成后,mSensorEventConnection中保存了mBitTube的弓I用,mSensorEventQueu#保存了mSensorEventConnection和mBitTube的引用。再返回到JNI部分,现在nativeInitSensorEventQueue中获得了mSensorEventQueue对象的引用,然后通过调用android_os_MessageQueue_getMessageQueue()i|J4vMessageQueue对象的弓

55、I用,利J用mSensorEventQueuef口mMessageQueue以及Java层SensorEventQueue对象来构造Receiver类实例。Receiver负责监听服务端事件,并将事件回调给Java层SensorEventQueue进行分发。事件监听的文件描述符及回调接口在onFirstRef函数中指定。mSensorQueue->getFd阱返回的是mBitTube中的mReceiveFd,this指定了监听到事件时的回调对象,当消息队列监听到mReceiveFd中有事件产生时,就会回调this->handleEvent()方法对事件进行处理。virtualvoi

56、donFirstRef()LoopsrCallback:onFirstRef();mMessageQueu.e->gGtLooper()->acdFd.(mSensorQueue->getFd()T0,ALOOPER_EVENT_IUPUTrthis,mSensorQueue,get();handleEvent函数会对数据进行分类,最后回调Java层SensorEventQueue的dispatchSensorEvenVJ法把数据分发到对应的SensorEventListenerX寸象进行处理。至止匕,第步newSensorEventQueue笳成。第二步调用addSenso

57、r(方法启用传感器。首先从mActiveSensors中检查该传感器是否已激活,如果已激活则返回false。但是,mActiveSensors是BaseEventQueue的成员变量,不是SystemSensorManager的全局变量,每一个BaseEventQueue对象者B对应一个mActiveSensors考虑到一个BaseEventQueue只能对应一个SensorEventListener所以除非是mListener和Sensor对象都相同才会返回false,否则不管是同一种传感器注册了另一个Listener对象,还是同一个Listener注册到另一种传感器上,都会继续执行enab

58、leSensorpufc-icboo-Lea-n3CldSnS0r1Sensorseriso;r,lr.Tde1ayusrintmajEHat,<zhRepQ:r±LMtlErLcyLr;SFintrv&df1aqg)(/CheckIfalreadypresentinthandle-sensor.getHandle()f1f(mA上tiveSe-'insara,(hand1*)-)r*turnfalse-;/Getreadytareceivseventsbeforecallingefi日bl?.niAGtivsSensors-putChanals.rtrus)与

59、ad.dLSeEiS'CxfeuVeiit(sensox;11(9.iLaDleSsn£«LIseniorfdldiyU£fLcULBdLaliRjJOXLLaLemayUs,vu:dJFlag&)1-J)T/Tiycontinuousrncdeifbatchingfalls.If(rnjiBatclilteportLatenuyVs"OilrmkmatchReportLatiencyun>0&&&TLableensorsensor,dftlByusf0fD)!«0)reraovesenaor(Bennr,falsa)?retujmxalse;i工旧tutil匕enableSensor(途调用JNI层的nativeEnableSensor()S数,然后依次调用SensorEventQueue->SensorEventConnection中

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论