1.APP层(注册sensor流程)
1.1 SensorManager.registerListenerImpl
1)如果没注册过则new SensorEventQueue,在SensorEventQueue构造中会new Receiver,用来接收数据(后续分析)
2)将要注册的sensor add进与linstener绑定的SensorEventQueue中。
1.2 SensorEventQueue.addSensor
1)加入到mActiveSensors中
1.3 BaseEventQueue.enableSensor
1.4 SensorEventQueue.enableSensor
1.5 SensorService.SensorEventConnection.enableDisable
1.6 SensorService.enable
2. Framework层(service启动以及如何将数据传给APP)
2.1 Sensor服务的启动:SystemServer.startBootstrapServices()
sensor service 在SystemServer中启动的,在SystemServer新建一个线程,当有APP选择该service时,再start sensor service.
startSensorService是一个native方法,该方法实现见android_server_SystemServer_startSensorService方法
2.2 com_android_server_SystemServer.android_server_SystemServer_startSensorService()
接下来,调用SensorService的instantiate()方法,SensorService.cpp中并没有instantiate()方法的实现,说明调用的是其父类的instantiate方法。接下来,查看SensorService是哪些类的子类。
SensorService继承了BinderService,BnSensorServer和Thread。
2.2.1 BinderService.instantiate()
通过其父类BinderService的instantiate方法可知,通过该方法new SensorService,并将该service add进ServiceManager,这样APP就能通过getSystemService获取到SensorService。接下来就进入SensorService了。
2.3 SensorService的构造
2.3.1 SensorService()
SensorService的构造函数中对属性进行初始化,创建了UidPolicy对象。构造函数被调用之后,会触发调用onFirstRef()方法。
2.3.2 onFirstRef()
onFirstRef() 方法被调用是因为前面在BinderService.instantiate()中创建SensorService时被转成了一个强指针(sp),在sp的构造函数中会调用RefBase的incStrong(),在incStrong方法中会调用到影子对象(SensorService)的onFirstRef()。该方法在第一次引用时被调用,用来做一些初始化操作。
void SensorService::onFirstRef() {
ALOGD("nuSensorService starting...");
//初始化SensorDevice,获取HAL层实例
SensorDevice& dev(SensorDevice::getInstance());
sHmacGlobalKeyIsValid = initializeHmacKey();
if (dev.initCheck() == NO_ERROR) {
sensor_t const* list;
//获取HAL层注册的sensors
ssize_t count = dev.getSensorList(&list);
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
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中。
//将每种sensor和其handler存在mRecentEvent(map)中
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();
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);
}
// Check if the device really supports batching by looking at the FIFO event
// counts for each sensor.
bool batchingSupported = false;
mSensors.forEachSensor(
[&batchingSupported] (const Sensor& s) -> bool {
if (s.getFifoMaxEventCount() > 0) {
batchingSupported = true;
}
return !batchingSupported;
});
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 wp<const SensorEventConnection> [minBufferSize];
mCurrentOperatingMode = NORMAL;
mNextSensorRegIndex = 0;
for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {
mLastNSensorRegistrations.push();
}
mInitCheck = NO_ERROR;
//SensorEventAckReceiver用于在dispatch wake up sensor event给上层后,接受上层返回的ACK
mAckReceiver = new SensorEventAckReceiver(this);
//SensorEventAckReceiver新起一个线程,run->执行threadLoop方法
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
//主线程新起一个线程,执行threadLoop方法
run("SensorService", PRIORITY_URGENT_DISPLAY);
//主线程降低优先级
// priority can only be changed after run
enableSchedFifoMode();
// Start watching UID changes to apply policy.
mUidPolicy->registerSelf();
}
}
}
2.3.2.1 SensorDevice::getInstance()
2.3.2.2 SensorService::threadLoop
该函数用于循环读取sensor硬件上传上来的数据(如果没有数据则堵塞),分发给应用。
1)通过poll往hal层取数据,若没数据就一直阻塞(HAL层实现),有数据就一直返回。
2)通过SensorEventConnection,将数据发送给每个应用
2.4 SensorEventConnection.sendEvents将数据发送给应用
每个注册sensor的应用都有专属的SensorEventConnection
1)处理每个数据
2)判断该sensor是否已经被disable了,或者该应用有没有注册该sensor,若已经disable或者应用没有注册,就过滤掉数据
3) 将需要发送给APP的数据,copy到scratch中
4)将scratch中的数据发送给APP
2.5 SensorEventQueue.write()
接下来分析,应用层如何接收sensor数据,从app通过SensorManager注册sensor开始分析。
2.6 APP通过SensorManager注册sensor
2.7 SystemSensorManager.registerListenerImpl()
1)如果之前SensorEventListener没有创建过SensorEventQueue,则创建一个,并将listener和queue一起放进mSensorListeners中。
2) new SensorEventQueue的时候,同时new 其父类BaseEventQueue。
3) BaseEventQueue的构造函数中会调用一个native方法
2.8 android_hardware_SensorManager.nativeInitSensorEventQueue
该方法中会创建一个接收数据的Receiver
1)在构造中将sensorQueue和messageQueue保存下来
2)在onFirstRef方法中利用Android Native Looper机制中的addFd来监听文件描述符,当有事件发生时,回调Receiver.handleEvent()
其中:
fd :需要轮询的文件描述符
ident :表示为当前发生事件的标识符,必须>=0
events :表示为要监听的文件类型
callback :当有事件发生时,会回调该callback函数。
data :文件描述符fd里面的数据
2.9 Receiver.handleEvent()
1)从BitTube中读取数据
2)调用SensorEventQueue的dispatchSensorEvent方法,将数据传到SystemSensorManager