In-depth analysis of Android SensorService

 

I wanted to write this article more than four months ago, but I never had time to write it. I will write it today when I have time. The main contents of this article are as follows

Table of contents

1. Basic flow chart of the relationship between Android modules

2. SensorService starts

3. Apply to register a sensor process

4. How does SensorService provide sensor data to the application?

5. SensorService behavior after standby

6. Fusion sensor (SensorFusion)

7. Compile SensorService

8,  dumpsys sensorservice

9. Android sensor hal layer starts

10. SensorManager starts

(1)SystemSensorManager startup process

(2) Native layer SensorManager startup process


 


The source code analyzed in this article is based on android 9.0

====================================================

1. Basic flow chart of the relationship between Android modules

The core of the entire android sensor module is SensorService. Applications interact with it through SensorManager. SensorService basically manages all behaviors of the sensor, including switching the sensor on and off, obtaining sensor data to the application, whether the application has permission to obtain the sensor, the behavior of the sensor after standby, and sensor data. and switch record cache, you can also customize virtual sensors here, etc.

Until Android 9, SensorService has been running in the system server. So as long as SensorService hangs up, the entire system hangs up (Android 10 seems to have been improved, but I haven’t studied it yet). I personally think that if Google makes it similar to audio The server will be better that way. It can be restarted after hanging for 3 seconds.

 

2. SensorService starts

The sensorservice is pulled up by the system_server when the system_server starts.
As mentioned earlier, it runs in the system_server process, so as long as the sensorservice crashes,
it will cause the system_server to hang up and restart.

android/frameworks/base/services/java/com/android/server/SystemServer.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);
	
	//......

}

The corresponding jni implementation is as follows:

/*
 * JNI registration.
 */
static const JNINativeMethod gMethods[] = {
    /* name, signature, funcPtr */
	//这边先将该接口注册,后面给system_server调用
    { "startSensorService", "()V", (void*) android_server_SystemServer_startSensorService }
    { "startHidlServices", "()V", (void*) android_server_SystemServer_startHidlServices },
};

//在这儿创建sensorservice
static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
    char propBuf[PROPERTY_VALUE_MAX];
    property_get("system_init.startsensorservice", propBuf, "1");
    if (strcmp(propBuf, "1") == 0) {
        SensorService::instantiate();
    }

}

A sensorservice instance created using SensorService::instantiate().
The sensorservice inherits BinderService, so BinderService::instantiate() is used to create the instance, as follows;

//这边SERVICE为SensorService类型
template<typename SERVICE>
class BinderService
{
//......
public:
    static status_t publish(bool allowIsolated = false,
                            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
        sp<IServiceManager> sm(defaultServiceManager());
	   //创建SensorService实例并且添加到ServiceManage
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
                              dumpFlags);
    }

    static void instantiate() { publish(); }

//......
};


Looking at the SensorService constructor, in fact, the constructor does nothing. It mainly creates a UidPolicy object. This is used for standby sensor behavior management, which will be analyzed later.
 

SensorService::SensorService()
    : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
      mWakeLockAcquired(false) {
    mUidPolicy = new UidPolicy(this);
}

The next thing to be called is the onFirstRef() method.
//The onFirstRef() method is called in the ServiceManager and is called
in RefBase::incStrong(const void* id) when the previously created SensorService object is promoted to a strong pointer. ,
how to be called has to go back to the previous BinderService::publish(), interested readers can study it by themselves.
=====================================
Look at onFirstRef(),

void SensorService::onFirstRef() {
    SensorDevice& dev(SensorDevice::getInstance());//创建并获取SensorDevice实例

    sHmacGlobalKeyIsValid = initializeHmacKey();

    if (dev.initCheck() == NO_ERROR) {
        sensor_t const* list;
        ssize_t count = dev.getSensorList(&list);//获取vendor层注册的sensor 数目
        if (count > 0) {
            ssize_t orientationIndex = -1;
            bool hasGyro = false, hasAccel = false, hasMag = false;
            uint32_t virtualSensorsNeeds =
                    (1<<SENSOR_TYPE_GRAVITY) |
                    (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
                    (1<<SENSOR_TYPE_ROTATION_VECTOR) |
                    (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR) |
                    (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR);
			//遍历每个sensor并将其注册到SensorList里边
            for (ssize_t i=0 ; i<count ; i++) {
                bool useThisSensor=true;

                switch (list[i].type) {
                    case SENSOR_TYPE_ACCELEROMETER:
                        hasAccel = true;
                        break;
                    case SENSOR_TYPE_MAGNETIC_FIELD:
                        hasMag = true;
                        break;
                    case SENSOR_TYPE_ORIENTATION:
                        orientationIndex = i;
                        break;
                    case SENSOR_TYPE_GYROSCOPE:
                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
                        hasGyro = true;
                        break;
                    case SENSOR_TYPE_GRAVITY:
                    case SENSOR_TYPE_LINEAR_ACCELERATION:
                    case SENSOR_TYPE_ROTATION_VECTOR:
                    case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
                    case SENSOR_TYPE_GAME_ROTATION_VECTOR:
                        if (IGNORE_HARDWARE_FUSION) {
                            useThisSensor = false;
                        } else {
                            virtualSensorsNeeds &= ~(1<<list[i].type);
                        }
                        break;
                }
                if (useThisSensor) {
				//将HAL层的sensor_t类型结构体,存在HardwareSensor类里边,
				//进而在SensorList类里边通过map将handle和HardwareSensor一起存储起来,
                    registerSensor( new HardwareSensor(list[i]) );
                }
            }
			
			
            // it's safe to instantiate the SensorFusion object here
            // (it wants to be instantiated after h/w sensors have been
            // registered)
            SensorFusion::getInstance();
			//融合虚拟sensor的一些逻辑处理,这些不是重点,可以先不管
			//所谓融合sensor,就是虚拟一个sensor,数据是拿一个或多个实际sensor的数据通过各种算法运算处理出来的,
			//比如手机里边的自动转屏功能,就是用加速度数据算出来的。
			//一般这些虚拟sensor需要一个算法一直在跑,若直接跑在AP端功耗很高,
			//手机厂家都是将其实现在协处理器里边,比如高通骁龙845、855的slpi,
			//而不是直接用google在framework实现的那套算法,
            if (hasGyro && hasAccel && hasMag) {
                // Add Android virtual sensors if they're not already
                // available in the HAL
                bool needRotationVector =
                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) != 0;

                registerSensor(new RotationVectorSensor(), !needRotationVector, true);
                registerSensor(new OrientationSensor(), !needRotationVector, true);

                bool needLinearAcceleration =
                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) != 0;

                registerSensor(new LinearAccelerationSensor(list, count),
                               !needLinearAcceleration, true);

                // virtual debugging sensors are not for user
                registerSensor( new CorrectedGyroSensor(list, count), true, true);
                registerSensor( new GyroDriftSensor(), true, true);
            }

            if (hasAccel && hasGyro) {
                bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0;
                registerSensor(new GravitySensor(list, count), !needGravitySensor, true);

                bool needGameRotationVector =
                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) != 0;
                registerSensor(new GameRotationVectorSensor(), !needGameRotationVector, true);
            }

            if (hasAccel && hasMag) {
                bool needGeoMagRotationVector =
                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)) != 0;
                registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true);
            }


            mWakeLockAcquired = false;
            mLooper = new Looper(false);
            const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
            mSensorEventBuffer = new sensors_event_t[minBufferSize];//创建存储sensor数据的buffer,可以存储256个数据
            mSensorEventScratch = new sensors_event_t[minBufferSize];//这个用来存储啥的还不知道
            mMapFlushEventsToConnections = new wp<const SensorEventConnection> [minBufferSize];
            mCurrentOperatingMode = NORMAL;

            mNextSensorRegIndex = 0;
            for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {
                mLastNSensorRegistrations.push();//这个用来保存应用开关sensor的记录,后面 dumpsys sensorservice dump出来方便debug问题
            }

            mInitCheck = NO_ERROR;
			//创建并运行一个SensorEventAckReceiver 线程
			//这个loop线程用来不断检测是否需要持有wakelock
            mAckReceiver = new SensorEventAckReceiver(this);
            mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
            
            //在run里边调用SensorEventAckReceiver::threadLoop()方法,
            //至于threadLoop是如何被调用的,感兴趣的读者可以跟一下源码,
			//大概是在android/system/core/libutils/Threads.cpp 里边,
            //通过pread_create() 创建一个线程运行thread::_threadLoop,
			//在这里边调用其子类(也就是SensorEventAckReceiver)的threadLoop,

			
			//同理通过创建一个线程运行SensorService::threadLoop(),
            run("SensorService", PRIORITY_URGENT_DISPLAY);

            // priority can only be changed after run
            enableSchedFifoMode();//降低主线程调度优先级

            // Start watching UID changes to apply policy.
            mUidPolicy->registerSelf();//这边mUidPolicy将自己注册到uid待机管理里边,后面应用待机行为发生变化时其接口会通过多态被回调
        }
    }
}

 

Before looking at SensorService::threadLoop(), let's first look at the constructor of SensorDevice.
SensorDevice is a class that actually interacts directly with the HAL layer.
It establishes a connection with the sensor's service in the HAL layer through hidl (the HAL referred to here). The layer only refers to the part implemented by Google,
namely: [email protected]. Through dlopen(), this layer will call the
SO library implemented by third parties such as chip manufacturers, mobile phone manufacturers, developers, etc. In fact, These should be collectively called the HAL layer, or the vendor layer).


