1.前言

  1. 本篇文档主要分析安卓 Sensor框架Native层如何实现SensorEvent的分发,有何优秀设计点可以借鉴,有何缺点可以规避。下面是我分析的主要源码的路径:
语言 路径
Java frameworks/base/core/java/android/hardware/SystemSensorManager.java
C++ frameworks/base/core/jni/android_hardware_SensorManager.cpp
C++ hardware/libhardware/include/hardware/sensors.h
C++ hardware/libhardware/include/hardware/sensors-base.h
C++ frameworks/native/libs/sensor/*
C++ frameworks/native/services/sensorservice/SensorService.cpp
C++ frameworks/native/services/sensorservice/SensorEventConnenction.cpp

2.传感器堆栈

  1. 下图显示了Android传感器组件堆栈。各个组件仅可与其上方和下方紧邻的组件通信,控制信号从应用向下流向传感器,数据从传感器向上流向应用。<br />![ape_fwk_sensors.png](https://cdn.nlark.com/yuque/0/2020/png/505091/1606381353068-13b51429-8a0f-449a-abfa-d6a7ca70e706.png#align=left&display=inline&height=532&margin=%5Bobject%20Object%5D&name=ape_fwk_sensors.png&originHeight=532&originWidth=425&size=26543&status=done&style=none&width=425)<br />**图1**.Android 传感器堆栈层级以及各自的所有者

2.1 SDK

  1. 应用通过Sensor SDK API访问传感器。SDK包含列出可用传感器和注册监听传感器数据的函数。在注册到传感器时,应用可以指定自己的首选采样率和延迟要求。

2.2 Framework层

  1. Sensor Framework负责将多个应用关联到HALHAL本身是单一客户端。如果框架级别没有发生这种多路复用,则任何指定时间内每个传感器都只能被一个应用访问。
  • 当第一个应用注册到传感器时,框架会向HAL发送请求以激活传感器。
  • 当其他应用注册到相同的传感器时,框架会考虑每个应用的要求,并将更新的已请求参数发送到HAL。

1.采样率将是请求的采用率的最大值,这意味着一些应用接收事件的频率会高于所请求的频率
2.最大报告延迟将是请求的延迟的最小值。如果某个应用的最大报告延迟是0,若它请求传感器,则所有应用将以连续模 式从该传感器接收事件,即使某些应用请求传感器时的最大报告延迟不是0也是如此。

  • 当注册到某个传感器的最后一个应用取消注册后,框架会向HAL发送请求以停用该传感器,从而避免不必要的功耗。

    2.3HAL

    Sensors Hardware Abstraction Layer(HAL)API是硬件驱动程序和Android框架之间的接口。它包含一个HAL接口sensors.h(hardware/libhardware/include/hardware/sensors.h)和一个被称为sensors.cpp的HAL实现。
    接口由Android和AOSP贡献者定义,并由设备制造商提供实现。

    3.Native类的调用关系和启动流程

    3.1调用关系

    下图大致展示了Sensor框架各个主要类的调用关系:
    senser_framework_主要类调用关系.png

    3.2 启动流程

    Sensor框架在系统中主要分两条路线启动:
    一条是系统启动时,SensorService的启动,另一条是系统启动时SensorManager.java启动连带着SensorManager.cpp的启动:

    3.2.1 SensorService的启动

    SensorService是在system_server启动的时候,被system_server启动的,
    代码路径:frameworks/base/services/java/com/android/server/SystemServer.java ```java

private void startBootstrapServices() { //…… mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> { TimingsTraceLog traceLog = new TimingsTraceLog( SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER); traceLog.traceBegin(START_SENSOR_SERVICE); startSensorService();//调用JNI接口 traceLog.traceEnd(); }, START_SENSOR_SERVICE);

  1. //......

}

  1. startSensorService是一个JNI方法,其对应的C++实现如下:
  2. ```cpp
  3. /*
  4. * JNI registration.
  5. */
  6. static const JNINativeMethod gMethods[] = {
  7. /* name, signature, funcPtr */
  8. //这边先将该接口注册,后面给system_server调用
  9. { "startSensorService", "()V", (void*) android_server_SystemServer_startSensorService }
  10. { "startHidlServices", "()V", (void*) android_server_SystemServer_startHidlServices },
  11. };
  12. //在这儿创建sensorservice
  13. static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
  14. char propBuf[PROPERTY_VALUE_MAX];
  15. property_get("system_init.startsensorservice", propBuf, "1");
  16. if (strcmp(propBuf, "1") == 0) {
  17. SensorService::instantiate();
  18. }
  19. }

从上面源码看出,SensorService实例是通过调用SensorService::instantiate()方法创建的,此方法来源于SensorService的父类BinderService,所以实质上是调用BinderService::instantiate()来创建实例,而BinderService::instantiate()方法内部仅仅调用了BinderService::publish(),相关方法源码如下:

  1. //这边SERVICE为SensorService类型
  2. template<typename SERVICE>
  3. class BinderService
  4. {
  5. //......
  6. public:
  7. static status_t publish(bool allowIsolated = false,
  8. int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
  9. sp<IServiceManager> sm(defaultServiceManager());
  10. //创建SensorService实例并且添加到ServiceManage
  11. return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
  12. dumpFlags);
  13. }
  14. static void instantiate() { publish(); }
  15. //......
  16. };

看SensorService的构造函数,主要是创建了UidPolicy对象,此对象功能是管理待机sensor的行为:

  1. SensorService::SensorService()
  2. : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
  3. mWakeLockAcquired(false) {
  4. mUidPolicy = new UidPolicy(this);
  5. }

