MTKSensor框架及信息传递详解
⼀、概述
sensor(传感器)作为⼿机中⼀个⾮常重要且⽬前来说不可或缺的⼀种组件,功能强⼤,但是使⽤却很简单。Android 传感器属于虚拟设备,可提供来⾃以下各种物理传感器的数据:加速度计、陀螺仪、磁⼒计、⽓压计、湿度传感器、压⼒传感器、光传感器、近程传感器和⼼率传感器。因为对于⽇常⽣活来说有⼀部分sensor是使⽤频率是很⾼的,所以必然也伴随着⼿机功耗的增加如果每次都是CPU进⾏处理的化,⽽且CPU⼀旦休眠还伴随着sensor会停⽌⼯作,为了优化⼿机使⽤Google和MTK分别开发了CHRE 和SCP 进⾏sensor控制。
⾸先介绍以下SCP:
SCP 是⽤来处理sensor和audio相关功能和其他客制化需求的⼀个协处理理器,MTK SCP选择freeRTOS作为操作系统,CHRE是处理传感器相关操作的专门任务,它的架构如下
然后是CHRE:
在SCP下,MTK传感器集线器功能是在google CHRE ar上开发的,chre(Context Hub Runtime Environment)是⼀种事件驱动的体系结构,也可以被视为操作系统。
黄⾊部分是事件队列,CHRE只有⼀个while循环来处理事件队列中的头事件。如果以前的调⽤尚未完成,CHRE将⽆法调⽤队列中的⼀个任务。因此,没有优先级概念,当前事件队列处理只能
被中断中断。默认情况下,CHRE在事件队列中最多⽀持512个事件。CHRE的⽬的是实现实时性和轻量级,因此事件队列中调⽤的所有任务都必须快速运⾏。CHRE中的驱动程序实现称为nano hub app。
整个sensor体系中包括:应⽤层、framework层、jni、hal层、kernel层、SCP/CHRE。
⼆、应⽤层调⽤
sensor在应⽤层调⽤⾮常简单,代码如下:
public class SensorActivity extends Activity implements SensorEventListener {
private final SensorManager mSensorManager;
private final Sensor mAccelerometer;
public SensorActivity() {
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mAccelerometer = DefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
protected void onResume() {
}
protected void onPause() {
mSensorManager.unregisterListener(this);
手机unknown是什么意思}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
}
}
只需要获取到sensormanager然后注册监听就可以,sensor的信息就会通过回调接⼝上报上来
getSystemService 获取系统服务的标准接⼝,参数是表⽰要获取的服务类型
三、framework层
经过上层的getSystemService获取了服务,功能就来到了framework层,这⾥对应
framework/base/core/java/android/hardware/SensorManager.java,但是实际上这只是⼀个代理抽象类,真正获取的是SystemSensorManager:framework/base/core/java/android/hardware/SystemSensorManager.java。
(从SystemServiceRegistry.java中可以看出,这是⼀个专门为上层注册接⼝的类)。
SystemSensorManager 在最上层控制着所有的sensor ,他的实现仅仅靠⾃⼰是不够的,它还链接了⼀个jni库,注册了很多native⽅法。android_hardware_SensorManager :framework/base/core/jni/android_hardware_SensorManager.cpp
static const JNINativeMethod gSystemSensorManagerMethods[] = {
{"nativeClassInit",
"()V",
(void*)nativeClassInit },
{"nativeCreate",
"(Ljava/lang/String;)J",
(void*)nativeCreate },
{"nativeGetSensorAtIndex",
"(JLandroid/hardware/Sensor;I)Z",
(void*)nativeGetSensorAtIndex },
{"nativeGetDynamicSensors",
"(JLjava/util/List;)V",
(void*)nativeGetDynamicSensors },
{"nativeIsDataInjectionEnabled",
"(J)Z",
(void*)nativeIsDataInjectionEnabled },
{"nativeCreateDirectChannel",
"(JJIILandroid/hardware/HardwareBuffer;)I",
(void*)nativeCreateDirectChannel },
{"nativeDestroyDirectChannel",
"(JI)V",
(void*)nativeDestroyDirectChannel },
{"nativeConfigDirectChannel",
"(JIII)I",
(void*)nativeConfigDirectChannel },
(void*)nativeConfigDirectChannel },
{"nativeSetOperationParameter",
"(JII[F[I)I",
(void*)nativeSetOperationParameter },
};
static const JNINativeMethod gBaseEventQueueMethods[] = {
{"nativeInitBaseEventQueue",
"(JLjava/lang/ref/WeakReference;Landroid/os/MessageQueue;Ljava/lang/String;ILjava/lang/" "String;Ljava/lang/String;)J",
(void *)nativeInitSensorEventQueue},
{"nativeEnableSensor", "(JIII)I", (void *)nativeEnableSensor},
{"nativeDisableSensor", "(JI)I", (void *)nativeDisableSensor},
{"nativeDestroySensorEventQueue", "(J)V", (void *)nativeDestroySensorEventQueue},
{"nativeFlushSensor", "(J)I", (void *)nativeFlushSensor},
{"nativeInjectSensorData", "(JI[FIJ)I", (void *)nativeInjectSensorData},
};
} //unnamed namespace
int register_android_hardware_SensorManager(JNIEnv *env)
{
RegisterMethodsOrDie(env, "android/hardware/SystemSensorManager",
gSystemSensorManagerMethods, NELEM(gSystemSensorManagerMethods));
RegisterMethodsOrDie(env, "android/hardware/SystemSensorManager$BaseEventQueue",
gBaseEventQueueMethods, NELEM(gBaseEventQueueMethods));
gBaseEventQueueClassInfo.clazz = FindClassOrDie(env,
"android/hardware/SystemSensorManager$BaseEventQueue");
gBaseEventQueueClassInfo.dispatchSensorEvent = GetMethodIDOrDie(env,
gBaseEventQueueClassInfo.clazz, "dispatchSensorEvent", "(I[FIJ)V");
gBaseEventQueueClassInfo.dispatchFlushCompleteEvent = GetMethodIDOrDie(env,
gBaseEventQueueClassInfo.clazz, "dispatchFlushCompleteEvent", "(I)V");
gBaseEventQueueClassInfo.dispatchAdditionalInfoEvent = GetMethodIDOrDie(env,
gBaseEventQueueClassInfo.clazz, "dispatchAdditionalInfoEvent", "(III[F[I)V");
return 0;
}
上⾯代码是android_hardware_SensorManager⽤来绑定java类和相关⽅法的。然后⼜将⽅法实现转移到
SensorManager.cpp:framework/native/libs/sensor/SensorManager.cpp,
SystemSensorManager创建时 会创建native SensorManager的实例并持有,然后获取sensorlist。SystemSensorManager中封装了很多⽅法,如:启⽤、禁⽤、刷新、添加监听等等。
SensorManager 也不是⾃⼰去做事情,它通过BitTube和SensorService 链接,将指令传到sensorservice。
android_hardware_SensorManager 有⼀个内部类专门监听了BitTube通道⽂件描述符,会将sensor上报的信息通过这⾥上报到上层。
然后所有的事情都会转移到frameworks/native/services/sensorservice/ 这个包中,这⾥⾯会对所有sensor信息进⾏整理过滤,这⾥的所有信息都是从hal层获取,这⾥有个很关键的类SensorDevice,这个类链接了hal层
SensorDevice::SensorDevice()
: mHidlTransportErrors(20),
mRestartWaiter(new HidlServiceRegistrationWaiter()),
mEventQueueFlag(nullptr),
mWakeLockQueueFlag(nullptr),
mReconnecting(false) {
if (!connectHidlService()) {
return;
}
initializeSensorList();
mIsDirectReportSupported =
(checkReturnAndGetStatus(mSensors->unregisterDirectChannel(-1)) != INVALID_OPERATION);
}
...
bool SensorDevice::connectHidlService() {
HalConnectionStatus status = connectHidlServiceV2_1(); // 链接hal 2.1
if (status == HalConnectionStatus::DOES_NOT_EXIST) {
status = connectHidlServiceV2_0(); // 链接 hal 2.0
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论