SensorDevice::SensorDevice()
        : mHidlTransportErrors(20), mRestartWaiter(new HidlServiceRegistrationWaiter()) {

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

    //获取开机时前面所说的第三方SO库注册的sensor,这个SO库一般就是直接与驱动进行通信对实际sensor进行开关和数据获取了,
	//比如高通骁龙855的sensors.ssc.so通过qmi与slpi进行通信。
	//后面所有与HAL层通信都是通过这个sp<hardware::sensors::V1_0::ISensors> mSensors
    checkReturn(mSensors->getSensorsList(
            [&](const auto &list) {
                const size_t count = list.size();

                mActivationCount.setCapacity(count);
                Info model;
                for (size_t i=0 ; i < count; i++) {
                    sensor_t sensor;
                    convertToSensor(list[i], &sensor);
                    // Sanity check and clamp power if it is 0 (or close)
                    if (sensor.power < minPowerMa) {
                        ALOGE("Reported power %f not deemed sane, clamping to %f",
                              sensor.power, minPowerMa);
                        sensor.power = minPowerMa;
                    }
                    mSensorList.push_back(sensor);//将HAL层注册的sensor保存起来,具体如何注册的,后面分析sensor HAL层部分再分析
					
					//保存该sensor的handle,这个现在还不知道做什么的,具体这个handle是在前面所说的第三方SO库决定的,一般按顺序叠加
                    mActivationCount.add(list[i].sensorHandle, model);

                    checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* disable */));//关闭该sensor,以防开着没用漏电
                }
            }));

}

Looking back at SensorService::threadLoop(),

bool SensorService::threadLoop() {
    ALOGD("nuSensorService thread starting...");

    // each virtual sensor could generate an event per "real" event, that's why we need to size
    // numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.  in practice, this is too
    // aggressive, but guaranteed to be enough.
    const size_t vcount = mSensors.getVirtualSensors().size();
    const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
    const size_t numEventMax = minBufferSize / (1 + vcount);
    //为何要这么做,再解释一下,比如说这边有vcount个虚拟的 sensor跑在framework,
    //那么比较极端的情况下每从HAL取numEventMax个数据,这边vcount个sensor会各生成numEventMax个数据,
    //而mSensorEventBuffer 最多只能容纳 MAX_RECEIVE_BUFFER_EVENT_COUNT个数据,
    //所以 numEventMax = minBufferSize / (1 + vcount);

    SensorDevice& device(SensorDevice::getInstance());

    const int halVersion = device.getHalDeviceVersion();
    do {
        //通过SensorDevice往HAL层取数据, 若没有数据的时候就一直阻塞(这个由前面说的第三方SO库实现)
        //一般在该so库的poll里边,可以采用c++标准实现的queue::pop(),来获取数据,没数据时就一直阻塞,
        //当驱动有数据上来时,另外一个线程将sensor数据往这个队列里边queue::pop就行了
        ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
        if (count < 0) {
            ALOGE("sensor poll failed (%s)", strerror(-count));
            break;

        }

        // Reset sensors_event_t.flags to zero for all events in the buffer.
        for (int i = 0; i < count; i++) {
             mSensorEventBuffer[i].flags = 0;
        }

        // Make a copy of the connection vector as some connections may be removed during the course
        // of this loop (especially when one-shot sensor events are present in the sensor_event
        // buffer). Promote all connections to StrongPointers before the lock is acquired. If the
        // destructor of the sp gets called when the lock is acquired, it may result in a deadlock
        // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the
        // strongPointers to a vector before the lock is acquired.
        SortedVector< sp<SensorEventConnection> > activeConnections;
        populateActiveConnections(&activeConnections);

        Mutex::Autolock _l(mLock);
        // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
        // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
        // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
        // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
        // releasing the wakelock.
        bool bufferHasWakeUpEvent = false;
        for (int i = 0; i < count; i++) {
            if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
                bufferHasWakeUpEvent = true;
                break;
            }
        }
		//若有wakeup 类型sensor上报的数据就持有wakelock
        if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
            setWakeLockAcquiredLocked(true);
        }
        recordLastValueLocked(mSensorEventBuffer, count);//将事件保存下来,后面可以用dumpsys sensorservice dump出来方便分析问题

        // 暂时可先忽略handle virtual sensor,dynamic sensor部分不看
		
		
        // Send our events to clients. Check the state of wake lock for each client and release the
        // lock if none of the clients need it.
        bool needsWakeLock = false;
        size_t numConnections = activeConnections.size();
        for (size_t i=0 ; i < numConnections; ++i) {
            if (activeConnections[i] != 0) {
				//通过SensorEventConnection 将数据通过socket发送给应用
                activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
                        mMapFlushEventsToConnections);
                needsWakeLock |= activeConnections[i]->needsWakeLock();
                // If the connection has one-shot sensors, it may be cleaned up after first trigger.
                // Early check for one-shot sensors.
                if (activeConnections[i]->hasOneShotSensors()) {
                    cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
                            count);
                }
            }
        }
		
		//若还有wake up 类型的sensor报上来的数据的话,需要继续持有wakelock
        if (mWakeLockAcquired && !needsWakeLock) {
            setWakeLockAcquiredLocked(false);
        }
    } while (!Thread::exitPending());

    ALOGW("Exiting SensorService::threadLoop => aborting...");
    abort();
    return false;
}

At this point, the sensorservice has been started and can receive enable(), disable(), flush() and other requests sent from binder communication. It
can also read the data of the HAL layer and provide it to the application.

=============================================================================

Before looking at how SensorService provides data to the application, let’s first analyze the following key classes:

(1)SensorDevice

SensorDevice inherits the Singleton class and is designed as a singleton. If you want to use it later, use getinstance(). Why use a
singleton because sensorservice will have multiple threads to interact with the vendor layer. If you use multiple threads, the logic will be confused. And there is no need, save some memory haha.
There is a key member stored in it: sp<hardware::sensors::V1_0::ISensors> mSensors.
During construction, the sensor service [email protected] of the vendor layer will be obtained. The following are
passed This mSensors calls the interface of the Vendor layer. The code is as follows. In fact, it has been analyzed before. In order not to pull it back to see it, I will paste it again.

SensorDevice::SensorDevice()
        : mHidlTransportErrors(20), mRestartWaiter(new HidlServiceRegistrationWaiter()) {

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

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

                mActivationCount.setCapacity(count);
                Info model;
                for (size_t i=0 ; i < count; i++) {
                    sensor_t sensor;
                    convertToSensor(list[i], &sensor);
                    // Sanity check and clamp power if it is 0 (or close)
                    if (sensor.power < minPowerMa) {
                        ALOGE("Reported power %f not deemed sane, clamping to %f",
                              sensor.power, minPowerMa);
                        sensor.power = minPowerMa;
                    }
                    mSensorList.push_back(sensor);//将HAL层注册的sensor保存起来,具体如何注册的,后面分析sensor HAL层部分再分析
					
					//保存该sensor的handle,具体数值是在前面所说的第三方SO库决定的,一般是从1开启按顺序叠加
                    mActivationCount.add(list[i].sensorHandle, model);

                    checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* disable */));//关闭该sensor,以防开着没用漏电
                }
            }));

}

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

    while (retry-- > 0) {
		//......
		
        //通过hidl获取 [email protected]
        mSensors = ISensors::getService();
        if (mSensors == nullptr) {
            // no sensor hidl service found
            break;
        }
		
		//.......
    }
    return (mSensors != nullptr);
}


(2)SensorEventConnection

This class is mainly used to send sensor data to applications and communicate through sockets.
When an application registers a sensor, SensorManager.cpp will generate a connection belonging to the application by calling SensorService::createSensorEventConnection().
How many connections does an application have? SensorEventConnection depends on how many SensorEventListerners the application creates.
Some application developers may like to create only one SensorEventListerner when registering multiple sensors, and then distinguish types in onSensorChanged().
Some prefer one sensor and one SensorEventListerner, from a performance perspective. It is enough to consider suggesting that an application create a SensorEventListerner.
After all, every time one is created, a new socket connection is established and one more poll is used to wait for data.

Take a look at the constructor,

SensorService::SensorEventConnection::SensorEventConnection(
        const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
        const String16& opPackageName, bool hasSensorAccess)
    : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
      mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL),
      mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName),
      mDestroyed(false), mHasSensorAccess(hasSensorAccess) {
    mChannel = new BitTube(mService->mSocketBufferSize);
#if DEBUG_CONNECTIONS
    mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
    mTotalAcksNeeded = mTotalAcksReceived = 0;
#endif
}

Mainly to save application information,
2 package names, respectively,
packageName: application package name;
opPackageName: java vm name, obtained
in android/frameworks/base/services/core/jni/com_android_server_SystemServer.cpp 
android_server_SystemServer_startHidlServices() and passed in.

The focus of this class is its SensorEventConnection::sendEvents() function, which sends data to the application. Therefore, if you encounter the problem that the application cannot obtain sensor data, you can also debug here, including

a. Multiple applications register the same sensor. Some applications receive data and some do not;

b. All applications have not received certain sensor data;

c, all sensors have no data;

You can print mPackageName and sensor type, sensor data, sensor timestamp here, or dump sensorservice after unified storage.

(3) SensorEventQueue

SensorEventQueue has multiple class implementations. The main one here is the SensorEventQueue used in SensorService, which is defined in android/frameworks/native/libs/sensor/. When the
application registers a sensor, a java class SensorEventQueue will be created in the SystemSensorManager. Here we will create the C++ class SensorEventQueue we are going to talk about.
When the sensor data arrives, the SensorEventQueue will give the data to the application through the onSensorChanged() interface implemented by the callback application.

//在这儿创建,android/frameworks/native/libs/sensor/SensorManager.cpp
sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) {
    sp<SensorEventQueue> queue;

    Mutex::Autolock _l(mLock);
    while (assertStateLocked() == NO_ERROR) {
		//向SensorService请求创建connection,最后调用 SensorService::createSensorEventConnection()
        sp<ISensorEventConnection> connection =
                mSensorServer->createSensorEventConnection(packageName, mode, mOpPackageName);
        if (connection == NULL) {
            // SensorService just died or the app doesn't have required permissions.
            ALOGE("createEventQueue: connection is NULL.");
            return NULL;
        }
		//将前边创建的SensorEventConnection,作为SensorEventQueue构造函数的参数传进去,
		//创建SensorEventQueue
        queue = new SensorEventQueue(connection);
        break;
    }
    return queue;
}

Under what circumstances is it created? The creation process is discussed in the process of registering a sensor in the application.

//接下来看下构造函数,
SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection)
    : mSensorEventConnection(connection), mRecBuffer(NULL), mAvailable(0), mConsumed(0),
      mNumAcksToSend(0) {
    mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT];
}

