前言
研究代码永远是学习进入的最好方式,因为本人更多的工作内容还是在farmework层,这里把之前的一些研究也总结一下。所有的研究都是基于
Android 9.0。
一、Sensor框架概述
关于Sensor框架在网上描述的也挺多的,我也不做深入分析了,这里把自己的思考在这里做一下总结。
整个Android的思路都是server-client的思路,Sensor也不例外,Sensor框架也分为两部分,
1.1 client --SensorManager(frameworks\base\core\java\android\hardware)SensorManager类,它提供给客户实际操作。围绕SystemSensorManager,还有一系列相关类
1.1.1 java层
➢SensorManager.java --虚类
➢LegacySensorManager--9.0已废除
➢SensorListener.java --监听类
➢Sensor.java ---单个sensor的抽象,用户通过该类对Sensor进行具体实现
➢SystemSensorManager--SensorManager的实现类,实际上上层对Sensor的控制都在SystemSensorManager
1.1.2 jni层
android_hardware_SensorManager.cpp(frameworks\base\core\jni)
1.2 server--SensorService(frameworks\native\services\sensorservice)
SensorService及其一系列代码的主要功能是实现对hal层的的访问,实现虚拟传感器的的相关算法SensorService.cpp --传感器服务
SensorDevice.cpp-管理传感器
RotationVectorSensor.cpp-虚拟传感器
1.3 Hal层
hal层是由厂家自己实现的,它对上提供给SensorService访问,对下直接访问驱动,每一款不同的SOC写法不一样,但都遵照了相Android的相关规则。这里后续描述。
1.4 驱动层
驱动实现了sensor的具体的功能,比如加速度传感器主要是获得xyz的加速度等等。
二、启动
2.1 SensorService的启动
Android启动过程中,先启动SensorService,然后调用hal层进行相关初始化,并进入相关轮询状态。
2.1.1 startBootstrapServices() frameworks\base\services\java\com\android\server\SystemServer.java
/**
* Start the sensor service. This is a blocking call and can take time.
*/
private static native void startSensorService();
private void startBootstrapServices() {
.............................
// The sensor service needs access to package manager service, app ops
// service, and permissions service, therefore we start it after them.
// Start sensor service in a separate thread. Completion should be checked
// before using it.
mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
TimingsTraceLog traceLog = new TimingsTraceLog(
SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
traceLog.traceBegin(START_SENSOR_SERVICE);
//启动sensor,在jni中实现
startSensorService();
traceLog.traceEnd();
}, START_SENSOR_SERVICE);
}
2.1.2 startSensorService()
frameworks\base\services\core\jni\com_android_server_SystemServer.cpp
startSensorService直接在jni中实现
/*
* JNI registration.
*/
static const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{ "startSensorService", "()V", (void*) android_server_SystemServer_startSensorService },
{ "startHidlServices", "()V", (void*) android_server_SystemServer_startHidlServices },
};
static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
//直接调用SensorService::instantiate()
SensorService::instantiate();
}
}
2.1.3 SensorService::instantiate()
SensorService继承自BinderService,SensorService::instantiate()会进一步执行BinderService::instantiate,在BinderService中会执行addService,然后将SensorService加入到ServiceManager中。
2.1.4 SensorService::onFirstRef()
SensorService还继承了RefBase,所以会在第一次调用时,调用onFirstRef,而SensorService的初始化就是在onFirstRef中完成。onFirstRef中,比较重要的初始化内容包括:
2.1.4.1.创建SensorDevice,SensorDevice是负责与Hal层连接的关键类
2.1.4.2.从SensorDevice获得当前的传感器列表,并判断当前系统存在哪些传感器,创建对应的相关类,
2.1.4.3 根据当前传感器,创建虚拟传感器类。
从代码上看,一些虚拟传感器的创建关系如下:
加速度/地磁/陀螺仪都有:
RotationVectorSensor
OrientationSensor
LinearAccelerationSensor
CorrectedGyroSensor
GyroDriftSensor
加速度/陀螺仪:
GameRotationVectorSensor
GravitySensor
加速度/地磁:
GeoMagRotationVectorSensor
void SensorService::onFirstRef() {
ALOGD("nuSensorService starting...");
//2.1.4.1===
SensorDevice& dev(SensorDevice::getInstance());
sHmacGlobalKeyIsValid = initializeHmacKey();
if (dev.initCheck() == NO_ERROR) {
sensor_t const* list;
//2.1.4.2===传感器创建
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);
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) {
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();
//2.1.4.3===虚拟传感器创建
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();
}
//2.1.4.4===运行
//会启动threadLoop
mInitCheck = NO_ERROR;
mAckReceiver = new SensorEventAckReceiver(this);
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
run("SensorService", PRIORITY_URGENT_DISPLAY);
// priority can only be changed after run
enableSchedFifoMode();
// Start watching UID changes to apply policy.
mUidPolicy->registerSelf();
}
}
}
2.1.5 SensorService::threadLoop()
SensorService::threadLoop()主要实现对sensor的poll,轮询sensor上报的相关事件
2.2 SensorService传感器的激活
SensorService除了了启动,还需要将已有的传感器进行activate,通常再底层驱动的实现过程中,只有activate后的传感器才会向上上报数据。
从代码跟踪上看Android启动过程中会向SystemSensorManager.注册registerListener,并进一步调用registerListenerImpl。
registerListenerImpl会获得SensorEventQueue ,并调用SensorEventQueue 的addSensor。
/** @hide */
@Override
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
................
// Invariants to preserve:
// - one Looper per SensorEventListener
// - one Looper per SensorEventQueue
// We map SensorEventListener to a SensorEventQueue, which holds the looper
synchronized (mSensorListeners) {
//获得SensorEventQueue
SensorEventQueue queue = mSensorListeners.get(listener);
if (queue == null) {
Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
final String fullClassName =
listener.getClass().getEnclosingClass() != null
? listener.getClass().getEnclosingClass().getName()
: listener.getClass().getName();
queue = new SensorEventQueue(listener, looper, this, fullClassName);
//向queue 中添加要监听的传感器
if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
queue.dispose();
return false;
}
mSensorListeners.put(listener, queue);
return true;
} else {
Log.e(TAG, "registerListenerImpl33333");
return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
}
}
}
SensorEventQueue是SystemSensorManager的内部类,具体实现类是InjectEventQueue。
SensorEventQueue中的addSensor,会将上层要监听的sensor加入到监听队列中,并调用enableSensor使能对应的传感器
public boolean addSensor(
Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {
// Check if already present.
int handle = sensor.getHandle();
if (mActiveSensors.get(handle)) return false;
// Get ready to receive events before calling enable.
mActiveSensors.put(handle, true);
//添加监听队列
addSensorEvent(sensor);
//使能传感器
if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) {
// Try continuous mode if batching fails.
if (maxBatchReportLatencyUs == 0
|| maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
removeSensor(sensor, false);
return false;
}
}
return true;
}
private int enableSensor(
Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
if (mNativeSensorEventQueue == 0) throw new NullPointerException();
if (sensor == null) throw new NullPointerException();
//调用android_hardware_SensorManager.cpp jni使能传感器
return nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs,
maxBatchReportLatencyUs);
}
android_hardware_SensorManager.cpp jni使能传感器 开始调用SensorEventQueue
static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us,
jint maxBatchReportLatency) {
sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
ALOGI("nativeEnableSensor");
return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,
0);
}
SensorEventQueue会调用SensorEventConnection
status_t SensorEventQueue::enableSensor(Sensor const* sensor, int32_t samplingPeriodUs) const {
ALOGE("SensorEventQueue enableSensor");
return mSensorEventConnection->enableDisable(sensor->getHandle(), true,
us2ns(samplingPeriodUs), 0, 0);
}
SensorEventConnection会调用SensorService进行传感器激活
status_t SensorService::SensorEventConnection::enableDisable(
int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
int reservedFlags)
{
status_t err;
if (enabled) {
ALOGE("SensorEventConnection::enableDisabl");
err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
reservedFlags, mOpPackageName);
} else {
err = mService->disable(this, handle);
}
return err;
}
03-20 11:12:18.037 3509 3524 D SensorService: Calling batch handle==0 flags=0rate=66667000 timeout== 100000000
03-20 11:12:18.037 3509 3524 D SensorService: Calling batch handle==0 flags=0rate=66667000 timeout== 100000000
03-20 11:12:18.037 3509 3524 D SensorService: SensorDevice::batch: ident=0x9a4d1180, handle=0x00000000, flags=0, period_ns=66667000 timeout=100000000
03-20 11:12:18.037 3509 3524 D SensorService: >>> curr_period=9223372036854775807 min_period=66667000 curr_timeout=9223372036854775807 min_timeout=100000000
03-20 11:12:18.037 3509 3524 D SensorService: >>> actuating h/w BATCH 0x00000000 66667000 100000000
03-20 11:12:18.038 3509 3524 D SensorService: Calling activate on 0
03-20 11[ 26.291237@2] sensors 2-006b: sensor on: starting poll sensor data 64ms
:12:18.038 3509 3524 D SensorService: SensorDevice::activate: ident=0x9a4d1180, handle=0x00000000, enabled=1, count=1
03-20 11:12:18.038 3509 3524 D SensorService: enable index=0
03-20 11:12:18.038 3509 3524 D SensorService: >>> actuating h/w activate handle=0 enabled=1