深入分析Android SensorService
深入分析Android SensorService
本文分析的源码基于android 9.0
====================================================
1,Android 各模块关系基本流程图
![](https://img.haomeiwen.com/i13327761/bb86b96a273b409d.png)
整个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实现的那部分,
即: android.hardware.sensors@1.0-service,这一层通过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服务android.hardware.sensors@1.0-service,后面都是
通过这个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获取 android.hardware.sensors@1.0-service
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: "android.hardware.sensors@1.0-service",
relative_install_path: "hw",
vendor: true,
init_rc: ["android.hardware.sensors@1.0-service.rc"],
defaults: ["hidl_defaults"],
srcs: ["service.cpp"],
shared_libs: [
"liblog",
"libcutils",
"libdl",
"libbase",
"libutils",
"libhidlbase",
"libhidltransport",
"android.hardware.sensors@1.0",
"libhwbinder",
],
arch: {
arm: {
cflags: ["-DARCH_ARM_32"],
},
},
}
该service名字为android.hardware.sensors@1.0-service,
将service.cpp编译成bin程序,通过android.hardware.sensors@1.0-service.rc启动,
service vendor.sensors-hal-1-0 /vendor/bin/hw/android.hardware.sensors@1.0-service
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对象地址