The constructor is very simple. It creates mRecBuffer to store the data sent from SensorEventConnection.

Among them,
SensorEventQueue::write() is used to send data to SensorEventConnection, and
SensorEventQueue::read() is used to read data to the application.

ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
        ASensorEvent const* events, size_t numEvents) {
    return BitTube::sendObjects(tube, events, numEvents);
}
ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {
    if (mAvailable == 0) {
        ssize_t err = BitTube::recvObjects(mSensorChannel,
                mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
        if (err < 0) {
            return err;
        }
        mAvailable = static_cast<size_t>(err);
        mConsumed = 0;
    }
    size_t count = min(numEvents, mAvailable);
    memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent));
    mAvailable -= count;
    mConsumed += count;
    return static_cast<ssize_t>(count);
}

3. Apply to register a sensor process

Let’s first look at the code for the application to simply register a sensor.


    private SensorManager mSensorManager;
    private Sensor mSensor;
    //获取sensorManager      
    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);//申请的为加速度传感器
    mSensorManager.registerListener(mSensorEventListener,mSensor,SensorManager.SENSOR_DELAY_NORMAL);
    final SensorEventListener mSensorEventListener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent sensorEvent) {
         //有数据时该接口被回调,在这边使用sensor数据
            Log.i(TAG,"sensorEvent.sensor.getType():" + sensorEvent.sensor.getType());
            if(sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
                //add you code
            }
 
        }
        @Override
        public void onAccuracyChanged(Sensor sensor, int i) {
            //add your code
 
        }

Let’s look at registerListener() first. Google has implemented several of them for application developers to use. We can just pick one and start following it, because in the end, the interface SystemSensorManager::registerListenerImpl() is called.

android/frameworks/base/core/java/android/hardware/SensorManager.java

public boolean registerListener(SensorEventListener listener, Sensor sensor,
        int samplingPeriodUs, int maxReportLatencyUs, Handler handler) {
    int delayUs = getDelay(samplingPeriodUs);
    return registerListenerImpl(listener, sensor, delayUs, handler, maxReportLatencyUs, 0);
}
//接着看
//android/frameworks/base/core/java/android/hardware/SystemSensorManager.java
    protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
            int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
        android.util.SeempLog.record_sensor_rate(381, sensor, delayUs);
        if (listener == null || sensor == null) {
            Log.e(TAG, "sensor or listener is null");
            return false;
        }

        // Invariants to preserve:
        // - one Looper per SensorEventListener
        // - one Looper per SensorEventQueue
        //一个SensorEventListener对应一个SensorEventQueue
        // We map SensorEventListener to a SensorEventQueue, which holds the looper
        synchronized (mSensorListeners) {
            SensorEventQueue queue = mSensorListeners.get(listener);
            if (queue == null) {
                Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
                final String fullClassName =
                        listener.getClass().getEnclosingClass() != null
                            ? listener.getClass().getEnclosingClass().getName()
                            : listener.getClass().getName();
                //这边创建SensorEventQueue
                //并装在hashmap mSensorListeners里边
                queue = new SensorEventQueue(listener, looper, this, fullClassName);
                if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
                    queue.dispose();
                    return false;
                }
                mSensorListeners.put(listener, queue);
                return true;
            } else {
                return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
            }
        }
    }

If the SensorEventListener (created by the application itself) has not created a SensorEventQueue before, then create one and add it to mSensorListeners together with the SensorEventListener. The
key point is how the sensor data is fed from the bottom layer and the application's onSensorChanged() is called back. When a SensorEventQueue is created, its parent class object BaseEventQueue will be constructed at the same time, and then in its nativeInitBaseEventQueue() method, android/frameworks/base/core/jni/android_hardware_SensorManager.cpp nativeInitSensorEventQueue()
is called through jni to create a Receiver that receives data. Object, after this analysis data will be uploaded and then analyzed in detail.

Next, look at the registration process, and then continue the process of registering a sensor through BaseEventQueue::addSensor().

public boolean addSensor(
        Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {
    // Check if already present.
    int handle = sensor.getHandle();
    if (mActiveSensors.get(handle)) return false; 

    // Get ready to receive events before calling enable.
    mActiveSensors.put(handle, true);
    addSensorEvent(sensor);
    if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) {
        // Try continuous mode if batching fails.
        if (maxBatchReportLatencyUs == 0
                || maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
            removeSensor(sensor, false);
            return false;
        }
    }
    return true;
}

Continue down through BaseEventQueue::enableSensor()
and look at,

private int enableSensor(
        Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
    if (mNativeSensorEventQueue == 0) throw new NullPointerException();
    if (sensor == null) throw new NullPointerException();
    return nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs,
            maxBatchReportLatencyUs);


}

Call the C++ interface through jni,
and then look at,

android/frameworks/base/core/jni/android_hardware_SensorManager.cpp

static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us,
                               jint maxBatchReportLatency) {
    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
    return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,
                                                         0);
}

Next comes 
android/frameworks/native/libs/sensor/SensorEventQueue.cpp
SensorEventQueue::enableSensor()

There are several overloads here, but the parameters are different. Let’s just take a look at one of them. (TO DO: How to start this block will be analyzed later and how the sensor data is provided. Let’s follow the process directly)

status_t SensorEventQueue::enableSensor(int32_t handle, int32_t samplingPeriodUs,
                                        int64_t maxBatchReportLatencyUs, int reservedFlags) const {
    return mSensorEventConnection->enableDisable(handle, true, us2ns(samplingPeriodUs),
                                                 us2ns(maxBatchReportLatencyUs), reservedFlags);
}

接着就到了 
android/frameworks/native/services/sensorservice/SensorEventConnection.cpp
SensorService::SensorEventConnection::enableDisable()

status_t SensorService::SensorEventConnection::enableDisable(
        int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
        int reservedFlags)
{
    status_t err;
    if (enabled) {
        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
                               reservedFlags, mOpPackageName);

    } else {
        err = mService->disable(this, handle);
    }
    return err;
}

Next is SensorService::enable()

status_t SensorService::enable(const sp<SensorEventConnection>& connection,
        int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
        const String16& opPackageName) {
    if (mInitCheck != NO_ERROR)
        return mInitCheck;

    //获取到HardwareSensor,里边存储HAL层注册的sensor_t 类型结构体
    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);

    //检查应用是否有权限获取sensor数据
    if (sensor == nullptr ||
        !canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) {
        return BAD_VALUE;
    }

    Mutex::Autolock _l(mLock);
    if (mCurrentOperatingMode != NORMAL
           && !isWhiteListedPackage(connection->getPackageName())) {
        return INVALID_OPERATION;
    }
    //将来自应用的SensorEventConnection保存在SensorRecord,若之前没有一个应用开启该sensor,则创建SensorRecord,
    //将该SensorRecord和对应的sensor handle保存在mActiveSensors里边记录下来,
    SensorRecord* rec = mActiveSensors.valueFor(handle);
    if (rec == 0) {
        rec = new SensorRecord(connection);
        mActiveSensors.add(handle, rec);
        if (sensor->isVirtual()) {
            mActiveVirtualSensors.emplace(handle);
        }
    } else {
        if (rec->addConnection(connection)) {
            // this sensor is already activated, but we are adding a connection that uses it.
            // Immediately send down the last known value of the requested sensor if it's not a
            // "continuous" sensor.
            if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
                // NOTE: The wake_up flag of this event may get set to
                // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event.

                auto logger = mRecentEvent.find(handle);
                if (logger != mRecentEvent.end()) {
                    sensors_event_t event;
                    // It is unlikely that this buffer is empty as the sensor is already active.
                    // One possible corner case may be two applications activating an on-change
                    // sensor at the same time.
                    if(logger->second->populateLastEvent(&event)) {
                        event.sensor = handle;
                        if (event.version == sizeof(sensors_event_t)) {
                            if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
                                setWakeLockAcquiredLocked(true);
                            }
                            //若该sensor之前已经有其他应用注册着了,并且是on change类型的sensor,比如 proximity,
                            //那么将最新的一次事件送给应用
                            connection->sendEvents(&event, 1, NULL);
                            if (!connection->needsWakeLock() && mWakeLockAcquired) {
                                checkWakeLockStateLocked();
                            }
                        }
                    }
                }
            }
        }
    }

    if (connection->addSensor(handle)) {
        BatteryService::enableSensor(connection->getUid(), handle);
        // the sensor was added (which means it wasn't already there)
        // so, see if this connection becomes active
        if (mActiveConnections.indexOf(connection) < 0) {
            mActiveConnections.add(connection);//若该connection还没有保存在mActiveConnections,保存一下
        }
    } else {
        ALOGW("sensor %08x already enabled in connection %p (ignoring)",
            handle, connection.get());
    }

    // Check maximum delay for the sensor.
    nsecs_t maxDelayNs = sensor->getSensor().getMaxDelay() * 1000LL;
    if (maxDelayNs > 0 && (samplingPeriodNs > maxDelayNs)) {
        samplingPeriodNs = maxDelayNs;
    }

    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
    if (samplingPeriodNs < minDelayNs) {
        samplingPeriodNs = minDelayNs;
    }

    ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d"
                                "rate=%" PRId64 " timeout== %" PRId64"",
             handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
    ///enable sensor的时候先batch和翻录是一下,目的是清除一下数据?
    status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs,
                                 maxBatchReportLatencyNs);

    // Call flush() before calling activate() on the sensor. Wait for a first
    // flush complete event before sending events on this connection. Ignore
    // one-shot sensors which don't support flush(). Ignore on-change sensors
    // to maintain the on-change logic (any on-change events except the initial
    // one should be trigger by a change in value). Also if this sensor isn't
    // already active, don't call flush().
    if (err == NO_ERROR &&
            sensor->getSensor().getReportingMode() == AREPORTING_MODE_CONTINUOUS &&
            rec->getNumConnections() > 1) {
        connection->setFirstFlushPending(handle, true);
        status_t err_flush = sensor->flush(connection.get(), handle);
        // Flush may return error if the underlying h/w sensor uses an older HAL.
        if (err_flush == NO_ERROR) {
            rec->addPendingFlushConnection(connection.get());
        } else {
            connection->setFirstFlushPending(handle, false);
        }
    }

    //关键就在这儿
    //调用 HardwareSensor::activate() ==> SensorDevice::activate()
    if (err == NO_ERROR) {
        ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
        err = sensor->activate(connection.get(), true);
    }
	
    if (err == NO_ERROR) {
        connection->updateLooperRegistration(mLooper);
		//记录调用者和对应sensor信息,后面可用dumpsys sensorservice dump出来debug问题
        mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex) =
                SensorRegistrationInfo(handle, connection->getPackageName(),
                                       samplingPeriodNs, maxBatchReportLatencyNs, true);
        mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE;
    }
	
	//若调用失败,则将与应用的链接直接清掉
    if (err != NO_ERROR) {
        // batch/activate has failed, reset our state.
        cleanupWithoutDisableLocked(connection, handle);
    }
    return err;
}

