1.前言
本篇文档主要分析安卓 Sensor框架Native层如何实现SensorEvent的分发。下面是我分析的主要源码的路径:2.传感器堆栈
下图显示了Android传感器组件堆栈。各个组件仅可与其上方和下方紧邻的组件通信,控制信号从应用向下流向传感器,数据从传感器向上流向应用。2.1 SDK
应用通过Sensor SDK API访问传感器。SDK包含列出可用传感器和注册监听传感器数据的函数。在注册到传感器时,应用可以指定自己的首选采样率和延迟要求。
2.2 Framework层
Sensor Framework负责将多个应用关联到HAL。HAL本身是单一客户端。如果框架级别没有发生这种多路复用,则任何指定时间内每个传感器都只能被一个应用访问。
● 当第一个应用注册到传感器时,框架会向HAL发送请求以激活传感器。
● 当其他应用注册到相同的传感器时,框架会考虑每个应用的要求,并将更新的已请求参数发送到HAL。
1.采样率将是请求的采用率的最大值,这意味着一些应用接收事件的频率会高于所请求的频率
2.最大报告延迟将是请求的延迟的最小值。如果某个应用的最大报告延迟是0,若它请求传感器,则所有应用将以连续模 式从该传感器接收事件,即使某些应用请求传感器时的最大报告延迟不是0也是如此。
● 当注册到某个传感器的最后一个应用取消注册后,框架会向HAL发送请求以停用该传感器,从而避免不必要的功耗。
2.3HAL
Sensors Hardware Abstraction Layer(HAL)API是硬件驱动程序和Android框架之间的接口。它包含一个HAL接口sensors.h(hardware/libhardware/include/hardware/sensors.h)和一个被称为sensors.cpp的HAL实现。
接口由Android和AOSP贡献者定义,并由设备制造商提供实现。
3.Native类的调用关系和启动流程
3.1调用关系
下图大致展示了Sensor框架各个主要类的调用关系:3.2 启动流程
Sensor框架在系统中主要分两条路线启动:
一条是系统启动时,SensorService的启动,另一条是系统启动时SensorManager.java启动连带着SensorManager.cpp的启动:
3.2.1 SensorService的启动
SensorService是在system_server启动的时候,被system_server启动的,
代码路径:frameworks/base/services/java/com/android/server/SystemServer.java
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);
//......
}
startSensorService是一个JNI方法,其对应的C++实现如下:
/*
* 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实例是通过调用SensorService::instantiate()方法创建的,此方法来源于SensorService的父类BinderService,所以实质上是调用BinderService::instantiate()来创建实例,而BinderService::instantiate()方法内部仅仅调用了BinderService::publish(),相关方法源码如下:
//这边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);
}
在BinderService::publish()函数中创建SensorService实例时,会调用onFirstRef()方法,这个方法里,首先创建并获取SensorDevice实例,获取vendor层注册的sensor数据,然后遍历每个sensor并将它们注册到SensorList里边,创建并运行一个SensorEventAckReceiver线程,再创建一个线程运行SensorService::threadLoop(),其代码如下:
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()方法,
//通过创建一个线程运行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()方法:
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;
}
该方法就是用SensorDevice循环去HAL层取数据,若无数据则阻塞当前线程,若有数据,则封装SensorEventConnection发送出去。至此SensorService已经启动了。
3.2.2 SensorManager的启动流程
从前一篇分析安卓Sensor 框架 Java API层的源码中我们知道,SystemSensorManager继承并实现SensorManager的虚方法,应用通过调用SensorManger的方法来达到其监听sensor数据的需求,而实际功能的实现者是SystemSensorManager,且SystemSensorManager中负责和Native层的SensorManager交互。安卓系统开机时在
frameworks/base/core/java/android/app/SystemServiceRegistry.java中创建SystemSensorManger实例:
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里边
}
在加锁的情况下,如果没有初始化过Native层的类,则调用nativeClassInit() JNI方法初始化,调用nativeCreate()方法初始化SensorManager.cpp的实例,再调用nativeGetSensorAtIndex() jni方法初始化sensor列表,以上分析可知,当SystemSensorManager初始化时,SensorManager.cpp同时也初始化了。
static jlong
nativeCreate
(JNIEnv *env, jclass clazz, jstring opPackageName)
{
ScopedUtfChars opPackageNameUtf(env, opPackageName);
return (jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str()));
}
接下来跳入Native SensorManager的构造函数中:
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();
}
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件事情:
- 等待SensorService起来,获取到其指针
- 注册一个DeathObserver,当sensorManagerDied()时,做一些清理操作
- 获取sensorList里面的每一个sensor对象的地址
3.3 Sensor数据的分发
接下来分析SensorService如何将sensor数据分发到应用,上面SensorService启动时,我们知道SensorService启动了一个线程去执行threadLoop方法,这个方法首先调用SensorDevice::getInstance()方法,获取其实例引用,接下来就进入了一个调用SensorDevice::poll()方法的do while循环中,SensorDevice在其中扮演了十分重要的角色,主要通过该类从HAL层取数据,下面是SensorDevice的部分源码:
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);
}
与HAL层如何交互的分析已经远远超出我负责的范畴了,这里不做深入分析。我们只需知道Native层的Sensor数据是通过SensorDevice去HAL取得的就行了。当数据上来后,通过做一些判断和处理然后再分发给应用,其中判断处理包括:是否应该丢弃数据,是否是flush数据,是否需要将数据给融合sensor,应用是否已经关闭该sensor等,处理后,通过SensorService::SensorEventConnection::sendEvents将数据发出,senEvent()函数代码如下:
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;
}
}
发现别无他法发送数据,唯有SensorEventQueue::write() 对复制得来的的scratch数据进行了处理,下面跳进该方法中:
ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
ASensorEvent const* events, size_t numEvents) {
return BitTube::sendObjects(tube, events, numEvents);
}
该方法仅仅调用了一下BitTube::sendObjects()方法,只能进入此方法中查看:
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);
看到tube->write(),则继续跟进去看:
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;
}
这个send方法是 sys/socket.h中声明的,是Unix套接字,这里分析到发送端就结束了。
接下来分析接收端怎么接收的,应用是通过SensorManager注册一个SensorEventListener来接收数据的,主要是通过调用registerListener方法,代码如下:
public boolean registerListener(SensorEventListener listener, Sensor sensor,
int samplingPeriodUs, Handler handler) {
int delay = getDelay(samplingPeriodUs);
return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
}
SystemSensorManager是SensorManager的实现类,其实现方法如下:
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
if (listener == null || sensor == null) {
Log.e(TAG, "sensor or listener is null");
return false;
}
// Trigger Sensors should use the requestTriggerSensor call.
if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
Log.e(TAG, "Trigger Sensors should use the requestTriggerSensor.");
return false;
}
if (maxBatchReportLatencyUs < 0 || delayUs < 0) {
Log.e(TAG, "maxBatchReportLatencyUs and delayUs should be non-negative");
return false;
}
if (mSensorListeners.size() >= MAX_LISTENER_COUNT) {
throw new IllegalStateException("register failed, " +
"the sensor listeners size has exceeded the maximum limit " +
MAX_LISTENER_COUNT);
}
// Invariants to preserve:
// - one Looper per SensorEventListener
// - one Looper per 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();
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);
}
}
}
在各种合法性判断之后,先根据传入的listener获取对应的SensorEventQueue实例,如果不为空则调用addSensor方法,为空则创建该实例并调用addSensor方法最后将其加入mSensorListeners中,而创建实例时,会调用android/frameworks/base/core/jni/android_hardware_SensorManager.cpp nativeInitSensorEventQueue(),其源码如下:
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());
}
这里创建了一个接收数据的Receiver对象,该类定义也在android_hardwate_SensorManager.cpp中,receiver又根据clientName创建了一个Native层的SensorEventQueue:
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));
}
receiver在执行incStrong时,会顺带执行它自己的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里,在Looper::pollInner()方法中通过epoll监听该fd,当有事件时,就会回调Receiver::hanldeEvent(),接下来看该方法:
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;
}
};
方法里面通过JNI 在C++代码里调用了SystemSensorManagre.java 中 BaseEventQueue的 dispatchSensorEvent(),下面为该方法(SensorEventQueue.java实现类)源码:
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事件给到应用
}
该方法最后调用了(SensorEventListener)listener的onSensorChanged方法,最后回调到了应用。
3.4总结
Sensor数据的分发最终还是走的Socket,SensorEventConnection类中持有 sp<BitTube>类型名为mChannel的实例,而其也持有一个应用包名字符串和Java虚拟机名字符串,一个应用对应一个SensorEventConnection,通过SensorEventConnection进行sensor监听的管理。
网友评论