本文以android13 代码为基础,分析android sensor模块,主要以sensorservice 启动,sensor 注册和sensor数据上报逻辑为主。
1. sensorservice 启动
APP 通过调用API接口
1. public Sensor getDefaultSensor(int type)
2. public boolean registerListener(SensorListener listener, int sensors)
3. public void unregisterListener(SensorListener listener, int sensors)
4. public List<Sensor> getSensorList(int type)
//获取sensor 类型
public HeadingSensor(SensorManager sensorManager) {
mSensorManager = sensorManager;
mAccelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mMagneticSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}
/**
* Activates corresponding device sensors to start calculating device heading.
* This would increase power consumption.
*/
public void activate() {
// Get events from the accelerometer and magnetic sensor.
if (mAccelerometerSensor != null) {
mSensorManager.registerListener(this, mAccelerometerSensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
if (mMagneticSensor != null) {
mSensorManager.registerListener(this, mMagneticSensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
}
/**
* Deactivates corresponding device sensors to stop calculating device heading.
*/
public void deactivate() {
// Unregister the sensors.
if (mAccelerometerSensor != null) {
mSensorManager.unregisterListener(this, mAccelerometerSensor);
}
if (mMagneticSensor != null) {
mSensorManager.unregisterListener(this, mMagneticSensor);
}
}
Framework
framework 分成java \jni\native 层
接口层
/frameworks/base/core/java/android/hardware/SensorManager.java
接口实现
/frameworks/base/core/java/android/hardware/SystemSensorManager.java
JNI 实现
接口的实现最终通过JNI到Native层SensorManager.cpp 代码
/frameworks/base/core/jni/android_hardware_SensorManager.cpp
static jlong
nativeCreate
(JNIEnv *env, jclass clazz, jstring opPackageName)
{
ScopedUtfChars opPackageNameUtf(env, opPackageName);
return (jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str()));
}
其中nativeCreate new出SensorManager类
SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) {
waitForSensorService(nullptr);
Mutex::Autolock _l(sLock);
SensorManager* sensorManager;
auto iterator = sPackageInstances.find(packageName);
if (iterator != sPackageInstances.end()) {
sensorManager = iterator->second;
} else {
String16 opPackageName = packageName;
// It is possible that the calling code has no access to the package name.
// In this case we will get the packages for the calling UID and pick the
// first one for attributing the app op. This will work correctly for
// runtime permissions as for legacy apps we will toggle the app op for
// all packages in the UID. The caveat is that the operation may be attributed
// to the wrong package and stats based on app ops may be slightly off.
if (opPackageName.size() <= 0) {
sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
if (binder != nullptr) {
const uid_t uid = IPCThreadState::self()->getCallingUid();
Vector<String16> packages;
interface_cast<IPermissionController>(binder)->getPackagesForUid(uid, packages);
if (!packages.isEmpty()) {
opPackageName = packages[0];
} else {
ALOGE("No packages for calling UID");
}
} else {
ALOGE("Cannot get permission service");
}
}
sensorManager = new SensorManager(opPackageName);
// If we had no package name, we looked it up from the UID and the sensor
// manager instance we created should also be mapped to the empty package
// name, to avoid looking up the packages for a UID and get the same result.
if (packageName.size() <= 0) {
sPackageInstances.insert(std::make_pair(String16(), sensorManager));
}
// Stash the per package sensor manager.
sPackageInstances.insert(std::make_pair(opPackageName, sensorManager));
}
return *sensorManager;
}