Next look at SensorDevice::activate()

status_t SensorDevice::activate(void* ident, int handle, int enabled) {
    if (mSensors == nullptr) return NO_INIT;

    status_t err(NO_ERROR);
    bool actuateHardware = false;

    Mutex::Autolock _l(mLock);
    ssize_t activationIndex = mActivationCount.indexOfKey(handle);
    if (activationIndex < 0) {
        ALOGW("Handle %d cannot be found in activation record", handle);
        return BAD_VALUE;
    }
    Info& info(mActivationCount.editValueAt(activationIndex));//从这里边获取到Info

    ALOGD_IF(DEBUG_CONNECTIONS,
             "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
             ident, handle, enabled, info.batchParams.size());

    if (enabled) {
        ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));

        if (isClientDisabledLocked(ident)) {
            ALOGE("SensorDevice::activate, isClientDisabledLocked(%p):true, handle:%d",
                    ident, handle);
            return INVALID_OPERATION;
        }

        if (info.batchParams.indexOfKey(ident) >= 0) {
		  //若是第一个注册该sensor的应用,那么需要调用HAL层的activate()
          if (info.numActiveClients() == 1) {
              // This is the first connection, we need to activate the underlying h/w sensor.
              actuateHardware = true;
          }
        } else {
            // Log error. Every activate call should be preceded by a batch() call.
            ALOGE("\t >>>ERROR: activate called without batch");
        }
    } else {
        ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));

        // If a connected dynamic sensor is deactivated, remove it from the
        // dictionary.
        auto it = mConnectedDynamicSensors.find(handle);
        if (it != mConnectedDynamicSensors.end()) {
            delete it->second;
            mConnectedDynamicSensors.erase(it);
        }

        if (info.removeBatchParamsForIdent(ident) >= 0) {
			//若是最后一个反注册该sensor的应用,那么需要调用HAL层的activate(),
			//否则就重新batch一下
            if (info.numActiveClients() == 0) {
                // This is the last connection, we need to de-activate the underlying h/w sensor.
                actuateHardware = true;
            } else {
                // Call batch for this sensor with the previously calculated best effort
                // batch_rate and timeout. One of the apps has unregistered for sensor
                // events, and the best effort batch parameters might have changed.
                ALOGD_IF(DEBUG_CONNECTIONS,
                         "\t>>> actuating h/w batch 0x%08x %" PRId64 " %" PRId64, handle,
                         info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
                checkReturn(mSensors->batch(
                        handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch));
            }
        } else {
            // sensor wasn't enabled for this ident
        }

        if (isClientDisabledLocked(ident)) {
            return NO_ERROR;
        }
    }

    if (actuateHardware) {
        ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
                 enabled);
		//这儿通过hidl调用HAL层的接口,源码在/android/hardware/interfaces/sensors/1.0,
        err = StatusFromResult(checkReturn(mSensors->activate(handle, enabled)));
        ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
                 strerror(-err));

        if (err != NO_ERROR && enabled) {
            // Failure when enabling the sensor. Clean up on failure.
            info.removeBatchParamsForIdent(ident);
        }
    }

    return err;
}

Next, through hidl, we get to HAL. First we go to the hal layer implemented by android itself, let’s call it android sensor hal. Then we go down to the hal layer implemented by the mobile phone manufacturer itself, which is called OEM sensor hal.

Here we also look directly at the process, and we will analyze the startup of android sensor hal later.

android/hardware/interfaces/sensors/1.0/default/Sensors.cpp

Return<Result> Sensors::activate(
        int32_t sensor_handle, bool enabled) {
    return ResultFromStatus(
            mSensorDevice->activate(
                reinterpret_cast<sensors_poll_device_t *>(mSensorDevice),
                sensor_handle,
                enabled));
}

Then came

android/hardware/libhardware/modules/sensors/multihal.cpp

static int device__activate(struct sensors_poll_device_t *dev, int handle,
        int enabled) {
//留意这边有个强转,其实dev就是sensors_poll_context_t*类型,只是后面为了方便存储,
//就只是存了一个第一个成员变量首地址,通过这个地址可以获取到其父类,父类的父类的地址,
    sensors_poll_context_t* ctx = (sensors_poll_context_t*) dev;
    return ctx->activate(handle, enabled);
}

 Next is

int sensors_poll_context_t::activate(int handle, int enabled) {
    int retval = -EINVAL;
    ALOGV("activate");
    int local_handle = get_local_handle(handle);
    sensors_poll_device_t* v0 = this->get_v0_device_by_handle(handle);

    if (halIsCompliant(this, handle) && local_handle >= 0 && v0) {
        retval = v0->activate(v0, local_handle, enabled);

    } else {
        ALOGE("IGNORING activate(enable %d) call to non-API-compliant sensor handle=%d !",
                enabled, handle);
    }
    ALOGV("retval %d", retval);
    return retval;
}

Further down here is the interface implemented by the mobile phone manufacturer itself, and the android part ends here.

4. How does SensorService provide sensor data to the application?

To put it simply, SensorService uses SensorEventConnection as the data sending end, and the application side uses SensorEventListerner as the data receiving end. Data is transmitted through unix socket. We can analyze it from the two ends respectively.

Let’s first look at the sending end from the SensorService side. After the SensorService is constructed, it creates a thread threadLoop() that runs continuously, and retrieves sensor data from the hal layer through poll (this poll has the same name as the Linux C standard function poll(), and has similar functions. Instead of calling the poll() function of the Linux C standard), when there is no sensor data, it will continue to block and wait (this blocking function is implemented by the HAL layer). When data comes up, it will be sent after doing some processing and judgment. to the application,

The processing judgment includes whether the data should be discarded, saving the data in a vector-implemented cache so that it can be dumped for debugging later, whether it is flush data, whether the data should be given to the fusion sensor, whether the application has closed the sensor, and whether the application has entered idle. etc.

//从SensorService::threadLoop()开始看,
bool SensorService::threadLoop() {
    ALOGD("nuSensorService thread starting...");

    // each virtual sensor could generate an event per "real" event, that's why we need to size
    // numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.  in practice, this is too
    // aggressive, but guaranteed to be enough.
    const size_t vcount = mSensors.getVirtualSensors().size();
    const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
    const size_t numEventMax = minBufferSize / (1 + vcount);
    //为何要这么做,再解释一下,比如说这边有vcount个虚拟的 sensor跑在framework,
    //那么比较极端的情况下每从HAL取numEventMax个数据,这边vcount个sensor会各生成numEventMax个数据,
    //而mSensorEventBuffer 最多只能容纳 MAX_RECEIVE_BUFFER_EVENT_COUNT个数据,
    //所以 numEventMax = minBufferSize / (1 + vcount);

    SensorDevice& device(SensorDevice::getInstance());

    const int halVersion = device.getHalDeviceVersion();
    do {
        //通过SensorDevice往HAL层取数据, 若没有数据的时候就一直阻塞(这个由前面说的HAL层实现)
        //当有数据时该函数就会返回
        ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
        if (count < 0) {
            ALOGE("sensor poll failed (%s)", strerror(-count));
            break;

        }

        // Reset sensors_event_t.flags to zero for all events in the buffer.
        for (int i = 0; i < count; i++) {
             mSensorEventBuffer[i].flags = 0;
        }

        // Make a copy of the connection vector as some connections may be removed during the course
        // of this loop (especially when one-shot sensor events are present in the sensor_event
        // buffer). Promote all connections to StrongPointers before the lock is acquired. If the
        // destructor of the sp gets called when the lock is acquired, it may result in a deadlock
        // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the
        // strongPointers to a vector before the lock is acquired.
        SortedVector< sp<SensorEventConnection> > activeConnections;
        populateActiveConnections(&activeConnections);

        Mutex::Autolock _l(mLock);
        // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
        // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
        // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
        // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
        // releasing the wakelock.
        bool bufferHasWakeUpEvent = false;
        for (int i = 0; i < count; i++) {
            if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
                bufferHasWakeUpEvent = true;
                break;
            }
        }
		//若有wakeup 类型sensor上报的数据就持有wakelock
        if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
            setWakeLockAcquiredLocked(true);
        }
        recordLastValueLocked(mSensorEventBuffer, count);//将事件保存下来,后面可以用dumpsys sensorservice dump出来方便分析问题

        // 暂时可先忽略handle virtual sensor,dynamic sensor部分不看
		
		
        // Send our events to clients. Check the state of wake lock for each client and release the
        // lock if none of the clients need it.
        bool needsWakeLock = false;
        size_t numConnections = activeConnections.size();
        for (size_t i=0 ; i < numConnections; ++i) {
            if (activeConnections[i] != 0) {
            //通过SensorEventConnection 将数据给到每个应用,每个应用都有自己的SensorEventConnection,好就是这里,再跟进去
                activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
                        mMapFlushEventsToConnections);
                needsWakeLock |= activeConnections[i]->needsWakeLock();
                // If the connection has one-shot sensors, it may be cleaned up after first trigger.
                // Early check for one-shot sensors.
                if (activeConnections[i]->hasOneShotSensors()) {
                    cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
                            count);
                }
            }
        }
		
		//若还有wake up 类型的sensor报上来的数据的话,需要继续持有wakelock
       
        if (mWakeLockAcquired && !needsWakeLock) {
            setWakeLockAcquiredLocked(false);
        }
    } while (!Thread::exitPending());

    ALOGW("Exiting SensorService::threadLoop => aborting...");
    abort();
    return false;
}