在BinderService::publish()函数中创建SensorService实例时,会调用onFirstRef()方法,这个方法里,首先创建并获取SensorDevice实例,获取vendor层注册的sensor数据,然后遍历每个sensor并将它们注册到SensorList里边,创建并运行一个SensorEventAckReceiver线程,再创建一个线程运行SensorService::threadLoop(),其代码如下:

  1. void SensorService::onFirstRef() {
  2. SensorDevice& dev(SensorDevice::getInstance());//创建并获取SensorDevice实例
  3. sHmacGlobalKeyIsValid = initializeHmacKey();
  4. if (dev.initCheck() == NO_ERROR) {
  5. sensor_t const* list;
  6. ssize_t count = dev.getSensorList(&list);//获取vendor层注册的sensor 数目
  7. if (count > 0) {
  8. ssize_t orientationIndex = -1;
  9. bool hasGyro = false, hasAccel = false, hasMag = false;
  10. uint32_t virtualSensorsNeeds =
  11. (1<<SENSOR_TYPE_GRAVITY) |
  12. (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
  13. (1<<SENSOR_TYPE_ROTATION_VECTOR) |
  14. (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR) |
  15. (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR);
  16. //遍历每个sensor并将其注册到SensorList里边
  17. for (ssize_t i=0 ; i<count ; i++) {
  18. bool useThisSensor=true;
  19. switch (list[i].type) {
  20. case SENSOR_TYPE_ACCELEROMETER:
  21. hasAccel = true;
  22. break;
  23. case SENSOR_TYPE_MAGNETIC_FIELD:
  24. hasMag = true;
  25. break;
  26. case SENSOR_TYPE_ORIENTATION:
  27. orientationIndex = i;
  28. break;
  29. case SENSOR_TYPE_GYROSCOPE:
  30. case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
  31. hasGyro = true;
  32. break;
  33. case SENSOR_TYPE_GRAVITY:
  34. case SENSOR_TYPE_LINEAR_ACCELERATION:
  35. case SENSOR_TYPE_ROTATION_VECTOR:
  36. case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
  37. case SENSOR_TYPE_GAME_ROTATION_VECTOR:
  38. if (IGNORE_HARDWARE_FUSION) {
  39. useThisSensor = false;
  40. } else {
  41. virtualSensorsNeeds &= ~(1<<list[i].type);
  42. }
  43. break;
  44. }
  45. if (useThisSensor) {
  46. //将HAL层的sensor_t类型结构体,存在HardwareSensor类里边,
  47. //进而在SensorList类里边通过map将handle和HardwareSensor一起存储起来,
  48. registerSensor( new HardwareSensor(list[i]) );
  49. }
  50. }
  51. // it's safe to instantiate the SensorFusion object here
  52. // (it wants to be instantiated after h/w sensors have been
  53. // registered)
  54. SensorFusion::getInstance();
  55. //融合虚拟sensor的一些逻辑处理,这些不是重点,可以先不管
  56. //所谓融合sensor,就是虚拟一个sensor,数据是拿一个或多个实际sensor的数据通过各种算法运算处理出来的,
  57. //比如手机里边的自动转屏功能,就是用加速度数据算出来的。
  58. //一般这些虚拟sensor需要一个算法一直在跑,若直接跑在AP端功耗很高,
  59. //手机厂家都是将其实现在协处理器里边,比如高通骁龙845、855的slpi,
  60. //而不是直接用google在framework实现的那套算法,
  61. if (hasGyro && hasAccel && hasMag) {
  62. // Add Android virtual sensors if they're not already
  63. // available in the HAL
  64. bool needRotationVector =
  65. (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) != 0;
  66. registerSensor(new RotationVectorSensor(), !needRotationVector, true);
  67. registerSensor(new OrientationSensor(), !needRotationVector, true);
  68. bool needLinearAcceleration =
  69. (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) != 0;
  70. registerSensor(new LinearAccelerationSensor(list, count),
  71. !needLinearAcceleration, true);
  72. // virtual debugging sensors are not for user
  73. registerSensor( new CorrectedGyroSensor(list, count), true, true);
  74. registerSensor( new GyroDriftSensor(), true, true);
  75. }
  76. if (hasAccel && hasGyro) {
  77. bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0;
  78. registerSensor(new GravitySensor(list, count), !needGravitySensor, true);
  79. bool needGameRotationVector =
  80. (virtualSensorsNeeds & (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) != 0;
  81. registerSensor(new GameRotationVectorSensor(), !needGameRotationVector, true);
  82. }
  83. if (hasAccel && hasMag) {
  84. bool needGeoMagRotationVector =
  85. (virtualSensorsNeeds & (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)) != 0;
  86. registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true);
  87. }
  88. mWakeLockAcquired = false;
  89. mLooper = new Looper(false);
  90. const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
  91. mSensorEventBuffer = new sensors_event_t[minBufferSize];//创建存储sensor数据的buffer,可以存储256个数据
  92. mSensorEventScratch = new sensors_event_t[minBufferSize];
  93. mMapFlushEventsToConnections = new wp<const SensorEventConnection> [minBufferSize];
  94. mCurrentOperatingMode = NORMAL;
  95. mNextSensorRegIndex = 0;
  96. for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {
  97. mLastNSensorRegistrations.push();//这个用来保存应用开关sensor的记录,后面 dumpsys sensorservice dump出来方便debug问题
  98. }
  99. mInitCheck = NO_ERROR;
  100. //创建并运行一个SensorEventAckReceiver 线程
  101. //这个loop线程用来不断检测是否需要持有wakelock
  102. mAckReceiver = new SensorEventAckReceiver(this);
  103. mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
  104. //在run里边调用SensorEventAckReceiver::threadLoop()方法,
  105. //通过创建一个线程运行SensorService::threadLoop(),
  106. run("SensorService", PRIORITY_URGENT_DISPLAY);
  107. // priority can only be changed after run
  108. enableSchedFifoMode();//降低主线程调度优先级
  109. // Start watching UID changes to apply policy.
  110. mUidPolicy->registerSelf();//这边mUidPolicy将自己注册到uid待机管理里边,后面应用待机行为发生变化时其接口会通过多态被回调
  111. }
  112. }
  113. }
  1. 下面来看SensorService::threadLoop()方法:
  1. bool SensorService::threadLoop() {
  2. ALOGD("nuSensorService thread starting...");
  3. // each virtual sensor could generate an event per "real" event, that's why we need to size
  4. // numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT. in practice, this is too
  5. // aggressive, but guaranteed to be enough.
  6. const size_t vcount = mSensors.getVirtualSensors().size();
  7. const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
  8. const size_t numEventMax = minBufferSize / (1 + vcount);
  9. //比如这边有vcount个虚拟的 sensor跑在framework,
  10. //那么比较极端的情况下每从HAL取numEventMax个数据,这边vcount个sensor会各生成numEventMax个数据,
  11. //而mSensorEventBuffer 最多只能容纳 MAX_RECEIVE_BUFFER_EVENT_COUNT个数据,
  12. //所以 numEventMax = minBufferSize / (1 + vcount);
  13. SensorDevice& device(SensorDevice::getInstance());
  14. const int halVersion = device.getHalDeviceVersion();
  15. do {
  16. //通过SensorDevice往HAL层取数据, 若没有数据的时候就一直阻塞(这个由前面说的第三方SO库实现)
  17. //一般在该so库的poll里边,可以采用c++标准实现的queue::pop(),来获取数据,没数据时就一直阻塞,
  18. //当驱动有数据上来时,另外一个线程将sensor数据往这个队列里边queue::pop就行了
  19. ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
  20. if (count < 0) {
  21. ALOGE("sensor poll failed (%s)", strerror(-count));
  22. break;
  23. }
  24. // Reset sensors_event_t.flags to zero for all events in the buffer.
  25. for (int i = 0; i < count; i++) {
  26. mSensorEventBuffer[i].flags = 0;
  27. }
  28. // Make a copy of the connection vector as some connections may be removed during the course
  29. // of this loop (especially when one-shot sensor events are present in the sensor_event
  30. // buffer). Promote all connections to StrongPointers before the lock is acquired. If the
  31. // destructor of the sp gets called when the lock is acquired, it may result in a deadlock
  32. // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the
  33. // strongPointers to a vector before the lock is acquired.
  34. SortedVector< sp<SensorEventConnection> > activeConnections;
  35. populateActiveConnections(&activeConnections);
  36. Mutex::Autolock _l(mLock);
  37. // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
  38. // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
  39. // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
  40. // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
  41. // releasing the wakelock.
  42. bool bufferHasWakeUpEvent = false;
  43. for (int i = 0; i < count; i++) {
  44. if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
  45. bufferHasWakeUpEvent = true;
  46. break;
  47. }
  48. }
  49. //若有wakeup 类型sensor上报的数据就持有wakelock
  50. if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
  51. setWakeLockAcquiredLocked(true);
  52. }
  53. recordLastValueLocked(mSensorEventBuffer, count);//将事件保存下来,后面可以用dumpsys sensorservice dump出来方便分析问题
  54. // 暂时先忽略handle virtual sensor,dynamic sensor部分
  55. // Send our events to clients. Check the state of wake lock for each client and release the
  56. // lock if none of the clients need it.
  57. bool needsWakeLock = false;
  58. size_t numConnections = activeConnections.size();
  59. for (size_t i=0 ; i < numConnections; ++i) {
  60. if (activeConnections[i] != 0) {
  61. //通过SensorEventConnection 将数据通过socket发送给应用
  62. activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
  63. mMapFlushEventsToConnections);
  64. needsWakeLock |= activeConnections[i]->needsWakeLock();
  65. // If the connection has one-shot sensors, it may be cleaned up after first trigger.
  66. // Early check for one-shot sensors.
  67. if (activeConnections[i]->hasOneShotSensors()) {
  68. cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
  69. count);
  70. }
  71. }
  72. }
  73. //若还有wake up 类型的sensor报上来的数据的话,需要继续持有wakelock
  74. if (mWakeLockAcquired && !needsWakeLock) {
  75. setWakeLockAcquiredLocked(false);
  76. }
  77. } while (!Thread::exitPending());
  78. ALOGW("Exiting SensorService::threadLoop => aborting...");
  79. abort();
  80. return false;
  81. }

该方法就是用SensorDevice循环去HAL层取数据,若无数据则阻塞当前线程,若有数据,则封装SensorEventConnection发送出去。至此SensorService已经启动了。

3.2.2 SensorManager的启动流程

  1. 从前一篇分析安卓Sensor 框架 Java API层的源码中我们知道,SystemSensorManager继承并实现SensorManager的虚方法,应用通过调用SensorManger的方法来达到其监听sensor数据的需求,而实际功能的实现者是SystemSensorManager,且SystemSensorManager中负责和Native层的SensorManager交互。安卓系统开机时在<br />frameworks/base/core/java/android/app/SystemServiceRegistry.java中创建SystemSensorManger实例:
  1. registerService(Context.SENSOR_SERVICE, SensorManager.class,
  2. new CachedServiceFetcher<SensorManager>() {
  3. @Override
  4. public SensorManager createService(ContextImpl ctx) {
  5. return new SystemSensorManager(ctx.getOuterContext(),
  6. ctx.mMainThread.getHandler().getLooper());
  7. }});

然后跳转到SystemSensorManager的构造方法中:

  1. public SystemSensorManager(Context context, Looper mainLooper) {
  2. synchronized (sLock) {
  3. if (!sNativeClassInited) {
  4. sNativeClassInited = true;
  5. nativeClassInit();//native层offset初始化,没做什么其他事情
  6. }
  7. }
  8. Log.e("======>lkh", Log.getStackTraceString(new Throwable()));
  9. mMainLooper = mainLooper;
  10. mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;
  11. mContext = context;
  12. mNativeInstance = nativeCreate(context.getOpPackageName());
  13. //mNativeInstance 保存native创建的 c++对象 SensorManager的引用,
  14. //该对象通过getOpPackageName()返回的结果作为参数创建,并且2者保存在一个map里边,
  15. //注意,此SensorManager为native层c++实现的,非面向应用用Java实现的SensorManager
  16. // initialize the sensor list
  17. for (int index = 0;; ++index) {
  18. Sensor sensor = new Sensor();
  19. if (!nativeGetSensorAtIndex(mNativeInstance, sensor, index)) break;
  20. mFullSensorsList.add(sensor);
  21. mHandleToSensor.put(sensor.getHandle(), sensor);
  22. }
  23. //获取SesorService的sensor list里边的所有sensor,每个sensor创建一个对应的java层的Sensor对象,
  24. //并保存到链表里边,并将sensor handle和sensor一并保存到map里边
  25. }
  1. 在加锁的情况下,如果没有初始化过Native层的类,则调用nativeClassInit() JNI方法初始化,调用nativeCreate()方法初始化SensorManager.cpp的实例,再调用nativeGetSensorAtIndex() jni方法初始化sensor列表,以上分析可知,当SystemSensorManager初始化时,SensorManager.cpp同时也初始化了。
  1. static jlong
  2. nativeCreate
  3. (JNIEnv *env, jclass clazz, jstring opPackageName)
  4. {
  5. ScopedUtfChars opPackageNameUtf(env, opPackageName);
  6. return (jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str()));
  7. }

