深入分析Android SensorService

 

四個多月前就想寫這個了文章了,一直沒空寫,今天把有空就寫一下吧。本篇文章主要內容如下

目錄

1,Android 各模塊關係基本流程圖

2, SensorService啓動

3,  應用註冊一個sensor流程

4, SensorService如何將sensor數據給到應用

5,  待機後SensorService行爲

6,  融合sensor(SensorFusion)

7,  編譯SensorService

8,  dumpsys sensorservice

9,  android sensor hal層啓動

10,SensorManager 啓動

(1)SystemSensorManager 啓動流程

(2) native層 SensorManager 啓動流程


 


本文分析的源碼基於android 9.0

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

1,Android 各模塊關係基本流程圖

整個android sensor模塊的核心是SensorService,應用通過SensorManager與其交互,SensorService基本上管理sensor的所有行爲,包括開關sensor,獲取sensor數據給到應用,應用是否有權限獲取sensor,待機後sensor的行爲,sensor數據和開關記錄緩存,還可以在這自定義虛擬sensor,等等。

到Android 9爲止,SensorService一直跑在system server裏邊,所有隻要SensorService掛了,整個系統就掛了(android 10貌似有做了改進,還沒有去研究下),個人覺得google 如果把它做成和audio server那樣會好一些,掛了3s之後重新拉起來。

 

2, SensorService啓動

sensorservice是在system_server啓動的時候,由system_server拉起來的,
如前面所說,跑在system_server進程裏邊,所以只要sensorservice 發生 crash,
會導致syste_server跟着掛掉重啓,

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);
	
	//......

}

對應jni實現如下:

/*
 * 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();
    }

}

用SensorService::instantiate()方式創建的sensorservice實例,
sensorservice繼承了BinderService,所以是用BinderService::instantiate()來創建實例,如下;

//這邊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(); }

//......
};


看SensorService構造函數,其實構造函數沒做什麼事,主要是創建了UidPolicy對象,這個用來做待機sensor行爲管理,後面分析
 

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

接下來被調用的是onFirstRef()方法,
//onFirstRef()方法是在ServiceManager裏邊調用的
當前面創建的SensorService對象被提升爲一個強指針時在 RefBase::incStrong(const void* id)裏邊被調用的,
如何被調用還得回到前面的BinderService::publish(),感興趣的讀者可以自行研究下。
=====================================
看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待機管理裏邊,後面應用待機行爲發生變化時其接口會通過多態被回調
        }
    }
}

 

在看SensorService::threadLoop()之前,先來看下SensorDevice的構造函數,
SensorDevice是實際上與HAL層直接進行交互的類,通過hidl與
sensor在HAL層的服務建立連接(這邊所指的HAL層只是指google實現的那部分,
即: [email protected],這一層通過dlopen(),會調用第三方如芯片廠商,
手機廠商,開發者等實現的SO庫,實際上這些都應該統稱爲HAL層,也可以統稱vendor層)。


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,以防開着沒用漏電
                }
            }));

}

回過頭來看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;
}

到此爲此,sensorservice已經啓動了,能夠接收binder通信發過來的enable(), disable(), flush()等請求
也能夠讀取HAL層的數據給到應用。

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

在看SensorService如何將數據給到應用之前,先分析一下以下幾個比較關鍵的類

(1)SensorDevice

SensorDevice繼承了Singleton類,設計成單例,後面要用的話用getinstance()的方式
爲何用單例,是因爲sensorservice會有多個線程與vendor層交互,若用多個的話,邏輯會比較混淆,並且也沒有必要,節約一點內存哈哈。
裏邊保存着一個關鍵性的成員 :sp<hardware::sensors::V1_0::ISensors> mSensors,
在構造的時候會獲取到vendor層的sensor服務[email protected],後面都是
通過這個mSensors調用Vendor層的接口的,代碼如下,前面其實已經分析過了,爲了不需要拉回去看,再貼一下

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

這個類主要是用來給應用發送sensor數據的,通過socket進行通信,
當應用註冊sensor時,SensorManager.cpp裏邊會通過調用 SensorService::createSensorEventConnection()來生成屬於該應用的connection,
一個應用擁有多少個SensorEventConnection,取決於應用創建多少個SensorEventListerner,
可能有的應用開發者註冊多個sensor時,喜歡只創建一個SensorEventListerner,然後在onSensorChanged()裏邊做類型區分,
有的喜歡一個sensor一個SensorEventListerner,從性能的角度考慮建議一個應用創建一個SensorEventListerner就夠了,
畢竟每創建一個,就要新建立一個socket連接,多一個poll去等待數據。

看下構造函數,

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
}

主要是保存應用的信息,
2個package名字,分別表示,
packageName:應用包名;
opPackageName:java vm的名字,
在android/frameworks/base/services/core/jni/com_android_server_SystemServer.cpp 
android_server_SystemServer_startHidlServices()裏邊獲取並傳進來的。

該類的重點在於其SensorEventConnection::sendEvents() 函數,在這邊將數據發送給應用,所以如果遇到應用獲取不到sensor數據的問題,也可以在這裏邊debug,包括

a,多個應用註冊同一個sensor,有的應用收到數據,有的沒有;

b,所有應用都沒有收到某些sensor數據;

c,所有sensor都沒有數據;

都可以將mPackageName和sensor type, sensor data,sensor timestamp在這打印出來,或者統一存儲後dump sensorservice出來。

(3)SensorEventQueue

SensorEventQueue有多個類實現,這邊主要說的是SensorService裏邊用到的SensorEventQueue,定義在 android/frameworks/native/libs/sensor/裏邊,
當應用註冊sensor時,會在SystemSensorManager裏邊創建一個java類SensorEventQueue,這裏邊再去創建咱們要講的那個c++類SensorEventQueue,
當sensor數據到來時,SensorEventQueue會通過回調應用實現的onSensorChanged()接口而將數據給到應用,

//在這兒創建,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;
}

在什麼情況下創建,創建流程,在 應用註冊一個sensor 流程 裏邊講。

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

構造函數很簡單,創建mRecBuffer,用來存從SensorEventConnection發送過來的數據,

其中的
SensorEventQueue::write()用來給SensorEventConnection發送數據,
SensorEventQueue::read()用來讀取數據給應用,

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,  應用註冊一個sensor流程

先看下應用簡單註冊一個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
 
        }

先看 registerListener(),這個google實現了好幾個供應用開發者使用,咱們隨便拿一個開始跟就行了,因爲最後都是調用了SystemSensorManager::registerListenerImpl()這個接口,

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);
            }
        }
    }

若之前該SensorEventListener(由應用自己創建)沒有創建過SensorEventQueue,那麼創建一個,並和SensorEventListener一起添加到mSensorListeners,
對於sensor數據是如何從底層給上來並回調應用的onSensorChanged(),重點就在這邊,當創建SensorEventQueue時,會同時構造一個其父類對象BaseEventQueue,接着在其nativeInitBaseEventQueue()方法裏邊,
通過jni調用
android/frameworks/base/core/jni/android_hardware_SensorManager.cpp nativeInitSensorEventQueue()
來創建一個接收數據的Receiver對象,這個之後分析數據如何給上來再詳細分析。

接着看註冊流程,然後,通過BaseEventQueue::addSensor()將註冊一個sensor的流程繼續往下走,

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;
}

通過BaseEventQueue::enableSensor()繼續往下走,
接着看,

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);


}

通過jni調用C++的接口,
接着看,

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);
}

接下來到了 
android/frameworks/native/libs/sensor/SensorEventQueue.cpp
SensorEventQueue::enableSensor()

這裏邊有重載了好幾個,只是參數不同而已,咱們拿其中一個看就可以,(TO DO: 這塊是如何啓動的後面分析 sensor數據是如何給上來的再說,先直接跟一下流程)

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;
}

接下去就是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;
}

接下來看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;
}

接下來通過hidl,到了HAL,先到android 自己實現的hal層,就稱它爲android sensor hal吧,後面再往下手機廠家自己實現的hal層稱爲oem sensor hal 咯,

這邊也是直接往下看流程,後面會再分析一下android sensor hal的啓動,

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));
}

接着到了

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);
}

 接下來是

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;
}

這邊再下去就是手機廠家自己實現的接口了,android的部分到此爲止

4, SensorService如何將sensor數據給到應用

簡單來講,SensorService這邊使用SensorEventConnection作爲數據發送端,應用那邊用SensorEventListerner作爲數據接收端,通過unix socket傳送數據,咱們可以分別從2端分析,

先從SensorService這邊看下發送端,SensorService在構造後創建了一個線程threadLoop()一直不斷運行,通過poll往hal層取sensor數據(該poll只是與linux c 標準函數poll()同名,且功能類似而以,不是調用了linux c標準的那個poll()函數),當沒有sensor數據時就不斷阻塞等待(該阻塞功能由HAL層實現),當有數據上來時,通過做一些處理和判斷後發送給應用,

其中處理判斷包括是否應該丟棄數據,保存數據到一個vector實現的緩存裏邊方便後面dump出來debug,是否是flush數據,是否要將數據給到融合sensor,應用是否已經關閉該sensor,應用是否已經進入idle等等。

//從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;
}

也就是說, SensorService::threadLoop() 通過SensorDevice從hal層取到sensor數據,

同過  SensorService::SensorEventConnection::sendEvents()來將數據進一步處理併發送,這邊請注意有多個SensorEventConnection各屬於不同應用,到了sendEvents()裏邊就是各個應用處理各自的了,

接着看,

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;
    }

}

接下來跟一下 
ssize_t SensorEventQueue::write(const sp<BitTube>& tube, ASensorEvent const* events, size_t numEvents)
看看如何把數據通過onSensorChange()接口給到應用,

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);
  

那麼就到了BitTube::write(void const* vaddr, size_t size),接着看

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;
}

接下來需要從接收端來分析了,看看在哪去接收的(android_hardware_SensorManager.cpp Receiver裏邊去接收的),
具體流程如何,就需要回到 從應用通過SensorManager註冊一個sensor那邊說起了,

 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);
            }
        }
    }

若之前該SensorEventListener(由應用自己創建)沒有創建過SensorEventQueue,那麼創建一個,並和SensorEventListener一起添加到mSensorListeners,
重點就在這邊,當創建SensorEventQueue時,會同時構造一個其父類對象BaseEventQueue,接着在其nativeInitBaseEventQueue()方法裏邊,
通過jni調用
android/frameworks/base/core/jni/android_hardware_SensorManager.cpp nativeInitSensorEventQueue()
來創建一個接收數據的Receiver對象,

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());
}

根據clientName創建一個SensorEventQueue,接着創建Receiver,看下其構造函數,

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));
}

再看onFirstRef()

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

}

//這邊獲取到創建的SensorEventQueue==>BitTube 裏邊通過unix socket創建的mReceiveFd,
添加到looper裏邊,
在 android/system/core/libutils/Looper.cpp  Looper::pollInner()
裏邊,會通過epoll監聽該fd,當有事件時,就會回調Receiver::handleEvent(),接着看

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事件給到應用
        }

到這,sensor數據就給到應用的onSensorChanged()接口了。

5,  待機後SensorService行爲

主要的相關類爲SensorService::UidPolicy,相關接口爲 SensorService::setSensorAccess()和SensorEventConnection::setSensorAccess(),

大致邏輯是SensorService會通過UidPolicy進而通過ActivityManager來監聽有哪些新創建的應用,哪些應用進入idle,哪些應用退出,然後當應用註冊sensor並且進入idle後,就不將數據發送給應用。

    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;
    };

這個類做的事情很簡單,在分析它之前,先看下 SensorService::setSensorAccess()和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
}

之後該應用的SensorEventConnection::mHasSensorAccess爲false,那麼就不會將數據發送給對應的應用,

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];
    
	}

	//......
		
}

接着看,

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"));
}

在SensorService::onFirstRef()裏邊被調用,前面分析SensorService啓動的時候有說了下,
註冊後開始監聽應用的待機狀態(應用進程的創建,銷燬,進入idle)

應用進入idle後該接口被回調,傳入其對應的uid
可通過該指令 am make-uid-idle com.example.applicationtestproject  強行讓應用進入idle進行調試

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
    }
}

應用退出idle後該接口被ActivityManager回調

簡單來講,google在android9 的SensorService實現的待機相關機制就是,應用進入idle後,
就不將sensor數據給到應用,保證用戶隱私不被獲取。
對於手機廠家,爲了節省功耗,其實還可以在這邊做一個優化,就是當持有該sensor的所有應用都進入idle後,
就關閉所有sensor。

6,  融合sensor(SensorFusion)

SensorFusion大概是在這可以虛擬出sensor,取多個sensor的數據,可以再結合其他信息作爲輸入,通過算法處理最後輸出虛擬sensor數據,
基本上對於手機廠商是不會用到的,原因一個是爲了降低功耗所以做到驅動裏邊,另一個原因是用戶刷第三方rom後該功能就沒了,所以如果不做在驅動層也會做到vendor層,在這不做分析了。


7,  編譯SensorService

android/frameworks/native/service/SensorService 目錄下直接 mm,

編譯完後,out目錄下生成libsensorservice.so ,system/lib system/lib64各有一個,push到手機對應的目錄即可,

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 實現了dump接口,debug問題時,可以通過 adb shell dumpsys sensorservice 
將sensor信息dump出來協助分析,目前的dump接口主要包含以下幾個信息:
(1)應用在手機上所有可獲得的sensor,包括android定義的sensor以及廠商自定義的sensor
(2)目前有幾個sensor被應用開啓,對應應用包名
(3)最近的sensor數據;
(4)最近的sensor開關記錄,和對應應用包名

9,  android sensor hal層啓動

 

android實現的sensor hal層是作爲一個守護進程的service在跑的, 通過hidl被調用,
代碼位置:android/hardware/interfaces/sensors/1.0,  android/hardware/libhardware/modules/sensors
對外提供的接口定義在ISensors.hal裏邊,主要有
getSensorsList()//獲取所有sensor鏈表
activate()//開啓/關閉一個sensor
poll()//獲取sensor數據
batch()//設置採樣率
flush()//刷新緩衝區

從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"],
        },
    },
}

該service名字爲[email protected],

將service.cpp編譯成bin程序,通過[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

看下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);
}

通過defaultPassthroughServiceImplementation(),將自己註冊爲一個服務到ServiceManager裏邊,

從Sensors.cpp開始看,
//接下來最先被ServiceManager調用的是這個函數

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;
}

創建一個Sensors實例,之後所有通過hidl調用sensor hal的接口,都會調用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));
}

其中 
#define TO_HW_DEVICE_T_OPEN(x) reinterpret_cast<struct hw_device_t**>(x)
將sensors_poll_device_1_t** 類型強轉成hw_device_t,
作爲參數給到函數open_sensors(),

接着到了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;
}

請注意,這邊傳出去的雖然是一個hw_device_t類型的地址&dev->proxy_device.common,由於它是sensors_poll_device_1的第一個成員,而sensors_poll_device_1又是sensors_poll_context_t的
第一個成員,並且這邊創建的其實是一個sensors_poll_context_t對象,所以之後可以通過&dev->proxy_device.common類型強轉獲取到 proxy_device和dev的首地址,


對於上面分析,舉個例子,對於SensorService通過HIDL調用下來的activate接口,
到了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));
}

//接着到了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);
}

接着看

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;
}

到了這邊,android HAL層已經啓動完畢,並能夠相應hidl客戶端的調用,並進而調用OEM HAL 層的接口了。

10,SensorManager 啓動

(1)SystemSensorManager 啓動流程

SystemSensorManager 繼承並實現SensorManager接口,應用通過調用SensorManager的接口來達到其需求,
而實際的功能實現者是SystemSensorManager(多態技術),
先看下SystemSensorManager的啓動流程, 創建實例的調用棧如下,

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)

開機的時候在 android/frameworks/base/core/java/android/app/SystemServiceRegistry.java裏邊創建的實例

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

開始看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層 SensorManager 啓動流程

SensorManager的創建如上所看到的,是SystemSensorManager初始化時通過jni調用到android_hardware_SensorManager,
接着調用其static接口getInstanceForPackage()進行初始化的,
可以看下其構造函數

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();
}

 

//保存SystemSensorManager傳過來的 opPackageName

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;
}

主要做的事情有3個,
1,開機的時候等SensorService起來,獲取到其指針,
2,註冊一個DeathObserver(這個具體是個什麼機制目前還沒去看,應該就是利用觀察者模式,SensorService掛了的時候,
  註冊的某個接口會被調用進行一些後期清理操作,這邊的話就是sensorManagerDied()接口了)
3,獲取sensorlist裏邊的每個sensor對象地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章