1:onFirstRef方法
sensorservice实例化被调用,只会调用一次。具体就是在systemserve启动过程中会启动这个binder服务。
void SensorService::onFirstRef()
{
ALOGD("nuSensorService starting...");
SensorDevice& dev(SensorDevice::getInstance()); //SensorDevice是单实例对象,代表HALL 层sensor device对象
if (dev.initCheck() == NO_ERROR) {
sensor_t const* list;
ssize_t count = dev.getSensorList(&list);//从HAL层获取支持的传感器列表
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);
mLastEventSeen.setCapacity(count);
for (ssize_t i=0 ; i<count ; i++) {
//为每一个类型的sensor构造HardwareSensor对象,注册到sensorservice中
registerSensor( new HardwareSensor(list[i]) );
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:
virtualSensorsNeeds &= ~(1<<list[i].type);
break;
}
}
// it's safe to instantiate the SensorFusion object here
// (it wants to be instantiated after h/w sensors have been
// registered)
const SensorFusion& fusion(SensorFusion::getInstance());
// build the sensor list returned to users
mUserSensorList = mSensorList;//mUserSensorList是发送给client的sensor list
//注册虚拟传感器
if (hasGyro && hasAccel && hasMag) {
Sensor aSensor;
// Add Android virtual sensors if they're not already
// available in the HAL
aSensor = registerVirtualSensor( new RotationVectorSensor() );
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
mUserSensorList.add(aSensor);
}
aSensor = registerVirtualSensor( new GravitySensor(list, count) );
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
mUserSensorList.add(aSensor);
}
aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
mUserSensorList.add(aSensor);
}
aSensor = registerVirtualSensor( new OrientationSensor() );
if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
// if we are doing our own rotation-vector, also add
// the orientation sensor and remove the HAL provided one.
mUserSensorList.replaceAt(aSensor, orientationIndex);
}
// virtual debugging sensors are not added to mUserSensorList
registerVirtualSensor( new CorrectedGyroSensor(list, count) );
registerVirtualSensor( new GyroDriftSensor() );
}
// debugging sensor list
mUserSensorListDebug = mSensorList;
// Check if the device really supports batching by looking at the FIFO event
// counts for each sensor.
//根据传感器的FIFO event counts个数判断这个sensor是否支持batch操作
bool batchingSupported = false;
for (size_t i = 0; i < mSensorList.size(); ++i) {
if (mSensorList[i].getFifoMaxEventCount() > 0) {
batchingSupported = true;
break;
}
}
if (batchingSupported) {
// Increase socket buffer size to a max of 100 KB for batching capabilities.
mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
} else {
mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
}
// Compare the socketBufferSize value against the system limits and limit
// it to maxSystemSocketBufferSize if necessary.
FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
char line[128];
if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
line[sizeof(line) - 1] = '\0';
size_t maxSystemSocketBufferSize;
sscanf(line, "%zu", &maxSystemSocketBufferSize);
if (mSocketBufferSize > maxSystemSocketBufferSize) {
mSocketBufferSize = maxSystemSocketBufferSize;
}
}
if (fp) {
fclose(fp);
}
mWakeLockAcquired = false;
mLooper = new Looper(false);
const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
mSensorEventBuffer = new sensors_event_t[minBufferSize];
mSensorEventScratch = new sensors_event_t[minBufferSize];
mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
mCurrentOperatingMode = NORMAL;
mNextSensorRegIndex = 0;
for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {
mLastNSensorRegistrations.push();
}
mInitCheck = NO_ERROR;
mAckReceiver = new SensorEventAckReceiver(this);
// run方法调用threadLoop方法
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
run("SensorService", PRIORITY_URGENT_DISPLAY);
}
}
}
mSensorList是sensorservice维护的sensor list,他的类型是Sensor。每个Sensor对象代表一个传感器。Sensor对象状态信号是通过在HAL层预定义的struct sensor_t对象初始化的。
Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
{
mName = hwSensor->name;
mVendor = hwSensor->vendor;
mVersion = hwSensor->version;
mHandle = hwSensor->handle;
mType = hwSensor->type;
mMinValue = 0; // FIXME: minValue
mMaxValue = hwSensor->maxRange; // FIXME: maxValue
mResolution = hwSensor->resolution;
mPower = hwSensor->power;
mMinDelay = hwSensor->minDelay;
mFlags = 0;
Sensor对象里的mFlags成员
这个mFlags成员的值也会在Sensor对象构造过程中初始化。
// Ensure existing sensors have correct string type, required permissions and reporting mode.
// Set reportingMode for all android defined sensor types, set wake-up flag only for proximity
// sensor, significant motion, tilt, pick_up gesture, wake gesture and glance gesture on older
// HALs. Newer HALs can define both wake-up and non wake-up proximity sensors.
// All the OEM defined defined sensors have flags set to whatever is provided by the HAL.
switch (mType) {
case SENSOR_TYPE_ACCELEROMETER:
mStringType = SENSOR_STRING_TYPE_ACCELEROMETER;
mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_AMBIENT_TEMPERATURE:
mStringType = SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE;
mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
break;
case SENSOR_TYPE_GAME_ROTATION_VECTOR:
mStringType = SENSOR_STRING_TYPE_GAME_ROTATION_VECTOR;
mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
mStringType = SENSOR_STRING_TYPE_GEOMAGNETIC_ROTATION_VECTOR;
mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_GRAVITY:
mStringType = SENSOR_STRING_TYPE_GRAVITY;
mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_GYROSCOPE:
mStringType = SENSOR_STRING_TYPE_GYROSCOPE;
mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
mFlags成员的取值如下:
sensors.h
enum {
/*
* Whether this sensor wakes up the AP from suspend mode when data is available. Whenever
* sensor events are delivered from a wake_up sensor, the driver needs to hold a wake_lock till
* the events are read by the SensorService i.e till sensors_poll_device_t.poll() is called the
* next time. Once poll is called again it means events have been read by the SensorService, the
* driver can safely release the wake_lock. SensorService will continue to hold a wake_lock till
* the app actually reads the events.
*/
SENSOR_FLAG_WAKE_UP = 1U << 0,
/*
* Reporting modes for various sensors. Each sensor will have exactly one of these modes set.
* The least significant 2nd, 3rd and 4th bits are used to represent four possible reporting
* modes.
*/
SENSOR_FLAG_CONTINUOUS_MODE = 0, // 0000
SENSOR_FLAG_ON_CHANGE_MODE = 0x2, // 0010
SENSOR_FLAG_ONE_SHOT_MODE = 0x4, // 0100
SENSOR_FLAG_SPECIAL_REPORTING_MODE = 0x6, // 0110
/*
* Set this flag if the sensor supports data_injection mode and allows data to be injected
* from the SensorService. When in data_injection ONLY sensors with this flag set are injected
* sensor data and only sensors with this flag set are activated. Eg: Accelerometer and Step
* Counter sensors can be set with this flag and SensorService will inject accelerometer data
* and read the corresponding step counts.
*/
SENSOR_FLAG_SUPPORTS_DATA_INJECTION = 0x8 // 1000
};
2:sensorservice类mActiveSensors成员
mActiveSensors是sensor handle和SensorRecord对象的键值对,SensorRecord对象里保存了一个SensorEventConnection对象的vector。由此可知:有多少个clients注册监听了对应的sensor handle。
3:SensorEventConnection类
当客户端注册监听一个sensor时,就会通过sensorservice bindre调用来创建SensorEventConnection对象。SensorEventConnection对象代表一个客户端的连接。
sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
int requestedMode, const String16& opPackageName) {
// Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION.
if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) {
return NULL;
}
Mutex::Autolock _l(mLock);
// To create a client in DATA_INJECTION mode to inject data, SensorService should already be
// operating in DI mode.
if (requestedMode == DATA_INJECTION) {
if (mCurrentOperatingMode != DATA_INJECTION) return NULL;
if (!isWhiteListedPackage(packageName)) return NULL;
}
sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
int requestedMode, const String16& opPackageName) {
// Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION.
if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) {
return NULL;
}
Mutex::Autolock _l(mLock);
// To create a client in DATA_INJECTION mode to inject data, SensorService should already be
// operating in DI mode.
if (requestedMode == DATA_INJECTION) {
if (mCurrentOperatingMode != DATA_INJECTION) return NULL;
if (!isWhiteListedPackage(packageName)) return NULL;
}
sensorservice的threadloop方法会pollsensor device,当底层有数据上报时,poll会返回buffer大小的事件,各种类型的事件都有。
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;
}
然后会循环每个SensorEventConnection对象,调用其sendEvents方法向client发送事件。
// 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);
}
}
}
SensorEventConnection对象会过滤事件,只保留注册在这个Connection对象里sensor handle对应的事件。
status_t SensorService::SensorEventConnection::sendEvents(
sensors_event_t const* buffer, size_t numEvents,
sensors_event_t* scratch,
SensorEventConnection const * const * mapFlushEventsToConnections) {
// filter out events not for this connection
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);
// Check if this connection has registered for this sensor. If not continue to the
// next sensor_event.
if (index < 0) {
++i;
continue;
}
SensorEventConnection对象成员mSensorInfo保存了注册在这个
Connection对象里的所有sensors。
mSensorInfo在sensor 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;
SensorInterface* sensor = mSensorMap.valueFor(handle);
if (sensor == NULL) {
return BAD_VALUE;
}
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);
}
} else {
ALOGW("sensor %08x already enabled in connection %p (ignoring)",
handle, connection.get());
}