接下来跳入Native SensorManager的构造函数中:

  1. SensorManager::SensorManager(const String16& opPackageName)
  2. : mSensorList(0), mOpPackageName(opPackageName), mDirectConnectionHandle(1) {
  3. // okay we're not locked here, but it's not needed during construction
  4. assertStateLocked();
  5. }
  6. status_t SensorManager::assertStateLocked() {
  7. bool initSensorManager = false;
  8. if (mSensorServer == NULL) {
  9. initSensorManager = true;
  10. } else {
  11. // Ping binder to check if sensorservice is alive.
  12. status_t err = IInterface::asBinder(mSensorServer)->pingBinder();
  13. if (err != NO_ERROR) {
  14. initSensorManager = true;
  15. }
  16. }
  17. if (initSensorManager) {
  18. waitForSensorService(&mSensorServer);
  19. LOG_ALWAYS_FATAL_IF(mSensorServer == nullptr, "getService(SensorService) NULL");
  20. class DeathObserver : public IBinder::DeathRecipient {
  21. SensorManager& mSensorManager;
  22. virtual void binderDied(const wp<IBinder>& who) {
  23. ALOGW("sensorservice died [%p]", who.unsafe_get());
  24. mSensorManager.sensorManagerDied();
  25. }
  26. public:
  27. explicit DeathObserver(SensorManager& mgr) : mSensorManager(mgr) { }
  28. };
  29. mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
  30. IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver);
  31. mSensors = mSensorServer->getSensorList(mOpPackageName);
  32. size_t count = mSensors.size();
  33. mSensorList =
  34. static_cast<Sensor const**>(malloc(count * sizeof(Sensor*)));
  35. LOG_ALWAYS_FATAL_IF(mSensorList == NULL, "mSensorList NULL");
  36. for (size_t i=0 ; i<count ; i++) {
  37. mSensorList[i] = mSensors.array() + i;
  38. }
  39. }
  40. return NO_ERROR;
  41. }

上面代码主要做了3件事情:

  1. 等待SensorService起来,获取到其指针
  2. 注册一个DeathObserver,当sensorManagerDied()时,做一些清理操作
  3. 获取sensorList里面的每一个sensor对象的地址

    3.3 Sensor数据的分发

    接下来分析SensorService如何将sensor数据分发到应用,上面SensorService启动时,我们知道SensorService启动了一个线程去执行threadLoop方法,这个方法首先调用SensorDevice::getInstance()方法,获取其实例引用,接下来就进入了一个调用SensorDevice::poll()方法的do while循环中,SensorDevice在其中扮演了十分重要的角色,主要通过该类从HAL层取数据,下面是SensorDevice的部分源码: ```cpp SensorDevice::SensorDevice()

    1. : mHidlTransportErrors(20), mRestartWaiter(new HidlServiceRegistrationWaiter()) {

    //通过hidl与HAL层建立连接 if (!connectHidlService()) {

    1. return;

    }

    //获取开机时前面所说的第三方SO库注册的sensor,这个SO库一般就是直接与驱动进行通信对实际sensor进行开关和数据获取了, //比如高通骁龙855的sensors.ssc.so通过qmi与slpi进行通信。 //这些sensor_t 类型的结构体,需要第三方的so库里边自己实现,每个结构体对象存储一个sensor的信息 checkReturn(mSensors->getSensorsList(

    1. [&](const auto &list) {
    2. const size_t count = list.size();
    3. mActivationCount.setCapacity(count);
    4. Info model;
    5. for (size_t i=0 ; i < count; i++) {
    6. sensor_t sensor;
    7. convertToSensor(list[i], &sensor);
    8. // Sanity check and clamp power if it is 0 (or close)
    9. if (sensor.power < minPowerMa) {
    10. ALOGE("Reported power %f not deemed sane, clamping to %f",
    11. sensor.power, minPowerMa);
    12. sensor.power = minPowerMa;
    13. }
    14. mSensorList.push_back(sensor);//将HAL层注册的sensor保存起来,具体如何注册的,后面分析sensor HAL层部分再分析
    15. //保存该sensor的handle,具体数值是在前面所说的第三方SO库决定的,一般是从1开启按顺序叠加
    16. mActivationCount.add(list[i].sensorHandle, model);
    17. checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* disable */));//关闭该sensor,以防开着没用漏电
    18. }
    19. }));

}

bool SensorDevice::connectHidlService() { // SensorDevice will wait for HAL service to start if HAL is declared in device manifest. size_t retry = 10;

  1. while (retry-- > 0) {
  2. //......
  3. //通过hidl获取 android.hardware.sensors@1.0-service
  4. mSensors = ISensors::getService();
  5. if (mSensors == nullptr) {
  6. // no sensor hidl service found
  7. break;
  8. }
  9. //.......
  10. }
  11. return (mSensors != nullptr);

}

  1. HAL层如何交互的分析已经远远超出我负责的范畴了,这里不做深入分析。我们只需知道Native层的Sensor数据是通过SensorDeviceHAL取得的就行了。当数据上来后,通过做一些判断和处理然后再分发给应用,其中判断处理包括:是否应该丢弃数据,是否是flush数据,是否需要将数据给融合sensor,应用是否已经关闭该sensor等,处理后,通过SensorService::SensorEventConnection::sendEvents将数据发出,senEvent()函数代码如下:
  2. ```cpp
  3. status_t SensorService::SensorEventConnection::sendEvents(
  4. sensors_event_t const* buffer, size_t numEvents,
  5. sensors_event_t* scratch,
  6. wp<const SensorEventConnection> const * mapFlushEventsToConnections) {
  7. // filter out events not for this connection
  8. sensors_event_t* sanitizedBuffer = nullptr;
  9. int count = 0;
  10. Mutex::Autolock _l(mConnectionLock);
  11. if (scratch) {
  12. size_t i=0;
  13. while (i<numEvents) {
  14. //每个数据琢一处理
  15. int32_t sensor_handle = buffer[i].sensor;
  16. if (buffer[i].type == SENSOR_TYPE_META_DATA) {
  17. ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
  18. buffer[i].meta_data.sensor);
  19. // Setting sensor_handle to the correct sensor to ensure the sensor events per
  20. // connection are filtered correctly. buffer[i].sensor is zero for meta_data
  21. // events.
  22. sensor_handle = buffer[i].meta_data.sensor;
  23. }
  24. ssize_t index = mSensorInfo.indexOfKey(sensor_handle);
  25. //enable 一个sensor时,会保存该sensor的handle
  26. //确认一下若该sensor已经被disable了,那么就没有必要将该sensor的数据给到应用了
  27. //或者该应用没有注册该sensor的话,也是直接过滤掉
  28. // Check if this connection has registered for this sensor. If not continue to the
  29. // next sensor_event.
  30. if (index < 0) {
  31. ++i;
  32. continue;
  33. }
  34. FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
  35. // Check if there is a pending flush_complete event for this sensor on this connection.
  36. if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
  37. mapFlushEventsToConnections[i] == this) {
  38. flushInfo.mFirstFlushPending = false;
  39. ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
  40. buffer[i].meta_data.sensor);
  41. ++i;
  42. continue;
  43. }
  44. // If there is a pending flush complete event for this sensor on this connection,
  45. // ignore the event and proceed to the next.
  46. if (flushInfo.mFirstFlushPending) {
  47. ++i;
  48. continue;
  49. }
  50. //过滤掉flush的数据后,将要给到应用的数据拷到scratch
  51. do {
  52. // Keep copying events into the scratch buffer as long as they are regular
  53. // sensor_events are from the same sensor_handle OR they are flush_complete_events
  54. // from the same sensor_handle AND the current connection is mapped to the
  55. // corresponding flush_complete_event.
  56. if (buffer[i].type == SENSOR_TYPE_META_DATA) {
  57. if (mapFlushEventsToConnections[i] == this) {
  58. scratch[count++] = buffer[i];
  59. }
  60. } else {
  61. // Regular sensor event, just copy it to the scratch buffer.
  62. //若为false,即应用进入idle,那么就不将数据装进scratch在通过scratch给到应用,
  63. //否则就装进去
  64. if (mHasSensorAccess) {
  65. scratch[count++] = buffer[i];
  66. }
  67. }
  68. i++;
  69. } while ((i<numEvents) && ((buffer[i].sensor == sensor_handle &&
  70. buffer[i].type != SENSOR_TYPE_META_DATA) ||
  71. (buffer[i].type == SENSOR_TYPE_META_DATA &&
  72. buffer[i].meta_data.sensor == sensor_handle)));
  73. }
  74. } else {
  75. //这边不会走到不用管,感觉google这段代码有点多余哈哈
  76. if (mHasSensorAccess) {
  77. scratch = const_cast<sensors_event_t *>(buffer);
  78. count = numEvents;
  79. } else {
  80. scratch = sanitizedBuffer = new sensors_event_t[numEvents];
  81. for (size_t i = 0; i < numEvents; i++) {
  82. if (buffer[i].type == SENSOR_TYPE_META_DATA) {
  83. scratch[count++] = buffer[i++];
  84. }
  85. }
  86. }
  87. }
  88. sendPendingFlushEventsLocked();
  89. // Early return if there are no events for this connection.
  90. if (count == 0) {
  91. delete sanitizedBuffer;//可能遇到空指针? free 已经做了判断了
  92. return status_t(NO_ERROR);
  93. }
  94. #if DEBUG_CONNECTIONS
  95. mEventsReceived += count;
  96. #endif
  97. //将最新的数据缓存到mEventCache,后面可以dump出来debug
  98. if (mCacheSize != 0) {
  99. // There are some events in the cache which need to be sent first. Copy this buffer to
  100. // the end of cache.
  101. if (mCacheSize + count <= mMaxCacheSize) {
  102. memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
  103. mCacheSize += count;
  104. } else {
  105. // Check if any new sensors have registered on this connection which may have increased
  106. // the max cache size that is desired.
  107. if (mCacheSize + count < computeMaxCacheSizeLocked()) {
  108. reAllocateCacheLocked(scratch, count);
  109. delete sanitizedBuffer;
  110. return status_t(NO_ERROR);
  111. }
  112. // Some events need to be dropped.
  113. int remaningCacheSize = mMaxCacheSize - mCacheSize;
  114. if (remaningCacheSize != 0) {
  115. memcpy(&mEventCache[mCacheSize], scratch,
  116. remaningCacheSize * sizeof(sensors_event_t));
  117. }
  118. int numEventsDropped = count - remaningCacheSize;
  119. countFlushCompleteEventsLocked(mEventCache, numEventsDropped);
  120. // Drop the first "numEventsDropped" in the cache.
  121. memmove(mEventCache, &mEventCache[numEventsDropped],
  122. (mCacheSize - numEventsDropped) * sizeof(sensors_event_t));
  123. // Copy the remainingEvents in scratch buffer to the end of cache.
  124. memcpy(&mEventCache[mCacheSize - numEventsDropped], scratch + remaningCacheSize,
  125. numEventsDropped * sizeof(sensors_event_t));
  126. }
  127. delete sanitizedBuffer;
  128. return status_t(NO_ERROR);
  129. }
  130. int index_wake_up_event = -1;
  131. if (mHasSensorAccess) {
  132. index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
  133. if (index_wake_up_event >= 0) {
  134. scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
  135. ++mWakeLockRefCount;
  136. #if DEBUG_CONNECTIONS
  137. ++mTotalAcksNeeded;
  138. #endif
  139. }
  140. }
  141. // NOTE: ASensorEvent and sensors_event_t are the same type.
  142. //重点在这边,把scratch里边的数据发出去,
  143. ssize_t size = SensorEventQueue::write(mChannel,
  144. reinterpret_cast<ASensorEvent const*>(scratch), count);
  145. if (size < 0) {
  146. // Write error, copy events to local cache.
  147. if (index_wake_up_event >= 0) {
  148. // If there was a wake_up sensor_event, reset the flag.
  149. scratch[index_wake_up_event].flags &= ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
  150. if (mWakeLockRefCount > 0) {
  151. --mWakeLockRefCount;
  152. }
  153. #if DEBUG_CONNECTIONS
  154. --mTotalAcksNeeded;
  155. #endif
  156. }
  157. if (mEventCache == NULL) {
  158. mMaxCacheSize = computeMaxCacheSizeLocked();
  159. mEventCache = new sensors_event_t[mMaxCacheSize];
  160. mCacheSize = 0;
  161. }
  162. memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
  163. mCacheSize += count;
  164. // Add this file descriptor to the looper to get a callback when this fd is available for
  165. // writing.
  166. updateLooperRegistrationLocked(mService->getLooper());
  167. delete sanitizedBuffer;
  168. return size;
  169. }
  170. }

发现别无他法发送数据,唯有SensorEventQueue::write() 对复制得来的的scratch数据进行了处理,下面跳进该方法中:

  1. ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
  2. ASensorEvent const* events, size_t numEvents) {
  3. return BitTube::sendObjects(tube, events, numEvents);
  4. }

该方法仅仅调用了一下BitTube::sendObjects()方法,只能进入此方法中查看:

  1. ssize_t BitTube::sendObjects(const sp<BitTube>& tube,
  2. void const* events, size_t count, size_t objSize)
  3. {
  4. //SensorService::SensorEventConnection::mChannel::write()
  5. //mChannel 为 BitTube 对象
  6. const char* vaddr = reinterpret_cast<const char*>(events);
  7. ssize_t size = tube->write(vaddr, count*objSize);
  8. // should never happen because of SOCK_SEQPACKET
  9. LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
  10. "BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were sent!)",
  11. count, objSize, size);
  1. 看到tube->write(),则继续跟进去看:
  1. ssize_t BitTube::write(void const* vaddr, size_t size)
  2. {
  3. ssize_t err, len;
  4. do {
  5. //这边通过 unix域套接字 发出去
  6. len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
  7. // cannot return less than size, since we're using SOCK_SEQPACKET
  8. err = len < 0 ? errno : 0;
  9. } while (err == EINTR);
  10. return err == 0 ? len : -err;
  11. }

这个send方法是 sys/socket.h中声明的,是Unix套接字,这里分析到发送端就结束了。
接下来分析接收端怎么接收的,应用是通过SensorManager注册一个SensorEventListener来接收数据的,主要是通过调用registerListener方法,代码如下:

  1. public boolean registerListener(SensorEventListener listener, Sensor sensor,
  2. int samplingPeriodUs, Handler handler) {
  3. int delay = getDelay(samplingPeriodUs);
  4. return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
  5. }

SystemSensorManager是SensorManager的实现类,其实现方法如下:

  1. protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
  2. int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
  3. if (listener == null || sensor == null) {
  4. Log.e(TAG, "sensor or listener is null");
  5. return false;
  6. }
  7. // Trigger Sensors should use the requestTriggerSensor call.
  8. if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
  9. Log.e(TAG, "Trigger Sensors should use the requestTriggerSensor.");
  10. return false;
  11. }
  12. if (maxBatchReportLatencyUs < 0 || delayUs < 0) {
  13. Log.e(TAG, "maxBatchReportLatencyUs and delayUs should be non-negative");
  14. return false;
  15. }
  16. if (mSensorListeners.size() >= MAX_LISTENER_COUNT) {
  17. throw new IllegalStateException("register failed, " +
  18. "the sensor listeners size has exceeded the maximum limit " +
  19. MAX_LISTENER_COUNT);
  20. }
  21. // Invariants to preserve:
  22. // - one Looper per SensorEventListener
  23. // - one Looper per SensorEventQueue
  24. // We map SensorEventListener to a SensorEventQueue, which holds the looper
  25. synchronized (mSensorListeners) {
  26. SensorEventQueue queue = mSensorListeners.get(listener);
  27. if (queue == null) {
  28. Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
  29. final String fullClassName = listener.getClass().getEnclosingClass() != null ?
  30. listener.getClass().getEnclosingClass().getName() :
  31. listener.getClass().getName();
  32. queue = new SensorEventQueue(listener, looper, this, fullClassName);
  33. if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
  34. queue.dispose();
  35. return false;
  36. }
  37. mSensorListeners.put(listener, queue);
  38. return true;
  39. } else {
  40. return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
  41. }
  42. }
  43. }

在各种合法性判断之后,先根据传入的listener获取对应的SensorEventQueue实例,如果不为空则调用addSensor方法,为空则创建该实例并调用addSensor方法最后将其加入mSensorListeners中,而创建实例时,会调用android/frameworks/base/core/jni/android_hardware_SensorManager.cpp nativeInitSensorEventQueue(),其源码如下:

  1. static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
  2. jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) {
  3. SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
  4. ScopedUtfChars packageUtf(env, packageName);
  5. String8 clientName(packageUtf.c_str());
  6. sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));
  7. if (queue == NULL) {
  8. jniThrowRuntimeException(env, "Cannot construct native SensorEventQueue.");
  9. return 0;
  10. }
  11. sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);//获取MessageQueue
  12. if (messageQueue == NULL) {
  13. jniThrowRuntimeException(env, "MessageQueue is not initialized.");
  14. return 0;
  15. }
  16. sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak);
  17. receiver->incStrong((void*)nativeInitSensorEventQueue);
  18. return jlong(receiver.get());
  19. }

这里创建了一个接收数据的Receiver对象,该类定义也在android_hardwate_SensorManager.cpp中,receiver又根据clientName创建了一个Native层的SensorEventQueue:

  1. Receiver(const sp<SensorEventQueue>& sensorQueue,
  2. const sp<MessageQueue>& messageQueue,
  3. jobject receiverWeak) {
  4. JNIEnv* env = AndroidRuntime::getJNIEnv();
  5. //保存传进来的2个比较关键的对象引用
  6. mSensorQueue = sensorQueue;
  7. mMessageQueue = messageQueue;
  8. mReceiverWeakGlobal = env->NewGlobalRef(receiverWeak);
  9. mIntScratch = (jintArray) env->NewGlobalRef(env->NewIntArray(16));
  10. mFloatScratch = (jfloatArray) env->NewGlobalRef(env->NewFloatArray(16));
  11. }

receiver在执行incStrong时,会顺带执行它自己的onFirstRef()方法:

  1. virtual void onFirstRef() {
  2. LooperCallback::onFirstRef();
  3. //获取套接字fd
  4. mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0,
  5. ALOOPER_EVENT_INPUT, this, mSensorQueue.get());
  6. }

