前面我们分析了Android Sensor HAL层源码分析(基于Qualcomm平台),该篇博文主要讲解了Sensor HAL的初始化,以及hal层是怎样获取所有sensor列表的。今天我们来进一步了解下sensor hal层的数据获取流程。
我们知道Native层SensorService启动后,会进入我们的treadLoop方法:
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 minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());
SensorDevice& device(SensorDevice::getInstance());
const size_t vcount = mVirtualSensorList.size();
const int halVersion = device.getHalDeviceVersion();
do {
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;
}
}
if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
setWakeLockAcquiredLocked(true);
}
recordLastValueLocked(mSensorEventBuffer, count);
// handle virtual sensors
if (count && vcount) {
sensors_event_t const * const event = mSensorEventBuffer;
const size_t activeVirtualSensorCount = mActiveVirtualSensors.size();
if (activeVirtualSensorCount) {
size_t k = 0;
SensorFusion& fusion(SensorFusion::getInstance());
if (fusion.isEnabled()) {
for (size_t i=0 ; i<size_t(count) ; i++) {
fusion.process(event[i]);
}
}
for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
if (count + k >= minBufferSize) {
ALOGE("buffer too small to hold all events: "
"count=%zd, k=%zu, size=%zu",
count, k, minBufferSize);
break;
}
sensors_event_t out;
SensorInterface* si = mActiveVirtualSensors.valueAt(j);
if (si->process(&out, event[i])) {
mSensorEventBuffer[count + k] = out;
k++;
}
}
}
if (k) {
// record the last synthesized values
recordLastValueLocked(&mSensorEventBuffer[count], k);
count += k;
// sort the buffer by time-stamps
sortEventBuffer(mSensorEventBuffer, count);
}
}
}
// handle backward compatibility for RotationVector sensor
if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
for (int i = 0; i < count; i++) {
if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
// All the 4 components of the quaternion should be available
// No heading accuracy. Set it to -1
mSensorEventBuffer[i].data[4] = -1;
}
}
}
// Map flush_complete_events in the buffer to SensorEventConnections which called
// flush on the hardware sensor. mapFlushEventsToConnections[i] will be the
// SensorEventConnection mapped to the corresponding flush_complete_event in
// mSensorEventBuffer[i] if such a mapping exists (NULL otherwise).
for (int i = 0; i < count; ++i) {
mMapFlushEventsToConnections[i] = NULL;
if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) {
const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor;
SensorRecord* rec = mActiveSensors.valueFor(sensor_handle);
if (rec != NULL) {
mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection();
rec->removeFirstPendingFlushConnection();
}
}
}
// 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) {
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);
}
}
}
if (mWakeLockAcquired && !needsWakeLock) {
setWakeLockAcquiredLocked(false);
}
} while (!Thread::exitPending());
ALOGW("Exiting SensorService::threadLoop => aborting...");
abort();
return false;
}
其中在do…while循环体中通过device->poll方法进行去hal层读取sensor上报的数据。device的类型为sensors_poll_device_1_t结构体,在sensors_open方法中我们已经将其中的方法进行了初始化:
static int sensors_open(const struct hw_module_t* module, const char* id,
struct hw_device_t** device)
{
UNREFERENCED_PARAMETER(id);
int ret = -EINVAL;
SensorsContext *dev = SensorsContext::getInstance();
memset(&dev->device, 0, sizeof(sensors_poll_device_1_t));
dev->device.common.tag = HARDWARE_DEVICE_TAG;
dev->device.common.version = SENSORS_DEVICE_API_VERSION_1_3;
dev->device.common.module = const_cast<hw_module_t*>(module);
dev->device.common.close = sensors_close;
dev->device.activate = sensors_activate;
dev->device.setDelay = sensors_set_delay;
dev->device.poll = sensors_poll;
dev->device.batch = sensors_batch;
dev->device.flush = sensors_flush;
*device = &dev->device.common;
ret = 0;
return ret;
}
所以device->poll方法最终会调用到hal层的sensors_poll,因此我们跟进sensors_poll方法:
static int sensors_poll(struct sensors_poll_device_t *dev,
sensors_event_t* data, int count)
{
SensorsContext *ctx = (SensorsContext *)dev;
return ctx->poll(data, count);
}
继而调用我们之前介绍过的SensorsContext对象的poll方法,其中数据将会填充到由类型为sensors_event_t* data的数据结构中。这个结构体定义在hal层,其结构体如下: