Android Sensor 之 SensorDevice
前面内容提到,第一次使用SensorService,onFirstRef方法将被被自动回调。
void SensorService::onFirstRef() {
ALOGD("nuSensorService starting...");
SensorDevice& dev(SensorDevice::getInstance());
//!< 创建 SensorDevice实例对象 >! NoteBy: yujixuan
if (dev.initCheck() == NO_ERROR) {
sensor_t const* list;
ssize_t count = dev.getSensorList(&list);
//!< 获取SensorList >! NoteBy: yujixuan
if (count > 0) {
......
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_GYROSCOPE:
......
}
if (useThisSensor) {
registerSensor( new HardwareSensor(list[i]) );
//!< new 对应的HardwareSensor >! NoteBy: yujixuan
}
SensorFusion::getInstance();
......
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);
}
}
}
SensorDevice::getInstance() 创建了一个SensorDevice的实例对象;
代码路径:./native/services/sensorservice/SensorDevice.cpp
SensorDevice::SensorDevice()
: mSensorDevice(0),
mSensorModule(0) {
status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
(hw_module_t const**)&mSensorModule);
//!< 加载Sensor HAL 的动态库 >! NoteBy: yujixuan
ALOGE_IF(err, "couldn't load %s module (%s)",
SENSORS_HARDWARE_MODULE_ID, strerror(-err));
if (mSensorModule) {
err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
//!< 调用其open方法,获取Hal中 的device >! NoteBy: yujixuan
ALOGE_IF(err, "couldn't open device for module %s (%s)",
SENSORS_HARDWARE_MODULE_ID, strerror(-err));
sensor_t const* list;
ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
//!< 获取sensor list >! NoteBy: yujixuan
mActivationCount.setCapacity(count);
Info model;
for (size_t i=0 ; i<size_t(count) ; i++) {
mActivationCount.add(list[i].handle, model);
mSensorDevice->activate(
reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
list[i].handle, 0);
}
}
}
}
bool SensorService::SensorEventAckReceiver::threadLoop() {
ALOGD("new thread SensorEventAckReceiver");
sp<Looper> looper = mService->getLooper();
do {
bool wakeLockAcquired = mService->isWakeLockAcquired();
int timeout = -1;
if (wakeLockAcquired) timeout = 5000;
int ret = looper->pollOnce(timeout);
if (ret == ALOOPER_POLL_TIMEOUT) {
mService->resetAllWakeLockRefCounts();
}
} while(!Thread::exitPending());
return false;
}
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);
SensorDevice& device(SensorDevice::getInstance());
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;
if (!mActiveVirtualSensors.empty()) {
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 (int handle : mActiveVirtualSensors) {
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;
sp<SensorInterface> si = mSensors.getInterface(handle);
if (si == nullptr) {
ALOGE("handle %d is not an valid virtual sensor", handle);
continue;
}
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;
}
}
}
for (int i = 0; i < count; ++i) {
// 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).
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();
}
}
// handle dynamic sensor meta events, process registration and unregistration of dynamic
// sensor based on content of event.
if (mSensorEventBuffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
if (mSensorEventBuffer[i].dynamic_sensor_meta.connected) {
int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle;
const sensor_t& dynamicSensor =
*(mSensorEventBuffer[i].dynamic_sensor_meta.sensor);
ALOGI("Dynamic sensor handle 0x%x connected, type %d, name %s",
handle, dynamicSensor.type, dynamicSensor.name);
if (mSensors.isNewHandle(handle)) {
const auto& uuid = mSensorEventBuffer[i].dynamic_sensor_meta.uuid;
sensor_t s = dynamicSensor;
// make sure the dynamic sensor flag is set
s.flags |= DYNAMIC_SENSOR_MASK;
// force the handle to be consistent
s.handle = handle;
SensorInterface *si = new HardwareSensor(s, uuid);
// This will release hold on dynamic sensor meta, so it should be called
// after Sensor object is created.
device.handleDynamicSensorConnection(handle, true /*connected*/);
registerDynamicSensorLocked(si);
} else {
ALOGE("Handle %d has been used, cannot use again before reboot.", handle);
}
} else {
int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle;
ALOGI("Dynamic sensor handle 0x%x disconnected", handle);
device.handleDynamicSensorConnection(handle, false /*connected*/);
if (!unregisterDynamicSensorLocked(handle)) {
ALOGE("Dynamic sensor release error.");
}
size_t numConnections = activeConnections.size();
for (size_t i=0 ; i < numConnections; ++i) {
if (activeConnections[i] != NULL) {
activeConnections[i]->removeSensor(handle);
}
}
}
}
}
// 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;
}