In other words, SensorService::threadLoop() obtains sensor data from the hal layer through SensorDevice.

The data is further processed and sent through SensorService::SensorEventConnection::sendEvents(). Please note that there are multiple SensorEventConnections that belong to different applications. In sendEvents(), each application processes its own.

Look next,

status_t SensorService::SensorEventConnection::sendEvents(
        sensors_event_t const* buffer, size_t numEvents,
        sensors_event_t* scratch,
        wp<const SensorEventConnection> const * mapFlushEventsToConnections) {
    // filter out events not for this connection

    sensors_event_t* sanitizedBuffer = nullptr;

    int count = 0;
    Mutex::Autolock _l(mConnectionLock); 
    if (scratch) {
        size_t i=0;
        while (i<numEvents) {
            //每个数据琢一处理
            int32_t sensor_handle = buffer[i].sensor;
            if (buffer[i].type == SENSOR_TYPE_META_DATA) {
                ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
                        buffer[i].meta_data.sensor);
                // Setting sensor_handle to the correct sensor to ensure the sensor events per
                // connection are filtered correctly.  buffer[i].sensor is zero for meta_data
                // events.
                sensor_handle = buffer[i].meta_data.sensor;
            }

            ssize_t index = mSensorInfo.indexOfKey(sensor_handle);
            //enable 一个sensor时,会保存该sensor的handle
            //确认一下若该sensor已经被disable了,那么就没有必要将该sensor的数据给到应用了
            //或者该应用没有注册该sensor的话,也是直接过滤掉
            // Check if this connection has registered for this sensor. If not continue to the
            // next sensor_event.
            if (index < 0) {
                ++i;
                continue;
            }

            FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
            // Check if there is a pending flush_complete event for this sensor on this connection.
            if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
                    mapFlushEventsToConnections[i] == this) {
                flushInfo.mFirstFlushPending = false;
                ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
                        buffer[i].meta_data.sensor);
                ++i;
                continue;
            }

            // If there is a pending flush complete event for this sensor on this connection,
            // ignore the event and proceed to the next.
            if (flushInfo.mFirstFlushPending) {
                ++i;
                continue;
            }

            //过滤掉flush的数据后,将要给到应用的数据拷到scratch
            do {
                // Keep copying events into the scratch buffer as long as they are regular
                // sensor_events are from the same sensor_handle OR they are flush_complete_events
                // from the same sensor_handle AND the current connection is mapped to the
                // corresponding flush_complete_event.
                if (buffer[i].type == SENSOR_TYPE_META_DATA) {
                    if (mapFlushEventsToConnections[i] == this) {
                        scratch[count++] = buffer[i];
                    }
                } else {
                    // Regular sensor event, just copy it to the scratch buffer.
					//若为false,即应用进入idle,那么就不将数据装进scratch在通过scratch给到应用,
                    //否则就装进去
                    if (mHasSensorAccess) {
                        scratch[count++] = buffer[i];
                    }
                }
                i++;
            } while ((i<numEvents) && ((buffer[i].sensor == sensor_handle &&
                                        buffer[i].type != SENSOR_TYPE_META_DATA) ||
                                       (buffer[i].type == SENSOR_TYPE_META_DATA  &&
                                        buffer[i].meta_data.sensor == sensor_handle)));
        }
    } else {
	    //这边不会走到不用管,感觉google这段代码有点多余哈哈
        if (mHasSensorAccess) {
            scratch = const_cast<sensors_event_t *>(buffer);
            count = numEvents;
        } else {
            scratch = sanitizedBuffer = new sensors_event_t[numEvents];
            for (size_t i = 0; i < numEvents; i++) {
                if (buffer[i].type == SENSOR_TYPE_META_DATA) {
                    scratch[count++] = buffer[i++];
                }
            }
        }
    }

    sendPendingFlushEventsLocked();
    // Early return if there are no events for this connection.
    if (count == 0) {
        delete sanitizedBuffer;//可能遇到空指针?  free 已经做了判断了
        return status_t(NO_ERROR);
    }



#if DEBUG_CONNECTIONS
     mEventsReceived += count;
#endif
//将最新的数据缓存到mEventCache,后面可以dump出来debug
    if (mCacheSize != 0) {
        // There are some events in the cache which need to be sent first. Copy this buffer to
        // the end of cache.
        if (mCacheSize + count <= mMaxCacheSize) {
            memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
            mCacheSize += count;
        } else {
            // Check if any new sensors have registered on this connection which may have increased
            // the max cache size that is desired.
            if (mCacheSize + count < computeMaxCacheSizeLocked()) {
                reAllocateCacheLocked(scratch, count);
                delete sanitizedBuffer;
                return status_t(NO_ERROR);
            }
            // Some events need to be dropped.
            int remaningCacheSize = mMaxCacheSize - mCacheSize;
            if (remaningCacheSize != 0) {
                memcpy(&mEventCache[mCacheSize], scratch,
                                                remaningCacheSize * sizeof(sensors_event_t));
            }
            int numEventsDropped = count - remaningCacheSize;
            countFlushCompleteEventsLocked(mEventCache, numEventsDropped);
            // Drop the first "numEventsDropped" in the cache.
            memmove(mEventCache, &mEventCache[numEventsDropped],
                    (mCacheSize - numEventsDropped) * sizeof(sensors_event_t));

            // Copy the remainingEvents in scratch buffer to the end of cache.
            memcpy(&mEventCache[mCacheSize - numEventsDropped], scratch + remaningCacheSize,
                                            numEventsDropped * sizeof(sensors_event_t));
        }
        delete sanitizedBuffer;
        return status_t(NO_ERROR);
    }

    int index_wake_up_event = -1;
    if (mHasSensorAccess) {
        index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
        if (index_wake_up_event >= 0) {
            scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
            ++mWakeLockRefCount;
#if DEBUG_CONNECTIONS
            ++mTotalAcksNeeded;
#endif
        }
    }

    // NOTE: ASensorEvent and sensors_event_t are the same type.
	

    //重点在这边,把scratch里边的数据发出去,
	
    ssize_t size = SensorEventQueue::write(mChannel,
                                    reinterpret_cast<ASensorEvent const*>(scratch), count);
    if (size < 0) {
        // Write error, copy events to local cache.
        if (index_wake_up_event >= 0) {
            // If there was a wake_up sensor_event, reset the flag.
            scratch[index_wake_up_event].flags &= ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
            if (mWakeLockRefCount > 0) {
                --mWakeLockRefCount;
            }
#if DEBUG_CONNECTIONS
            --mTotalAcksNeeded;
#endif
        }
        if (mEventCache == NULL) {
            mMaxCacheSize = computeMaxCacheSizeLocked();
            mEventCache = new sensors_event_t[mMaxCacheSize];
            mCacheSize = 0;
        }
        memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
        mCacheSize += count;

        // Add this file descriptor to the looper to get a callback when this fd is available for
        // writing.
        updateLooperRegistrationLocked(mService->getLooper());
        delete sanitizedBuffer;
        return size;
    }

}

Next, follow 
ssize_t SensorEventQueue::write(const sp<BitTube>& tube, ASensorEvent const* events, size_t numEvents)
to see how to send data to the application through the onSensorChange() interface.

android/frameworks/native/libs/sensor/SensorEventQueue.cpp

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

看一下 
ssize_t BitTube::sendObjects(const sp<BitTube>& tube, void const* events, size_t count, size_t objSize)

android/frameworks/native/libs/sensor/BitTube.cpp

ssize_t BitTube::sendObjects(const sp<BitTube>& tube,
        void const* events, size_t count, size_t objSize)
{
    //SensorService::SensorEventConnection::mChannel::write()
    //mChannel 为 BitTube 对象
    const char* vaddr = reinterpret_cast<const char*>(events);
    ssize_t size = tube->write(vaddr, count*objSize);

    // should never happen because of SOCK_SEQPACKET
    LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
            "BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were sent!)",
            count, objSize, size);

    //ALOGE_IF(size<0, "error %d sending %d events", size, count);
  

Then we come to BitTube::write(void const* vaddr, size_t size), and then look at

ssize_t BitTube::write(void const* vaddr, size_t size)
{
    ssize_t err, len;
    do {
	//这边通过 unix域套接字 发出去
        len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
        // cannot return less than size, since we're using SOCK_SEQPACKET
        err = len < 0 ? errno : 0;
    } while (err == EINTR);
    return err == 0 ? len : -err;
}

Next, we need to analyze it from the receiving end and see where it is received (received in android_hardware_SensorManager.cpp Receiver).
What is the specific process? We need to go back to the application to register a sensor through SensorManager.

 protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
            int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
        android.util.SeempLog.record_sensor_rate(381, sensor, delayUs);
        if (listener == null || sensor == null) {
            Log.e(TAG, "sensor or listener is null");
            return false;
        }

        // Invariants to preserve:
        // - one Looper per SensorEventListener
        // - one Looper per SensorEventQueue
		//一个SensorEventListener对应一个SensorEventQueue,并装在hashmap mSensorListeners里边
        // We map SensorEventListener to a SensorEventQueue, which holds the looper
        synchronized (mSensorListeners) {
            SensorEventQueue queue = mSensorListeners.get(listener);
            if (queue == null) {
                Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
                final String fullClassName =
                        listener.getClass().getEnclosingClass() != null
                            ? listener.getClass().getEnclosingClass().getName()
                            : listener.getClass().getName();
                queue = new SensorEventQueue(listener, looper, this, fullClassName);
                if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
                    queue.dispose();
                    return false;
                }
                mSensorListeners.put(listener, queue);
                return true;
            } else {
                return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
            }
        }
    }

If the SensorEventListener (created by the application itself) has not created a SensorEventQueue before, then create one and add it to mSensorListeners together with the SensorEventListener. The key point is
here. When a SensorEventQueue is created, its parent class object BaseEventQueue will be constructed at the same time, and then in In its nativeInitBaseEventQueue() method,
jni calls
android/frameworks/base/core/jni/android_hardware_SensorManager.cpp nativeInitSensorEventQueue()
to create a Receiver object that receives data.

