Native层。如果没有读取到事件,则继续下一次循环,知道读取到事件为止。
7.2 SensorEventConnection::sendEvents()
threadLoop中获取到HAL上报的数据后,会对数据进行判断和处理,然后通过SensorEventConnection::sendEvents()方法将数据通过对应的数据通道上报给应用层。
从下面的代码可以看出,数据会在当前所有活跃的Connection中都处理一遍,同时,如果connection中包含数据上报类型为One-Shot的传感器,则上报一次数据后,会将本数据通道自动停用。
虽然从代码看,数据在当前所有活跃的Connection中都处理了一次,但每个Connection只传递自己特定类型传感器的数据才是正解,而不是不管什么类型传感器的数据都传递一遍。
在SensorEventConnection对象中保存了一个Sensor Handle集合,标识了该Connection可以传递哪些类型传感器的数据。由第6节流程可知,在SensorService::enable()函数中,会调用mConnection->addSensor(handle)函数,将本次要enable的Sensor handle保存到Connection对象中。
在sendEvents()函数中,会将数据依次取出,获取其所属传感器的类型,如果有与本Connection中保存的Sensor handle类型相同的数据,则传递之;否则,不传递。由此可以确保每个Connection只传递指定类型Sensor数据。
如果有满足本mConnection数据传输要求的数据,则通过如下方法将数据写入到构造SensorEventConnection对象时创建的BitTube共享内存中。
BitTube中创建了一对匿名套接字,并将发送数据的socket赋值给mSendFd,将接收数据的Socket赋值给mReceiveFd。在JNI层,Receiver类中的MessageQueue添加了mReceiveFd为监听节点,SensorService中通过mSendFd将数据写入后,MessageQueue监听到有事件产生,会回调Receiver::handleEvent()函数。handleEvent()首先通过SensorEventQueue::read()函数从BitTube中读取ASensorEvent类型数据,每次最多读取16个。read()函数的实质就是Socket通信中的recv()函数,通过mReceiveFd读取数据。
当读取到数据后,handleEvent会按照传感器类型对数据进行简单处理,然后回调Java层BaseEventQueue类的dispatchSensorEvent方法。
BaseEventQueue的dispatchSensorEvent方法是一个abstract方法,具体实现是在BaseEventQueue的子类SensorEventQueue和TriggerEventQueue中。对于事件上报类型为OneShot的Sensor,register时会创建TriggerEventQueue,其他类型的创建SensorEventQueue。dispatchSensorEvent中的主要操作就是将JNI回调时传过来的数据转换成SensorEvent对象,然后通过mListener.onSensorChanged()将数据分发给应用层进行处理。
总结:一个SensorEventListener对象只能对应一个SensorEventQueue和一个SensorEventConnection,每个SensorEventConnection对象中都保存了一个Sensor handle列表,用于标识该数据通道允许传输的Sensor数据类型。如果一个SensorEventListener中同时对多种传感器数据进行处理,不会创建多个数据通道,只是将Sensor 添加到SensorEventConnection的Sensor handle列表中。
相关推荐: