四個多月前就想寫這個了文章了,一直沒空寫,今天把有空就寫一下吧。本篇文章主要內容如下
目錄
4, SensorService如何將sensor數據給到應用
(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對象地址