static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
        jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) {
    SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
    ScopedUtfChars packageUtf(env, packageName);
    String8 clientName(packageUtf.c_str());
    sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));

    if (queue == NULL) {
        jniThrowRuntimeException(env, "Cannot construct native SensorEventQueue.");
        return 0;
    }

    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);//获取MessageQueue
    if (messageQueue == NULL) {
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
        return 0;
    }

    sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak);
    receiver->incStrong((void*)nativeInitSensorEventQueue);
    return jlong(receiver.get());
}

Create a SensorEventQueue based on clientName, then create a Receiver and take a look at its constructor.

Receiver(const sp<SensorEventQueue>& sensorQueue,
        const sp<MessageQueue>& messageQueue,
        jobject receiverWeak) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
	//保存传进来的2个比较关键的对象引用
    mSensorQueue = sensorQueue;
    mMessageQueue = messageQueue;
	
    mReceiverWeakGlobal = env->NewGlobalRef(receiverWeak);

    mIntScratch = (jintArray) env->NewGlobalRef(env->NewIntArray(16));
    mFloatScratch = (jfloatArray) env->NewGlobalRef(env->NewFloatArray(16));
}

Look at onFirstRef() again

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

}

//Get the created SensorEventQueue here==>The mReceiveFd created through unix socket in BitTube
is added to the looper.
In android/system/core/libutils/Looper.cpp Looper::pollInner()
, it will be monitored through epoll This fd, when there is an event, will call back Receiver::handleEvent(), and then look at

virtual int handleEvent(int fd, int events, void* data) {
        JNIEnv* env = AndroidRuntime::getJNIEnv();
        sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);
        ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
        ssize_t n;
        ASensorEvent buffer[16];
        //这边最后是通过标准的socket接口recv将数据读取出来,代码在以下位置:
        //android/frameworks/native/libs/sensor
        //SensorEventQueue::read() ==> BitTube::recvObjects()==>BitTube::read()
        while ((n = q->read(buffer, 16)) > 0) {
            for (int i=0 ; i<n ; i++) {
                if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) {
                    // step-counter returns a uint64, but the java API only deals with floats
                    float value = float(buffer[i].u64.step_counter);
                    env->SetFloatArrayRegion(mFloatScratch, 0, 1, &value);
                } else if (buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
                    float value[2];
                    value[0] = buffer[i].dynamic_sensor_meta.connected ? 1.f: 0.f;
                    value[1] = float(buffer[i].dynamic_sensor_meta.handle);
                    env->SetFloatArrayRegion(mFloatScratch, 0, 2, value);
                } else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
                    env->SetIntArrayRegion(mIntScratch, 0, 14,
                                           buffer[i].additional_info.data_int32);
                    env->SetFloatArrayRegion(mFloatScratch, 0, 14,
                                             buffer[i].additional_info.data_float);
                } else {
                    env->SetFloatArrayRegion(mFloatScratch, 0, 16, buffer[i].data);
                }

                if (buffer[i].type == SENSOR_TYPE_META_DATA) {
                    // This is a flush complete sensor event. Call dispatchFlushCompleteEvent
                    // method.
                    if (receiverObj.get()) {
                        env->CallVoidMethod(receiverObj.get(),
                                            gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
                                            buffer[i].meta_data.sensor);
                    }
                } else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
                    // This is a flush complete sensor event. Call dispatchAdditionalInfoEvent
                    // method.
                    if (receiverObj.get()) {
                        int type = buffer[i].additional_info.type;
                        int serial = buffer[i].additional_info.serial;
                        env->CallVoidMethod(receiverObj.get(),
                                            gBaseEventQueueClassInfo.dispatchAdditionalInfoEvent,
                                            buffer[i].sensor,
                                            type, serial,
                                            mFloatScratch,
                                            mIntScratch,
                                            buffer[i].timestamp);
                    }
                }else {
                    int8_t status;
                    switch (buffer[i].type) {
                    case SENSOR_TYPE_ORIENTATION:
                    case SENSOR_TYPE_MAGNETIC_FIELD:
                    case SENSOR_TYPE_ACCELEROMETER:
                    case SENSOR_TYPE_GYROSCOPE:
                    case SENSOR_TYPE_GRAVITY:
                    case SENSOR_TYPE_LINEAR_ACCELERATION:
                        status = buffer[i].vector.status;
                        break;
                    case SENSOR_TYPE_HEART_RATE:
                        status = buffer[i].heart_rate.status;
                        break;
                    default:
                        status = SENSOR_STATUS_ACCURACY_HIGH;
                        break;
                    }
            //关键就在这里,这边通过jni回调SystemSensorManager::dispatchSensorEvent(),将数据给SensorManager
					
					
                    if (receiverObj.get()) {
                        env->CallVoidMethod(receiverObj.get(),
                                            gBaseEventQueueClassInfo.dispatchSensorEvent, 
                                            buffer[i].sensor,
                                            mFloatScratch,
                                            status,
                                            buffer[i].timestamp);
                    }
                }
                if (env->ExceptionCheck()) {
                    mSensorQueue->sendAck(buffer, n);
                    ALOGE("Exception dispatching input event.");
                    return 1;
                }
            }
			//对SensorService::SensorEventConnection发送确认,
			//SensorService::SensorEventConnection::handleEvent()接收并确认
            mSensorQueue->sendAck(buffer, n);
        }
		        if (n<0 && n != -EAGAIN) {
            // FIXME: error receiving events, what to do in this case?
        }
        return 1;
    }
};
protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
                long timestamp) {
            final Sensor sensor = mManager.mHandleToSensor.get(handle);
            if (sensor == null) {
                // sensor disconnected
                return;
            }

            SensorEvent t = null;
            synchronized (mSensorsEvents) {
                t = mSensorsEvents.get(handle);
            }

            if (t == null) {
                // This may happen if the client has unregistered and there are pending events in
                // the queue waiting to be delivered. Ignore.
                return;
            }
            // Copy from the values array.
            System.arraycopy(values, 0, t.values, 0, t.values.length);
            t.timestamp = timestamp;
            t.accuracy = inAccuracy;
            t.sensor = sensor;

            // call onAccuracyChanged() only if the value changes
            final int accuracy = mSensorAccuracies.get(handle);
            if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
                mSensorAccuracies.put(handle, t.accuracy);
                mListener.onAccuracyChanged(t.sensor, t.accuracy);
            }
            mListener.onSensorChanged(t);//在这边,通过多态回调应用开发者自己实现的onSensorChanged(),将sensor事件给到应用
        }

At this point, the sensor data is given to the onSensorChanged() interface of the application.

5. SensorService behavior after standby

The main related class is SensorService::UidPolicy, and the related interfaces are SensorService::setSensorAccess() and SensorEventConnection::setSensorAccess(),

The general logic is that SensorService will use UidPolicy and then ActivityManager to monitor which newly created applications, which applications enter idle, and which applications exit, then when the application registers the sensor and enters idle, the data will not be sent to the application.

    class UidPolicy : public BnUidObserver {
        public:
            explicit UidPolicy(wp<SensorService> service)
                    : mService(service) {}
            void registerSelf();
            void unregisterSelf();

            bool isUidActive(uid_t uid);
			
			//这三个接口重载实现了IUidObserver 声明的接口,
			//后面通过多态被调用
            void onUidGone(uid_t uid, bool disabled);
            void onUidActive(uid_t uid);
            void onUidIdle(uid_t uid, bool disabled);


            void addOverrideUid(uid_t uid, bool active);
            void removeOverrideUid(uid_t uid);
        private:
            bool isUidActiveLocked(uid_t uid);
            void updateOverrideUid(uid_t uid, bool active, bool insert);

            Mutex mUidLock;
            wp<SensorService> mService;
            std::unordered_set<uid_t> mActiveUids;
            std::unordered_map<uid_t, bool> mOverrideUids;
    };

What this class does is very simple. Before analyzing it, let’s take a look at SensorService::setSensorAccess() and SensorEventConnection::setSensorAccess()
 

void SensorService::setSensorAccess(uid_t uid, bool hasAccess) {
    SortedVector< sp<SensorEventConnection> > activeConnections;
    populateActiveConnections(&activeConnections);
    {
        Mutex::Autolock _l(mLock);
        for (size_t i = 0 ; i < activeConnections.size(); i++) {
		     //获取到该uid对应的SensorEventConnection
            //每个应用有各自的SensorEventConnection,在创建 SensorEventListerner的时候创建,
            //有一个或多个,具体有几个取决于应用创建多少个SensorEventListerner
            if (activeConnections[i] != 0 && activeConnections[i]->getUid() == uid) {
                activeConnections[i]->setSensorAccess(hasAccess);
            }
        }
    }
}

void SensorService::SensorEventConnection::setSensorAccess(const bool hasAccess) {
    Mutex::Autolock _l(mConnectionLock);
    mHasSensorAccess = hasAccess;//将mHasSensorAccess置成true/false
}

After that, the application's SensorEventConnection::mHasSensorAccess is false, then the data will not be sent to the corresponding application.

status_t SensorService::SensorEventConnection::sendEvents(
        sensors_event_t const* buffer, size_t numEvents,
        sensors_event_t* scratch,
        wp<const SensorEventConnection> const * mapFlushEventsToConnections) {

	//......
    if (mHasSensorAccess) {
        scratch[count++] = buffer[i];
    
	}

	//......
		
}

Look next,

void SensorService::UidPolicy::registerSelf() {
    ActivityManager am;
    am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
            | ActivityManager::UID_OBSERVER_IDLE
            | ActivityManager::UID_OBSERVER_ACTIVE,
            ActivityManager::PROCESS_STATE_UNKNOWN,
            String16("android"));
}

It is called in SensorService::onFirstRef(). As mentioned before when analyzing the startup of SensorService, after
registration, it starts to monitor the standby state of the application (the creation, destruction and entry of idle of the application process)

After the application enters idle, this interface is called back. By passing in its corresponding uid,
you can use the command am make-uid-idle com.example.applicationtestproject to force the application to enter idle for debugging.

void SensorService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
    ALOGI("%s , uid : %x", __FUNCTION__, (int)uid);
    bool deleted = false;
    {
        Mutex::Autolock _l(mUidLock);
        if (mActiveUids.erase(uid) > 0) {
            deleted = true;
        }
    }
    if (deleted) {
        sp<SensorService> service = mService.promote();
        if (service != nullptr) {
            service->setSensorAccess(uid, false);
			//应用进入idle后,这边设置对应 mHasSensorAccess 为false,那么之后sensor数据就不给应用了
        }
    }
}

 

void SensorService::UidPolicy::onUidActive(uid_t uid) {
    ALOGI("%s , uid : %x", __FUNCTION__, (int)uid);
    {
        Mutex::Autolock _l(mUidLock);
        mActiveUids.insert(uid);
    }
    sp<SensorService> service = mService.promote();
    if (service != nullptr) {
        service->setSensorAccess(uid, true);//置对应 mHasSensorAccess 为 true
    }
}

This interface is called back by ActivityManager after the application exits idle.

To put it simply, the standby-related mechanism implemented by Google in Android9's SensorService is that after the application enters idle,
sensor data will not be given to the application to ensure that user privacy is not obtained.
For mobile phone manufacturers, in order to save power consumption, they can actually make an optimization here, that is, when all applications holding the sensor enter idle,
all sensors will be turned off.

6. Fusion sensor (SensorFusion)

SensorFusion can probably virtualize sensors here, take data from multiple sensors, and then combine it with other information as input, and finally output virtual sensor data through algorithm processing. Basically, it will not be used
by mobile phone manufacturers. One reason is that To reduce power consumption, it is implemented in the driver. Another reason is that this function is gone after the user flashes a third-party ROM. Therefore, if it is not implemented in the driver layer, it will also be implemented in the vendor layer, and I will not analyze it here.


7. Compile SensorService

Directly mm in the android/frameworks/native/service/SensorService directory,

After compilation, libsensorservice.so is generated in the out directory, and there is one in system/lib system/lib64. Just push it to the corresponding directory of the mobile phone.

adb root

adb remount

adb push out/....../system/lib/libsensorservice.so /system/lib

adb push out/....../system/lib64/libsensorservice.so /system/lib64

8,  dumpsys sensorservice

SensorService implements the dump interface. When debugging problems, you can 
dump the sensor information through adb shell dumpsys sensorservice to assist in analysis. The current dump interface mainly contains the following information:
(1) Apply to all available sensors on the mobile phone, including android Defined sensors and manufacturer-defined sensors
(2) Several sensors are currently enabled by the application, corresponding to the application package name
(3) The most recent sensor data;
(4) The most recent sensor switch record, and the corresponding application package name

9. Android sensor hal layer starts

 

The sensor hal layer implemented by Android runs as a daemon service and is called through hidl. The code location is: android/hardware/interfaces/sensors/1.0. The interface provided by
android/hardware/libhardware/modules/sensors is defined in
In ISensors.hal, there are mainly
getSensorsList()//Get all sensor linked lists
activate()//Open/close a sensor
poll()//Get sensor data
batch()//Set the sampling rate
flush()//Refresh the buffer

As can be seen from Android.bp,

cc_binary {
    name: "[email protected]",
    relative_install_path: "hw",
    vendor: true,
    init_rc: ["[email protected]"],
    defaults: ["hidl_defaults"],
    srcs: ["service.cpp"],

    shared_libs: [
        "liblog",
        "libcutils",
        "libdl",
        "libbase",
        "libutils",
        "libhidlbase",
        "libhidltransport",
        "[email protected]",
        "libhwbinder",
    ],
    arch: {
        arm: {
            cflags: ["-DARCH_ARM_32"],
        },
    },
}

The service name is [email protected],

Compile service.cpp into a bin program and start it through [email protected],
service vendor.sensors-hal-1-0 /vendor/bin/hw/[email protected]
    class hal
    user system
    group system wakelock input
    capabilities BLOCK_SUSPEND
    rlimit rtprio 10 10

Take a look at service.cpp

int main() {
#ifdef ARCH_ARM_32
    android::hardware::ProcessState::initWithMmapSize((size_t)getHWBinderMmapSize());
#endif
    /* Sensors framework service needs at least two threads.
     * One thread blocks on a "poll"
     * The second thread is needed for all other HAL methods.
     */
    return defaultPassthroughServiceImplementation<ISensors>(2);
}

Register yourself as a service in ServiceManager through defaultPassthroughServiceImplementation().

Starting from Sensors.cpp,
//The first function called by ServiceManager is this function

ISensors *HIDL_FETCH_ISensors(const char * /* hal */) {
    Sensors *sensors = new Sensors;
    LOG(ERROR) << "=======>lkh HIDL_FETCH_ISensors";
    android::CallStack stack("=======>lkh ");
    if (sensors->initCheck() != OK) {
        delete sensors;
        sensors = nullptr;

        return nullptr;
    }

    return sensors;
}

Create a Sensors instance, and then all interfaces that call sensor hal through hidl will call the interface implemented by Sensors.

Sensors::Sensors()
    : mInitCheck(NO_INIT),
      mSensorModule(nullptr),
      mSensorDevice(nullptr) {
    status_t err = OK;
    //若文件/vendor/etc/sensors/hals.conf存在, 
    //打开哪些库就根据这个配置文件里边的库的名字来打开,
    //供应商要开发自己sensor库的话,也可以将自己的库名字添加进去,
    //比如高通骁龙845 855,hal层库名字叫sensors-hal,直接在hals.conf 填下 sensors-hal就ok了,
    LOG(ERROR) << "=======>lkh Sensors construct";
    android::CallStack stack("=======>lkh ");
    if (UseMultiHal()) {
        mSensorModule = ::get_multi_hal_module_info();
    } else {
        err = hw_get_module(
            SENSORS_HARDWARE_MODULE_ID,
            (hw_module_t const **)&mSensorModule);
    }
    if (mSensorModule == NULL) {
        err = UNKNOWN_ERROR;
    }

    if (err != OK) {
        LOG(ERROR) << "Couldn't load "
                   << SENSORS_HARDWARE_MODULE_ID
                   << " module ("
                   << strerror(-err)
                   << ")";

        mInitCheck = err;
        return;
    }

	//当这个函数返回时,mSensorDevice里边装的是
	//multihal.cpp  open_sensors()里边的 dev->proxy_device 
	//所以之后 mSensorDevice->activate(),mSensorDevice->poll(),mSensorDevice->batch()等接口调用,
	//其实现都是调用了multihal.cpp 的device__activate(),device__poll(),device__batch()
    err = sensors_open_1(&mSensorModule->common, &mSensorDevice);

    if (err != OK) {
        LOG(ERROR) << "Couldn't open device for module "
                   << SENSORS_HARDWARE_MODULE_ID
                   << " ("
                   << strerror(-err)
                   << ")";

        mInitCheck = err;
        return;
    }

    // Require all the old HAL APIs to be present except for injection, which
    // is considered optional.
    CHECK_GE(getHalDeviceVersion(), SENSORS_DEVICE_API_VERSION_1_3);

    if (getHalDeviceVersion() == SENSORS_DEVICE_API_VERSION_1_4) {
        if (mSensorDevice->inject_sensor_data == nullptr) {
            LOG(ERROR) << "HAL specifies version 1.4, but does not implement inject_sensor_data()";
        }
        if (mSensorModule->set_operation_mode == nullptr) {
            LOG(ERROR) << "HAL specifies version 1.4, but does not implement set_operation_mode()";
        }
    }

    mInitCheck = OK;
}

接着看 sensors_open_1()
android/hardware/libhardware/include/hardware/sensors.h

static inline int sensors_open_1(const struct hw_module_t* module,
        sensors_poll_device_1_t** device) {
    return module->methods->open(module,
            SENSORS_HARDWARE_POLL, TO_HW_DEVICE_T_OPEN(device));
}

Among them, 
#define TO_HW_DEVICE_T_OPEN(x) reinterpret_cast<struct hw_device_t**>(x)
casts the sensors_poll_device_1_t** type to hw_device_t and
gives it as a parameter to the function open_sensors(),

Then comes android/hardware/libhardware/modules/sensors/multihal.cpp

static int open_sensors(const struct hw_module_t* hw_module, const char* name,
        struct hw_device_t** hw_device_out) {
    ALOGV("open_sensors begin...");

    lazy_init_modules();//这边dlopen手机厂商或第三方供应商实现的那个sensor库
    //将获取到的hw_module_t保存起来
    // Create proxy device, to return later.
    sensors_poll_context_t *dev = new sensors_poll_context_t();
    memset(dev, 0, sizeof(sensors_poll_device_1_t));
    dev->proxy_device.common.tag = HARDWARE_DEVICE_TAG;
    dev->proxy_device.common.version = SENSORS_DEVICE_API_VERSION_1_4;
    dev->proxy_device.common.module = const_cast<hw_module_t*>(hw_module);
    dev->proxy_device.common.close = device__close;
    dev->proxy_device.activate = device__activate;
    dev->proxy_device.setDelay = device__setDelay;
    dev->proxy_device.poll = device__poll;
    dev->proxy_device.batch = device__batch;
    dev->proxy_device.flush = device__flush;
    dev->proxy_device.inject_sensor_data = device__inject_sensor_data;
    dev->proxy_device.register_direct_channel = device__register_direct_channel;
    dev->proxy_device.config_direct_report = device__config_direct_report;

    dev->nextReadIndex = 0;

    // Open() the subhal modules. Remember their devices in a vector parallel to sub_hw_modules.
    for (std::vector<hw_module_t*>::iterator it = sub_hw_modules->begin();
            it != sub_hw_modules->end(); it++) {
        sensors_module_t *sensors_module = (sensors_module_t*) *it;
        struct hw_device_t* sub_hw_device;
        //这边,就会去调用手机厂商或第三方供应商实现的那个sensor库里边实现的open函数,
        //进而将其对hw_device_t的实现装到sub_hw_device里边,存储在 sensors_poll_context_t::sub_hw_devices里边
        //之后, 所有对下hal层的调用,都通过该函数传出去的*hw_device_out(即proxy_device),
		//类型强转获取到这边创建的dev(首地址相同),然后调用sensors_poll_context_t实现的接口,
		//进而在这里边调用sub_hw_devices里边存储的从OEM HAL层获取的对应接口的实现(装在hw_device_t里边)。
        int sub_open_result = sensors_module->common.methods->open(*it, name, &sub_hw_device);

        if (!sub_open_result) {
            if (!HAL_VERSION_IS_COMPLIANT(sub_hw_device->version)) {
                ALOGE("SENSORS_DEVICE_API_VERSION_1_3 or newer is required for all sensor HALs");
                ALOGE("This HAL reports non-compliant API level : %s",
                        apiNumToStr(sub_hw_device->version));
                ALOGE("Sensors belonging to this HAL will get ignored !");
            }
            dev->addSubHwDevice(sub_hw_device);//用vector保存起来,后面调用OEM HAL层接口实现时重新取出来
        }
    }

    // Prepare the output param and return
    *hw_device_out = &dev->proxy_device.common;
	//这里边将proxy_device.common的地址装进去,实际上也是proxy_device的地址(common为其第一个成员,因此地址相同),
    ALOGV("...open_sensors end");
    return 0;
}

Please note that although the address passed out here is an hw_device_t type address &dev->proxy_device.common, because it is the first member of sensors_poll_device_1, and sensors_poll_device_1 is the first member of sensors_poll_context_t, and what is created here is
actually A sensors_poll_context_t object, so you can later obtain the first addresses of proxy_device and dev through &dev->proxy_device.common type force transfer.


For the above analysis, for example, for the activate interface called by SensorService through HIDL, it
reaches android/hardware/interfaces/sensors/1.0/default/Sensors.cpp

Return<Result> Sensors::activate(
        int32_t sensor_handle, bool enabled) {
    return ResultFromStatus(
            mSensorDevice->activate(
                reinterpret_cast<sensors_poll_device_t *>(mSensorDevice),
                sensor_handle,
                enabled));
}

//Then we get to android/hardware/libhardware/modules/sensors/multihal.cpp 

static int device__activate(struct sensors_poll_device_t *dev, int handle,
        int enabled) {
    sensors_poll_context_t* ctx = (sensors_poll_context_t*) dev;
    return ctx->activate(handle, enabled);
}

Read on

int sensors_poll_context_t::activate(int handle, int enabled) {
    int retval = -EINVAL;
    ALOGV("activate");
	//这边将前面分析的open_sensors()里边获取到的OEM HAL层实现的hw_device_t取出来,
	//进而调用OEM HAL层对activate的实现。
    int local_handle = get_local_handle(handle);
    sensors_poll_device_t* v0 = this->get_v0_device_by_handle(handle);

    if (halIsCompliant(this, handle) && local_handle >= 0 && v0) {
        retval = v0->activate(v0, local_handle, enabled);
    } else {
        ALOGE("IGNORING activate(enable %d) call to non-API-compliant sensor handle=%d !",
                enabled, handle);
    }
    ALOGV("retval %d", retval);
    return retval;
}

At this point, the android HAL layer has been started and can respond to calls from the hidl client and then call the interface of the OEM HAL layer.

10. SensorManager starts

(1)SystemSensorManager startup process

SystemSensorManager inherits and implements the SensorManager interface. The application meets its needs by calling the SensorManager interface. The
actual function implementer is SystemSensorManager (polymorphic technology).
Let's first look at the startup process of SystemSensorManager. The call stack for creating an instance is as follows:

05-21 16:01:29.257  1813  1885 E ======>lkh:     at android.hardware.SystemSensorManager.<init>(SystemSensorManager.java:147)
05-21 16:01:29.257  1813  1885 E ======>lkh:     at android.app.SystemServiceRegistry$33.createService(SystemServiceRegistry.java:476)
05-21 16:01:29.257  1813  1885 E ======>lkh:     at android.app.SystemServiceRegistry$33.createService(SystemServiceRegistry.java:472)
05-21 16:01:29.257  1813  1885 E ======>lkh:     at android.app.SystemServiceRegistry$CachedServiceFetcher.getService(SystemServiceRegistry.java:1200)
05-21 16:01:29.257  1813  1885 E ======>lkh:     at android.app.SystemServiceRegistry.getSystemService(SystemServiceRegistry.java:1116)
05-21 16:01:29.257  1813  1885 E ======>lkh:     at android.app.ContextImpl.getSystemService(ContextImpl.java:1739)
05-21 16:01:29.257  1813  1885 E ======>lkh:     at com.android.server.policy.WakeGestureListener.<init>(WakeGestureListener.java:43)
05-21 16:01:29.257  1813  1885 E ======>lkh:     at com.android.server.policy.PhoneWindowManager$MyWakeGestureListener.<init>(PhoneWindowManager.java:1407)
05-21 16:01:29.257  1813  1885 E ======>lkh:     at com.android.server.policy.PhoneWindowManager.init(PhoneWindowManager.java:2665)
05-21 16:01:29.257  1813  1885 E ======>lkh:     at com.android.server.policy.OemPhoneWindowManager.init(OemPhoneWindowManager.java:410)
05-21 16:01:29.257 1813 1885 E ======>lkh: at com.android.server.wm.WindowManagerService$4.run(WindowManagerService.java:1236)
05-21 16:01:29.257 1813 1885 E ======>lkh: at android.os.Handler$BlockingRunnable.run(Handler.java:893)
05-21 16:01:29.257 1813 1885 E ======>lkh: at android. os.Handler.handleCallback(Handler.java:873)
05-21 16:01:29.257 1813 1885 E ======>lkh: at android.os.Handler.dispatchMessage(Handler.java:99)
05-21 16:01:29.257 1813 1885 E ======>lkh: at android.os.Looper.loop(Looper.java:193)
05-21 16:01:29.257 1813 1885 E ======> lkh: at android.os.HandlerThread.run(HandlerThread.java:65)
05-21 16:01:29.257 1813 1885 E ======>lkh: at com.android.server.ServiceThread.run(ServiceThread. java:44)
05-21 16:01:29.257  1813  1885 E ======>lkh:     at com.android.server.UiThread.run(UiThread.java:43)

Instance created in android/frameworks/base/core/java/android/app/SystemServiceRegistry.java when booting

registerService(Context.SENSOR_SERVICE, SensorManager.class,
        new CachedServiceFetcher<SensorManager>() {
    @Override
    public SensorManager createService(ContextImpl ctx) {
        return new SystemSensorManager(ctx.getOuterContext(),
          ctx.mMainThread.getHandler().getLooper());
    }});

Start looking at the constructor of SystemSensorManager

public SystemSensorManager(Context context, Looper mainLooper) {
    synchronized (sLock) {
        if (!sNativeClassInited) {
            sNativeClassInited = true;
            nativeClassInit();//native层offset初始化,没做什么其他事情
        }
    }
    Log.e("======>lkh", Log.getStackTraceString(new Throwable()));


    mMainLooper = mainLooper;
    mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;
    mContext = context;
    mNativeInstance = nativeCreate(context.getOpPackageName());
    //mNativeInstance 保存native创建的 c++对象 SensorManager的引用,
    //该对象通过getOpPackageName()返回的结果作为参数创建,并且2者保存在一个map里边,
    //注意,此SensorManager为native层c++实现的,非面向应用用Java实现的SensorManager

    // initialize the sensor list
    for (int index = 0;; ++index) {
        Sensor sensor = new Sensor();
        if (!nativeGetSensorAtIndex(mNativeInstance, sensor, index)) break;
        mFullSensorsList.add(sensor);
        mHandleToSensor.put(sensor.getHandle(), sensor);
    }
    //获取SesorService的sensor list里边的所有sensor,每个sensor创建一个对应的java层的Sensor对象,
    //并保存到链表里边,并将sensor handle和sensor一并保存到map里边
}

(2) Native layer SensorManager startup process

The creation of SensorManager, as you can see above, is that SystemSensorManager is initialized by calling android_hardware_SensorManager through jni,
and then calling its static interface getInstanceForPackage() for initialization.
You can take a look at its constructor

SensorManager::SensorManager(const String16& opPackageName)
    : mSensorList(0), mOpPackageName(opPackageName), mDirectConnectionHandle(1) {
    // okay we're not locked here, but it's not needed during construction
    assertStateLocked();
}

 

//Save the opPackageName passed by SystemSensorManager

status_t SensorManager::assertStateLocked() {
    bool initSensorManager = false;
    if (mSensorServer == NULL) {
        initSensorManager = true;
    } else {
        // Ping binder to check if sensorservice is alive.
        status_t err = IInterface::asBinder(mSensorServer)->pingBinder();
        if (err != NO_ERROR) {
            initSensorManager = true;
        }
    }
    if (initSensorManager) {
        waitForSensorService(&mSensorServer);
        LOG_ALWAYS_FATAL_IF(mSensorServer == nullptr, "getService(SensorService) NULL");

        class DeathObserver : public IBinder::DeathRecipient {
            SensorManager& mSensorManager;
            virtual void binderDied(const wp<IBinder>& who) {
                ALOGW("sensorservice died [%p]", who.unsafe_get());
                mSensorManager.sensorManagerDied();
            }
        public:
            explicit DeathObserver(SensorManager& mgr) : mSensorManager(mgr) { }
        };

        mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
        IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver);

        mSensors = mSensorServer->getSensorList(mOpPackageName);
        size_t count = mSensors.size();
        mSensorList =
                static_cast<Sensor const**>(malloc(count * sizeof(Sensor*)));
        LOG_ALWAYS_FATAL_IF(mSensorList == NULL, "mSensorList NULL");

        for (size_t i=0 ; i<count ; i++) {
            mSensorList[i] = mSensors.array() + i;
        }
    }

    return NO_ERROR;
}

There are three main things to do.
1. Wait for the SensorService to start up when booting and get its pointer.
2. Register a DeathObserver (I haven’t seen the specific mechanism of this yet. It should be using the observer mode. The SensorService hangs up. At this time,
  a registered interface will be called to perform some post-cleaning operations. In this case, it is the sensorManagerDied() interface.)
3. Obtain the address of each sensor object in the sensorlist.

Guess you like

Origin blog.csdn.net/goodnight1994/article/details/97503586