3.2 dev.getSensorList(&list);获取厂商在HAL层初始化的sensor_t类型结构体的sSensorList,并返回sensor device的数目。
3.3 registerSensor( new HardwareSensor(list[i]) );在for循环中注册这些sensor。根据硬件sensor_t创建HardwareSensor,然后加入mSensorList(Sensor) 和mSensorMap(HardwareSensor)中,后面的switch是判断是否存在电子罗盘,GYRO以及GYRO对应所需要的对应的一些所对应的一些虚拟sensor
for (ssize_t i=0 ; i
Sensor SensorService::registerSensor(SensorInterface* s)
{
sensors_event_t event;
memset(&event, 0, sizeof(event));
const Sensor sensor(s->getSensor());
// add to the sensor list (returned to clients)
mSensorList.add(sensor);
// add to our handle->SensorInterface mapping
mSensorMap.add(sensor.getHandle(), s);
// create an entry in the mLastEventSeen array
mLastEventSeen.add(sensor.getHandle(), event);
return sensor;
}
3.4 mUserSensorList = mSensorList;将mSensorList传感器列表赋值给mUserSensorList,mSensorList是由registerSensor初始化的,mUserSensorList是要提交给Java框架层的传感器列表。
3.5 如果有GYRO就注册这样一些上面提到的三种虚拟sensor来实现GYRO的功能,此处我是这么理解的。
if (hasGyro) {
Sensor aSensor;
// Add Android virtual sensors if they're not already
// available in the HAL
aSensor = registerVirtualSensor( new RotationVectorSensor() );
if (virtualSensorsNeeds & (1<
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();
SensorEventAckReceiver sender(this);
sender.run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
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 > activeConnections;
{
Mutex::Autolock _l(mLock);
for (size_t i=0 ; i < mActiveConnections.size(); ++i) {
sp connection(mActiveConnections[i].promote());
if (connection != 0) {
activeConnections.add(connection);
}
}
}
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) {
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
mWakeLockAcquired = 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= 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) {
release_wake_lock(WAKE_LOCK_NAME);
mWakeLockAcquired = false;
}
} while (!Thread::exitPending());
ALOGW("Exiting SensorService::threadLoop => aborting...");
abort();
return false;
}
static int poll__poll(struct sensors_poll_device_t *dev,
sensors_event_t* data, int count) {
sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
return ctx->pollEvents(data, count);
}
int sensors_poll_context_t::pollEvents(sensors_event_t * data, int count)
{
int nbEvents = 0;
int n = 0;
int polltime = -1;
do {
// see if we have some leftover from the last poll()
for (int i = 0; count && i < numSensorDrivers; i++) {
SensorBase *const sensor(mSensors[i]);
if ((mPollFds[i].revents & POLLIN)
|| (sensor->hasPendingEvents())) {
int nb = sensor->readEvents(data, count);
if (nb < count) {
// no more data for this sensor
mPollFds[i].revents = 0;
}
#ifndef ORI_NULL
if ((0 != nb) && (acc == i)) {
((OriSensor *) (mSensors[ori]))->
setAccel(&data[nb - 1]);
}
#endif
count -= nb;
nbEvents += nb;
data += nb;
}
}
if (count) {
// we still have some room, so try to see if we can get
// some events immediately or just wait if we don't have
// anything to return
do {
n = poll(mPollFds, numFds,
nbEvents ? 0 : polltime);
} while (n < 0 && errno == EINTR);
if (n < 0) {
ALOGE("poll() failed (%s)", strerror(errno));
return -errno;
}
if (mPollFds[wake].revents & POLLIN) {
char msg;
int result = read(mPollFds[wake].fd, &msg, 1);
ALOGE_IF(result < 0,
"error reading from wake pipe (%s)",
strerror(errno));
ALOGE_IF(msg != WAKE_MESSAGE,
"unknown message on wake queue (0x%02x)",
int (msg));
mPollFds[wake].revents = 0;
}
}
// if we have events and space, go read them
} while (n && count);
return nbEvents;
}
这里首先调用的是sensor->readEvents(data, count);也就是各个sensor对应的读取sensor event的方法。readEvents()函数先调用fill函数将所要读的sensor的input_event事件读取到一个环形缓冲区,然后在while循环中mInputReader.readEvent(&event)读取当前指针所指向的事件,mInputReader.next();将指针指向环形队列下一条事件来读取下一条事件。
int STKLightSensor::readEvents(sensors_event_t* data, int count){
if (count < 1)
return -EINVAL;
if (mHasPendingEvent) {
mHasPendingEvent = false;
mPendingEvent.timestamp = getTimestamp();
*data = mPendingEvent;
return mEnabled ? 1 : 0;
}
ssize_t n = mInputReader.fill(data_fd);
if (n < 0)
return n;
int numEventReceived = 0;
input_event const* event;
while (count && mInputReader.readEvent(&event)) {
int type = event->type;
if (type == EV_ABS) {
if (event->code == ABS_MISC) {
mPendingEvent.light = (float)event->value;
}
} else if (type == EV_SYN) {
mPendingEvent.timestamp = timevalToNano(event->time);
if (mEnabled) {
*data++ = mPendingEvent;
count--;
numEventReceived++;
}
} else {
ALOGE("STKLightSensor: unknown event (type=%d, code=%d)",
type, event->code);
}
mInputReader.next();
}
return numEventReceived;
}
fill函数的参数data_fd是在前面sensors_poll_context_t()函数中的new STKLightSensor();进行初始化的,其主要是SensorBase(NULL, "lightsensor-level"),这里主要是openInput动作来获得一个fd从而从这个fd的文件中获取sensor event。
ssize_t InputEventCircularReader::fill(int fd)
{
size_t numEventsRead = 0;
if (mFreeSpace) {
const ssize_t nread =
read(fd, mHead, mFreeSpace * sizeof(input_event));
if (nread < 0 || nread % sizeof(input_event)) {
// we got a partial event!!
return nread < 0 ? -errno : -EINVAL;
}
numEventsRead = nread / sizeof(input_event);
if (numEventsRead) {
mHead += numEventsRead;
mFreeSpace -= numEventsRead;
if (mHead > mBufferEnd) {
size_t s = mHead - mBufferEnd;
memcpy(mBuffer, mBufferEnd,
s * sizeof(input_event));
mHead = mBuffer + s;
}
}
}
return numEventsRead;
}
ssize_t InputEventCircularReader::readEvent(input_event const **events)
{
*events = mCurr;
ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace;
return available ? 1 : 0;
}
void InputEventCircularReader::next()
{
mCurr++;
mFreeSpace++;
if (mCurr >= mBufferEnd) {
mCurr = mBuffer;
}
}
SensorBase::SensorBase(
const char* dev_name,
const char* data_name)
: dev_name(dev_name), data_name(data_name),
dev_fd(-1), data_fd(-1)
{
if (data_name) {
data_fd = openInput(data_name);
}
}
openInput()实际上是打开各个sensor对应于/dev/input/event*文件节点最后返回的是sensor对应文件节点的fd,也就是上面fill函数的参数data_fd,在adb shell,然后getevent命令也是获取位于/dev/input/下所有的event事件。
int SensorBase::openInput(const char* inputName) {
int fd = -1;
const char *dirname = "/dev/input";
char devname[PATH_MAX];
char *filename;
DIR *dir;
struct dirent *de;
dir = opendir(dirname);
if(dir == NULL)
return -1;
strcpy(devname, dirname);
filename = devname + strlen(devname);
*filename++ = '/';
while((de = readdir(dir))) {
if(de->d_name[0] == '.' &&
(de->d_name[1] == '\0' ||
(de->d_name[1] == '.' && de->d_name[2] == '\0')))
continue;
strcpy(filename, de->d_name);
fd = open(devname, O_RDONLY);
if (fd>=0) {
char name[80];
if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
name[0] = '\0';
}
if (!strcmp(name, inputName)) {
strcpy(input_name, filename);
break;
} else {
close(fd);
fd = -1;
}
}
}
closedir(dir);
ALOGE_IF(fd<0, "couldn't find '%s' input device", inputName);
return fd;
在获取完数据之后就要通过 activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,mMapFlushEventsToConnections);调用write函数将数据放到一个管道里面,sensor APP将数据取走。
ssize_t size = SensorEventQueue::write(mChannel,
reinterpret_cast(scratch), count);