SensorService相关架构和流程指导1.整体架构Applications层是使用传感器实现各种功能的具体应用程序,用来接收Sensor返回的数据,并处理实现对应的UI效果和特定功能,比如翻转静音、体感通话等功能。Framework层为应用层提供register、unRegister等接口,同时通过JNI建立与Native层的联系,主要代码有SensorManager.java和SystemSensorManager.java。另外,自动转屏、自动调节亮度、距离传感器控制亮屏和灭屏等功能也是在framework层实现。如果想用现有传感器通过算法合成其他传感器功能,也可以在本层添加,但由于不是Android原有接口,外部第三方APK无法使用。主要代码路径为:framework/base/core/java/android/hardware/framework/base/core/jni/android_hardware_SensorManager.cppLibraries表示动态库,它封装了整个Sensor的IPC机制,如SensorManager是客户端,SensorService是服务端,而HAL部分是封装了服务端对Kernel的直接访问。主要代码路径为:framework/native/libs/gui(生成libgui.so)framework/native/services/sensorservice(生成libsensorservice.so)hardware/qcom/sensors或hardware/hisense/sensors(生成sensor.xxx.so)驱动注册到Kernel的InputSubsystem上,然后通过EventDevice把Sensor数据传到HAL层,准确说是HAL从Event读。硬件挂在I2C总线上。2.类图SensorClassDiagram.jpgSensor框架分为三个层次,客户度、服务端、HAL层,服务端负责从HAL读取数据,并将数据写到管道中,客户端通过管道读取服务端数据。客户端主要类SensorManager.java:从android4.1开始,SensorManager被定义为一个抽象类,定义了一些主要的方法,该类是应用层直接使用的类,提供给应用层的接口。SystemSensorManager.java:继承于SensorManager.java类,是客户端消息处理的实体,应用程序调用getSystemService(Context.SENSOR_SERVICE)方法获取SensorService时,实际上获取的就是SystemSensorManager的实例。SensorEventListener接口:用于注册监听的接口,应用层必须实现该接口,并重写接口的两个方法,实现对获取到的Sensor数据的处理。android_hardware_SensorManager.cpp:提供在Java层和Native层之间通信的JNI接口。Receiver:android_hardware_SensorManager.cpp的内部类,保存了一个指向SensorEventQueue的指针,利用消息队列监听服务端事件上报,可以将消息队列中获取的数据回调到Java层。SensorManager.cpp:sensor在Native层的客户端,负责与服务端SensorService.cpp通信SenorEventQueue.cpp:消息队列,保存了指向SensorEventConnection对象的指针,实现与SensorService之间的命令传输和数据读取。服务端主要类SensorService.cpp:服务端数据处理中心SensorEventConnection:SensorService.cpp的内部类,从BnSensorEventConnection继承来,实现接口ISensorEventConnection的一些方法,ISensorEventConnection在SensorEventQueue会保存一个指针,指向调用服务接口创建的SensorEventConnection对象BitTube.cpp:在这个类中创建了管道,用于服务端与客户端读写数据SensorDevice:负责与HAL进行通信,传递命令和数据。HAL层Sensor.h是google为Sensor定义的Hal接口,单独提出去3.API调用流程当界面onResume()或者APP需要接收传感器数据的时候,应用层通过如下调用流程enable传感器,并指定接收到数据后的处理。其中mSensorEventListener是实现SensorEventListener接口的子类对象,在该子类中必须重写onSensorChange()和onAccuracyChanged(),对驱动上报的传感器数据进行处理。这两个方法的实现可以为空,表示对收到的数据不做任何处理。当界面切到后台或不再需要接收传感器数据时,通过调用以下方法停止接收数据,并尝试将该Sensor关闭。4.SensorService启动应用层通过getSystemService()获取注册到ServiceManager中的系统服务,SENSOR_SERVICE返回的是SystemSensorManager类的对象,该类最终会通过Binder方式连接到Native层的SensorService。SensorService.cpp的继承关系如上图所示,它的直接父类是BnSensorServer,BinderService和Thread,SensorManager.cpp通过Binder机制与SensorService.cpp进行通信。SensorService的启动调用流程如下。instantiate()方法是SensorService从BinderService类中继承的,具体实现如下图所示,该方法实际上就是生成了一个SensorService对象,并将其添加到ServiceManager中。从addService的函数声明可以看出,第二个参数是对newSensorService()对象的强引用,因此当第一次构建sp强引用计数时,会调用SensorService::onFirstRef()函数。onFirstRef()函数主要完成以下工作:初始化SensorDevice;获取HAL层传感器列表,根据支持的HardwareSensor,初始化VirtualSensor列表,最终形成可支持的完整传感器列表;调用run()函数启动线程。SensorDevice是一个单实例类,当调用getInstance()时,创建对象的工作由其父类SingletonSensorDevice完成。SensorDevice的构造函数中首先加载HAL的库文件,并创建SensorModule的对象。加载库文件时会依次获取ro.hardware.sensors,ro.hardware,ro.product.board,ro.board.platform,ro.arch对应的属性值,然后分别在vendor/lib/hw和system/lib/hw下查找名为sensors.xxx.so的库文件(xxx为属性值),如果这些文件都找不到,则查找sensors.default.so。按此顺序最先找到的库文件会最终被加载。如果加载成功会调用sensors_open_1()函数去打开传感器设备,该函数的最终实现是在multihal.cpp或者sensors.cpp的open_sensors()中。接着通过get_sensors_list函数获取NativeSensorManager中的传感器列表,并依次将列表中的传感器置为非活跃状态。SensorDevice的初始化工作完成后,SensorService的构造函数会获取HAL层的传感器列表,并将列表中的传感器逐个进行注册。其中mSensorList用于保存SensorService中支持的全部传感器列表,mSensorMap中保存SensorHandle与Sensor对象指针的映射,mLastEventSeen保存SensorHandle与SensorEvent的映射,每接收到一次传感器事件,就会将对应的event更新一次。注册完从HAL层获取的传感器列表后,根据是否支持陀螺仪,将旋转矢量、重力、线性加速度、方向传感器注册到VirtualSensor。除了会将这些虚拟传感器类型添加到上面的三个集合外,还需要添加到mVirtualSensorList中。最终,mSensorList中就保存了包含HardwareSensor和VirtualSensor在内的,系统所能支持的全部传感器类型,onFirstRef()函数最后调用run()函数来启动threadLooper()。threadLooper函数的核心功能就是不断循环等待获取HAL层传过来的传感器事件,对事件进行处理后分发给客户端。循环体中首先通过device.poll()方法等待HAL层数据,数据到来后读取到mSensorEventBuffer中。该方法的最终实现在sensor_poll_context_t::pollEvents()方法中。然后对当前所有的ActiveConnections做一个备份,并保存到有序Vector中。这样做是因为在本次循环尚未执行完时,有可能其中的一些Connection就已经被移除了,特别是One-Shot类型的事件。接下来,如果poll到的事件中存在wake-upSensorEvent,则申请一个PARTIAL_WAKE_LOCK类型的锁,阻止CPU进入休眠。然后用mSensorEventBuffer中最新的事件更新registerSensor()时初始化的mLastEventSeen,每个handle都只保留最新的一个事件。如果有虚拟传感器被启用,则会将Buffer中的传感器事件先传到SensorFusion中做一些处理,然后调用具体的虚拟传感器融合生成一个新的事件添加到Buffer中。如果事件生成成功,则重新更新mLastEventSeen中对应虚拟传感器的最后一次event。最后,通过SensorEventConnection::sendEvents()方法将Buffer中的传感器事件传输到客户端。sendEvents函数会过滤出只属于该Connection的事件进行上报,具体处理在传感器事件获取一节再详细讨论。至此,SensorService的启动完成。当应用层调用getSystemService()获取传感器服务时,就能够连接到Native层的SensorService,对传感器进行控制。getSystemService.jpg5.getDefaultSensor1TYPE_ACCELEROMETER14TYPE_MAGNETIC_FIELD_UNCALIBRATED2TYPE_MAGNETIC_FIELD15TYPE_GAME_ROTATION_VECTOR3TYPE_ORIENTATION16TYPE_GYROSCOPE_UNCALIBRATED4TYPE_GYROSCOPE17TYPE_SIGNIFICANT_MOTION5TYPE_LIGHT18TYPE_STEP_DETECTOR6TYPE_PRESSURE19TYPE_STEP_COUNTER7TYPE_TEMPERATURE20TYPE_GEOMAGNETIC_ROTATION_VECTOR8TYPE_PROXIMITY21TYPE_HEART_RATE9TYPE_GRAVITY22TYPE_TILT_DETECTOR10TYPE_LINEAR_ACCELERATION23TYPE_WAKE_GESTURE11TYPE_ROTATION_VECTOR24TYPE_GLANCE_GESTURE12TYPE_RELATIVE_HUMIDITY25TYPE_PICK_UP_GESTURE1