上面将SensorEventQueue中BitTube里通过unix socket创建的mReceiveFd,添加到looper里,在Looper::pollInner()方法中通过epoll监听该fd,当有事件时,就会回调Receiver::hanldeEvent(),接下来看该方法:

  1. virtual int handleEvent(int fd, int events, void* data) {
  2. JNIEnv* env = AndroidRuntime::getJNIEnv();
  3. sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);
  4. ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
  5. ssize_t n;
  6. ASensorEvent buffer[16];
  7. //这边最后是通过标准的socket接口recv将数据读取出来,代码在以下位置:
  8. //android/frameworks/native/libs/sensor
  9. //SensorEventQueue::read() ==> BitTube::recvObjects()==>BitTube::read()
  10. while ((n = q->read(buffer, 16)) > 0) {
  11. for (int i=0 ; i<n ; i++) {
  12. if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) {
  13. // step-counter returns a uint64, but the java API only deals with floats
  14. float value = float(buffer[i].u64.step_counter);
  15. env->SetFloatArrayRegion(mFloatScratch, 0, 1, &value);
  16. } else if (buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
  17. float value[2];
  18. value[0] = buffer[i].dynamic_sensor_meta.connected ? 1.f: 0.f;
  19. value[1] = float(buffer[i].dynamic_sensor_meta.handle);
  20. env->SetFloatArrayRegion(mFloatScratch, 0, 2, value);
  21. } else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
  22. env->SetIntArrayRegion(mIntScratch, 0, 14,
  23. buffer[i].additional_info.data_int32);
  24. env->SetFloatArrayRegion(mFloatScratch, 0, 14,
  25. buffer[i].additional_info.data_float);
  26. } else {
  27. env->SetFloatArrayRegion(mFloatScratch, 0, 16, buffer[i].data);
  28. }
  29. if (buffer[i].type == SENSOR_TYPE_META_DATA) {
  30. // This is a flush complete sensor event. Call dispatchFlushCompleteEvent
  31. // method.
  32. if (receiverObj.get()) {
  33. env->CallVoidMethod(receiverObj.get(),
  34. gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
  35. buffer[i].meta_data.sensor);
  36. }
  37. } else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
  38. // This is a flush complete sensor event. Call dispatchAdditionalInfoEvent
  39. // method.
  40. if (receiverObj.get()) {
  41. int type = buffer[i].additional_info.type;
  42. int serial = buffer[i].additional_info.serial;
  43. env->CallVoidMethod(receiverObj.get(),
  44. gBaseEventQueueClassInfo.dispatchAdditionalInfoEvent,
  45. buffer[i].sensor,
  46. type, serial,
  47. mFloatScratch,
  48. mIntScratch,
  49. buffer[i].timestamp);
  50. }
  51. }else {
  52. int8_t status;
  53. switch (buffer[i].type) {
  54. case SENSOR_TYPE_ORIENTATION:
  55. case SENSOR_TYPE_MAGNETIC_FIELD:
  56. case SENSOR_TYPE_ACCELEROMETER:
  57. case SENSOR_TYPE_GYROSCOPE:
  58. case SENSOR_TYPE_GRAVITY:
  59. case SENSOR_TYPE_LINEAR_ACCELERATION:
  60. status = buffer[i].vector.status;
  61. break;
  62. case SENSOR_TYPE_HEART_RATE:
  63. status = buffer[i].heart_rate.status;
  64. break;
  65. default:
  66. status = SENSOR_STATUS_ACCURACY_HIGH;
  67. break;
  68. }
  69. //关键就在这里,这边通过jni回调SystemSensorManager::dispatchSensorEvent(),将数据给SensorManager
  70. if (receiverObj.get()) {
  71. env->CallVoidMethod(receiverObj.get(),
  72. gBaseEventQueueClassInfo.dispatchSensorEvent,
  73. buffer[i].sensor,
  74. mFloatScratch,
  75. status,
  76. buffer[i].timestamp);
  77. }
  78. }
  79. if (env->ExceptionCheck()) {
  80. mSensorQueue->sendAck(buffer, n);
  81. ALOGE("Exception dispatching input event.");
  82. return 1;
  83. }
  84. }
  85. //对SensorService::SensorEventConnection发送确认,
  86. //SensorService::SensorEventConnection::handleEvent()接收并确认
  87. mSensorQueue->sendAck(buffer, n);
  88. }
  89. if (n<0 && n != -EAGAIN) {
  90. // FIXME: error receiving events, what to do in this case?
  91. }
  92. return 1;
  93. }
  94. };

方法里面通过JNI 在C++代码里调用了SystemSensorManagre.java 中 BaseEventQueue的 dispatchSensorEvent(),下面为该方法(SensorEventQueue.java实现类)源码:

  1. protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
  2. long timestamp) {
  3. final Sensor sensor = mManager.mHandleToSensor.get(handle);
  4. if (sensor == null) {
  5. // sensor disconnected
  6. return;
  7. }
  8. SensorEvent t = null;
  9. synchronized (mSensorsEvents) {
  10. t = mSensorsEvents.get(handle);
  11. }
  12. if (t == null) {
  13. // This may happen if the client has unregistered and there are pending events in
  14. // the queue waiting to be delivered. Ignore.
  15. return;
  16. }
  17. // Copy from the values array.
  18. System.arraycopy(values, 0, t.values, 0, t.values.length);
  19. t.timestamp = timestamp;
  20. t.accuracy = inAccuracy;
  21. t.sensor = sensor;
  22. // call onAccuracyChanged() only if the value changes
  23. final int accuracy = mSensorAccuracies.get(handle);
  24. if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
  25. mSensorAccuracies.put(handle, t.accuracy);
  26. mListener.onAccuracyChanged(t.sensor, t.accuracy);
  27. }
  28. mListener.onSensorChanged(t);//在这边,通过多态回调应用开发者自己实现的onSensorChanged(),将sensor事件给到应用
  29. }

该方法最后调用了(SensorEventListener)listener的onSensorChanged方法,最后回调到了应用。

3.4总结

  1. Sensor数据的分发最终还是走的SocketSensorEventConnection类中持有 sp<BitTube>类型名为mChannel的实例,而其也持有一个应用包名字符串和Java虚拟机名字符串,一个应用对应一个SensorEventConnection,通过SensorEventConnection进行sensor监听的管理。