赞
踩
本文基于android-10.0.0_r36 – 清华大学开源软件镜像站AOSP
Android 传感器概览:sensors_overview
传感器堆栈:sensor-stack
魅族内核团队:Android Sensor Framework 概览
对照 Android 平台架构
Android 平台支持三大类传感器:
动态传感器
这类传感器测量三个轴向上的加速力和旋转力。这个类别中包含加速度计、重力传感器、陀螺仪和旋转矢量传感器。
环境传感器
这类传感器测量各种环境参数,如环境气温、气压、照度和湿度。这个类别中包含气压计、光度计和温度计。
位置传感器
这类传感器测量设备的物理位置。这个类别中包含屏幕方向传感器和磁力计。
传感器 | 类型 | 说明 | 常见用途 |
---|---|---|---|
TYPE_ACCELEROMETER | 硬件 | 测量在所有三个物理轴向(x、y 和 z)上施加在设备上的加速力(包括重力),以 m/s2 为单位。 | 动态检测(摇晃、倾斜等)。 |
TYPE_AMBIENT_TEMPERATURE | 硬件 | 以摄氏度 (°C) 为单位测量环境室温。请参见下面的备注。 | 监测气温。 |
TYPE_GRAVITY | 软件或硬件 | 测量在所有三个物理轴向(x、y、z)上施加在设备上的重力,单位为 m/s2。 | 动态检测(摇晃、倾斜等)。 |
TYPE_GYROSCOPE | 硬件 | 测量设备在三个物理轴向(x、y 和 z)上的旋转速率,以 rad/s 为单位。 | 旋转检测(旋转、转动等)。 |
TYPE_LIGHT | 硬件 | 测量环境光级(照度),以 lx 为单位。 | 控制屏幕亮度。 |
TYPE_LINEAR_ACCELERATION | 软件或硬件 | 测量在所有三个物理轴向(x、y 和 z)上施加在设备上的加速力(不包括重力),以 m/s2 为单位。 | 监测单个轴向上的加速度。 |
TYPE_MAGNETIC_FIELD | 硬件 | 测量所有三个物理轴向(x、y、z)上的环境地磁场,以 μT 为单位。 | 创建罗盘。 |
TYPE_ORIENTATION | 软件 | 测量设备围绕所有三个物理轴(x、y、z)旋转的度数。从 API 级别 3 开始,您可以结合使用重力传感器、地磁场传感器和 getRotationMatrix() 方法来获取设备的倾角矩阵和旋转矩阵。 | 确定设备位置。 |
TYPE_PRESSURE | 硬件 | 测量环境气压,以 hPa 或 mbar 为单位。 | 监测气压变化。 |
TYPE_PROXIMITY | 硬件 | 测量物体相对于设备显示屏幕的距离,以 cm 为单位。该传感器通常用于确定手机是否被举到人的耳边。 | 通话过程中手机的位置。 |
TYPE_RELATIVE_HUMIDITY | 硬件 | 测量环境的相对湿度,以百分比 (%) 表示。 | 监测露点、绝对湿度和相对湿度。 |
TYPE_ROTATION_VECTOR | 软件或硬件 | 通过提供设备旋转矢量的三个元素来检测设备的屏幕方向。 | 动态检测和旋转检测。 |
TYPE_TEMPERATURE | 硬件 | 测量设备的温度,以摄氏度 (°C) 为单位。该传感器的实现因设备而异。在 API 级别 14 中,该传感器已被 TYPE_AMBIENT_TEMPERATURE 传感器取代 | 监测温度。 |
重力传感器提供指示重力方向和大小的三维矢量。通常,此传感器用于确定设备在空间中的相对屏幕方向。
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
计步器传感器提供自已激活传感器后最后一次重启以来用户迈出的步数。与步测器传感器相比,计步器的延迟时间更长(最多 10 秒),但精确度更高。
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
每次用户迈步时,步测器传感器都会触发事件。延迟时间预计将低于 2 秒。
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
近程传感器可让您确定物体与设备的距离。
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
近程传感器通常用于确定人的头部距手持设备表面的距离(例如,当用户拨打或接听电话时)。大多数近程传感器返回以厘米为单位的绝对距离,但有些仅返回近距离和远距离值。
public class SensorActivity extends Activity implements SensorEventListener { private SensorManager sensorManager; private Sensor proximity; @Override public final void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Get an instance of the sensor service, and use that to get an instance of // a particular sensor. sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); proximity = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); } @Override public final void onAccuracyChanged(Sensor sensor, int accuracy) { // Do something here if sensor accuracy changes. } @Override public final void onSensorChanged(SensorEvent event) { float distance = event.values[0]; // Do something with this sensor data. } @Override protected void onResume() { // Register a listener for the sensor. super.onResume(); sensorManager.registerListener(this, proximity, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { // Be sure to unregister the sensor when the activity pauses. super.onPause(); sensorManager.unregisterListener(this); } }
地磁旋转矢量传感器与旋转矢量传感器类似,但前者使用磁力计而非陀螺仪。此传感器的精度比普通旋转矢量传感器低,但能耗也有所降低。如果您希望在不消耗过多电量的情况下收集后台中的某些旋转信息,则可以仅使用此传感器。
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR);
从光、压力和温度传感器获取的原始数据通常不需要校准、滤波或修改,因此它们是一些最容易使用的传感器。要从这些传感器获取数据,您需要先创建 SensorManager 类的实例,并用它来获取物理传感器的实例。然后,在 onResume() 方法中注册传感器监听器,并开始在 onSensorChanged() 回调方法中处理传入的传感器数据。
public class SensorActivity extends Activity implements SensorEventListener { private SensorManager sensorManager; private Sensor pressure; @Override public final void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Get an instance of the sensor service, and use that to get an instance of // a particular sensor. sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); pressure = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE); } @Override public final void onAccuracyChanged(Sensor sensor, int accuracy) { // Do something here if sensor accuracy changes. } @Override public final void onSensorChanged(SensorEvent event) { float millibarsOfPressure = event.values[0]; // Do something with this sensor data. } @Override protected void onResume() { // Register a listener for the sensor. super.onResume(); sensorManager.registerListener(this, pressure, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { // Be sure to unregister the sensor when the activity pauses. super.onPause(); sensorManager.unregisterListener(this); } }
可以利用 Android 传感器框架来访问这些传感器并获取传感器的原始数据。传感器框架是 android.hardware 软件包的一部分,包含了以下类和接口:
在典型的应用中,您可以使用这些与传感器相关的 API 来执行两个基本任务:
识别传感器和传感器特性
如果应用具有依赖于特定传感器类型或特性的功能,则在运行时识别传感器和传感器特性非常有用。例如,您可能希望识别设备上的所有传感器,以便于停用依赖于不存在的传感器的应用功能。同样,您可能希望识别特定类型的所有传感器,以便选择可以为应用带来最佳性能的传感器实现。
监控传感器事件
您可以通过监控传感器事件来获取原始传感器数据。每当传感器检测到它所测量的参数发生变化时,就会发生传感器事件。传感器事件为您提供 4 项信息:触发事件的传感器的名称、事件的时间戳、事件的准确度以及触发事件的原始传感器数据。
使用 SensorManager 和Sensor 获取
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL); //列出所有传感器
pressure = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE); //获取特定传感器
SystemServer 负责启动,在引导服务 startBootstrapServices 中启动 startSensorService()
/** * Start the sensor service. This is a blocking call and can take time. */ private static native void startSensorService(); private void startBootstrapServices() { ... traceBeginAndSlog("StartSensorPrivacyService"); mSystemServiceManager.startService(new SensorPrivacyService(mSystemContext)); traceEnd(); ... // 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); startSensorService();//调用JNI接口,启动SensorService traceLog.traceEnd(); }, START_SENSOR_SERVICE); }
SensorPrivacyService初步了解:
在飞行模式下,设备仍可以访问某些传感器以启用特定功能,比如屏幕旋转和拍照。Android 10 提供了一个开发者选项设置,用于关闭设备中的所有传感器。(设置 > 系统 > 开发者选项 > 快捷设置开发者图块中可启用传感器已关闭)
管理传感器已关闭状态并向客户端传达状态变更的系统服务位于
frameworks/base/services/core/java/com/android/server/SensorPrivacyService.java
frameworks/base/core/java/android/hardware/SensorPrivacyManager.java。
在其他服务 startOtherServices 中启动 startHidlServices()
/** * Start all HIDL services that are run inside the system server. This may take some time. */ private static native void startHidlServices(); private void startOtherServices() { ... // Start receiving calls from HIDL services. Start in in a separate thread // because it need to connect to SensorManager. This have to start // after START_SENSOR_SERVICE is done. SystemServerInitThreadPool.get().submit(() -> { TimingsTraceLog traceLog = new TimingsTraceLog( SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER); traceLog.traceBegin(START_HIDL_SERVICES); startHidlServices(); traceLog.traceEnd(); }, START_HIDL_SERVICES); ... }
SystemSensorManager 该类主要实现 SensorManager 控制和数据获取的逻辑。
frameworks/base/core/java/android/app/SystemServiceRegistry.java
static {
//......
registerService(Context.SENSOR_SERVICE, SensorManager.class,
new CachedServiceFetcher<SensorManager>() {
@Override
public SensorManager createService(ContextImpl ctx) {
return new SystemSensorManager(ctx.getOuterContext(),
ctx.mMainThread.getHandler().getLooper());
}});
//......
}
frameworks/base/core/java/android/hardware/SystemSensorManager.java
public class SystemSensorManager extends SensorManager { //...... /** {@hide} */ public SystemSensorManager(Context context, Looper mainLooper) { synchronized (sLock) { if (!sNativeClassInited) { sNativeClassInited = true; nativeClassInit(); } } mMainLooper = mainLooper; mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion; mContext = context; mNativeInstance = nativeCreate(context.getOpPackageName()); // initialize the sensor list for (int index = 0;; ++index) { Sensor sensor = new Sensor(); if (!nativeGetSensorAtIndex(mNativeInstance, sensor, index)) break; mFullSensorsList.add(sensor); mHandleToSensor.put(sensor.getHandle(), sensor); } }
注册 SensorEventListener 监听;监控原始传感器数据,需要通过 SensorEventListener 接口公开的回调方法:onAccuracyChanged() 和 onSensorChanged()。
SystemSensorManager
该类主要实现 SensorManager 控制和数据获取的逻辑。
文件路径:frameworks/base/core/java/android/hardware/SystemSensorManager.java
protected boolean registerListenerImpl(clistener, Sensor sensor, int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) { if (listener == null || sensor == null) { Log.e(TAG, "sensor or listener is null"); return false; } // Trigger Sensors should use the requestTriggerSensor call. if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { Log.e(TAG, "Trigger Sensors should use the requestTriggerSensor."); return false; } if (maxBatchReportLatencyUs < 0 || delayUs < 0) { Log.e(TAG, "maxBatchReportLatencyUs and delayUs should be non-negative"); return false; } if (mSensorListeners.size() >= MAX_LISTENER_COUNT) { throw new IllegalStateException("register failed, " + "the sensor listeners size has exceeded the maximum limit " + MAX_LISTENER_COUNT); } // Invariants to preserve: // - one Looper per SensorEventListener // - one Looper per SensorEventQueue // We map SensorEventListener to a SensorEventQueue, which holds the looper synchronized (mSensorListeners) { 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); if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) { queue.dispose(); return false; } mSensorListeners.put(listener, queue); return true; } else { return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs); } } }
Handler\Looper
将SensorEventListener映射到SensorEventQueue
dispatchSensorEvent分发mListener.onSensorChanged、mListener.onAccuracyChanged(当accuracy值改变时)
还有dispatchFlushCompleteEvent、dispatchAdditionalInfoEvent
dispatch事件都有注释Called from native code,通过BaseEventQueue的JNI
static final class SensorEventQueue extends BaseEventQueue { private final SensorEventListener mListener; private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>(); public SensorEventQueue(SensorEventListener listener, Looper looper, SystemSensorManager manager, String packageName) { super(looper, manager, OPERATING_MODE_NORMAL, packageName); mListener = listener; } @Override public void addSensorEvent(Sensor sensor) { SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor, mManager.mTargetSdkLevel)); synchronized (mSensorsEvents) { mSensorsEvents.put(sensor.getHandle(), t); } } @Override public void removeSensorEvent(Sensor sensor) { synchronized (mSensorsEvents) { mSensorsEvents.delete(sensor.getHandle()); } } // Called from native code. @SuppressWarnings("unused") @Override protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy, long timestamp) { final Sensor sensor = mManager.mHandleToSensor.get(handle); if (sensor == null) { // sensor disconnected return; } SensorEvent t = null; synchronized (mSensorsEvents) { t = mSensorsEvents.get(handle); } if (t == null) { // This may happen if the client has unregistered and there are pending events in // the queue waiting to be delivered. Ignore. return; } // Copy from the values array. System.arraycopy(values, 0, t.values, 0, t.values.length); t.timestamp = timestamp; t.accuracy = inAccuracy; t.sensor = sensor; // call onAccuracyChanged() only if the value changes final int accuracy = mSensorAccuracies.get(handle); if ((t.accuracy >= 0) && (accuracy != t.accuracy)) { mSensorAccuracies.put(handle, t.accuracy); mListener.onAccuracyChanged(t.sensor, t.accuracy); } mListener.onSensorChanged(t); } // Called from native code. @SuppressWarnings("unused") @Override protected void dispatchFlushCompleteEvent(int handle) { if (mListener instanceof SensorEventListener2) { final Sensor sensor = mManager.mHandleToSensor.get(handle); if (sensor == null) { // sensor disconnected return; } ((SensorEventListener2) mListener).onFlushCompleted(sensor); } return; } // Called from native code. @SuppressWarnings("unused") @Override protected void dispatchAdditionalInfoEvent( int handle, int type, int serial, float[] floatValues, int[] intValues) { if (mListener instanceof SensorEventCallback) { final Sensor sensor = mManager.mHandleToSensor.get(handle); if (sensor == null) { // sensor disconnected return; } SensorAdditionalInfo info = new SensorAdditionalInfo(sensor, type, serial, intValues, floatValues); ((SensorEventCallback) mListener).onSensorAdditionalInfo(info); } } }
private abstract static class BaseEventQueue { private static native long nativeInitBaseEventQueue(long nativeManager, WeakReference<BaseEventQueue> eventQWeak, MessageQueue msgQ, String packageName, int mode, String opPackageName); private static native int nativeEnableSensor(long eventQ, int handle, int rateUs, int maxBatchReportLatencyUs); private static native int nativeDisableSensor(long eventQ, int handle); private static native void nativeDestroySensorEventQueue(long eventQ); private static native int nativeFlushSensor(long eventQ); private static native int nativeInjectSensorData(long eventQ, int handle, float[] values, int accuracy, long timestamp); private long mNativeSensorEventQueue; private final SparseBooleanArray mActiveSensors = new SparseBooleanArray(); protected final SparseIntArray mSensorAccuracies = new SparseIntArray(); private final CloseGuard mCloseGuard = CloseGuard.get(); protected final SystemSensorManager mManager; protected static final int OPERATING_MODE_NORMAL = 0; protected static final int OPERATING_MODE_DATA_INJECTION = 1; BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) { if (packageName == null) packageName = ""; mNativeSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance, new WeakReference<>(this), looper.getQueue(), packageName, mode, manager.mContext.getOpPackageName()); mCloseGuard.open("dispose"); mManager = manager; } public void dispose() { dispose(false); } 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; } public boolean removeAllSensors() { for (int i = 0; i < mActiveSensors.size(); i++) { if (mActiveSensors.valueAt(i) == true) { int handle = mActiveSensors.keyAt(i); Sensor sensor = mManager.mHandleToSensor.get(handle); if (sensor != null) { disableSensor(sensor); mActiveSensors.put(handle, false); removeSensorEvent(sensor); } else { // sensor just disconnected -- just ignore. } } } return true; } public boolean removeSensor(Sensor sensor, boolean disable) { final int handle = sensor.getHandle(); if (mActiveSensors.get(handle)) { if (disable) disableSensor(sensor); mActiveSensors.put(sensor.getHandle(), false); removeSensorEvent(sensor); return true; } return false; } public int flush() { if (mNativeSensorEventQueue == 0) throw new NullPointerException(); return nativeFlushSensor(mNativeSensorEventQueue); } public boolean hasSensors() { // no more sensors are set return mActiveSensors.indexOfValue(true) >= 0; } @Override protected void finalize() throws Throwable { try { dispose(true); } finally { super.finalize(); } } private void dispose(boolean finalized) { if (mCloseGuard != null) { if (finalized) { mCloseGuard.warnIfOpen(); } mCloseGuard.close(); } if (mNativeSensorEventQueue != 0) { nativeDestroySensorEventQueue(mNativeSensorEventQueue); mNativeSensorEventQueue = 0; } } private int enableSensor( Sensor sensor, int rateUs, int maxBatchReportLatencyUs) { if (mNativeSensorEventQueue == 0) throw new NullPointerException(); if (sensor == null) throw new NullPointerException(); return nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs, maxBatchReportLatencyUs); } protected int injectSensorDataBase(int handle, float[] values, int accuracy, long timestamp) { return nativeInjectSensorData( mNativeSensorEventQueue, handle, values, accuracy, timestamp); } private int disableSensor(Sensor sensor) { if (mNativeSensorEventQueue == 0) throw new NullPointerException(); if (sensor == null) throw new NullPointerException(); return nativeDisableSensor(mNativeSensorEventQueue, sensor.getHandle()); } @UnsupportedAppUsage protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy, long timestamp); @UnsupportedAppUsage protected abstract void dispatchFlushCompleteEvent(int handle); @UnsupportedAppUsage protected void dispatchAdditionalInfoEvent( int handle, int type, int serial, float[] floatValues, int[] intValues) { // default implementation is do nothing } protected abstract void addSensorEvent(Sensor sensor); protected abstract void removeSensorEvent(Sensor sensor); }
nativeInitBaseEventQueue : 创建一个接收数据的Receiver对象
addSensor
addSensorEvent
enableSensor : nativeEnableSensor
frameworks/base/services/core/jni/com_android_server_SystemServer.cpp
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::publish(false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL); } } static void android_server_SystemServer_startHidlServices(JNIEnv* env, jobject /* clazz */) { using ::android::frameworks::schedulerservice::V1_0::ISchedulingPolicyService; using ::android::frameworks::schedulerservice::V1_0::implementation::SchedulingPolicyService; using ::android::frameworks::sensorservice::V1_0::ISensorManager; using ::android::frameworks::sensorservice::V1_0::implementation::SensorManager; using ::android::hardware::configureRpcThreadpool; status_t err; configureRpcThreadpool(5, false /* callerWillJoin */); JavaVM *vm; LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Cannot get Java VM"); sp<ISensorManager> sensorService = new SensorManager(vm); err = sensorService->registerAsService(); ALOGE_IF(err != OK, "Cannot register %s: %d", ISensorManager::descriptor, err); sp<ISchedulingPolicyService> schedulingService = new SchedulingPolicyService(); err = schedulingService->registerAsService(); ALOGE_IF(err != OK, "Cannot register %s: %d", ISchedulingPolicyService::descriptor, err); }
frameworks/base/core/jni/android_hardware_SensorManager.cpp
该文件负责 jave 层和 native 层通信的 JNI 实现,上层的 Java 代码通过 JNI 调用 Native 层提供的服务。
SystemSensorManager.java构造函数先调用 nativeClassInit 和 nativeGetSensorAtIndex 获取系统支持的所有 Sensor 的参数(nativeClassInit 只会调用一次),包括名称、类型等参数。
nativeClassInit 获取Sensor.java类的成员变量和成员函数保存到gSensorOffsets中
/* * nativeClassInit is not inteneded to be thread-safe. It should be called before other native... * functions (except nativeCreate). */ static void nativeClassInit (JNIEnv *_env, jclass _this) { //android.hardware.Sensor SensorOffsets& sensorOffsets = gSensorOffsets; jclass sensorClass = (jclass) MakeGlobalRefOrDie(_env, FindClassOrDie(_env, "android/hardware/Sensor")); sensorOffsets.clazz = sensorClass; sensorOffsets.name = GetFieldIDOrDie(_env, sensorClass, "mName", "Ljava/lang/String;"); sensorOffsets.vendor = GetFieldIDOrDie(_env, sensorClass, "mVendor", "Ljava/lang/String;"); sensorOffsets.version = GetFieldIDOrDie(_env, sensorClass, "mVersion", "I"); sensorOffsets.handle = GetFieldIDOrDie(_env, sensorClass, "mHandle", "I"); sensorOffsets.range = GetFieldIDOrDie(_env, sensorClass, "mMaxRange", "F"); sensorOffsets.resolution = GetFieldIDOrDie(_env, sensorClass, "mResolution","F"); sensorOffsets.power = GetFieldIDOrDie(_env, sensorClass, "mPower", "F"); sensorOffsets.minDelay = GetFieldIDOrDie(_env, sensorClass, "mMinDelay", "I"); sensorOffsets.fifoReservedEventCount = GetFieldIDOrDie(_env,sensorClass, "mFifoReservedEventCount", "I"); sensorOffsets.fifoMaxEventCount = GetFieldIDOrDie(_env,sensorClass, "mFifoMaxEventCount", "I"); sensorOffsets.stringType = GetFieldIDOrDie(_env,sensorClass, "mStringType", "Ljava/lang/String;"); sensorOffsets.requiredPermission = GetFieldIDOrDie(_env,sensorClass, "mRequiredPermission", "Ljava/lang/String;"); sensorOffsets.maxDelay = GetFieldIDOrDie(_env,sensorClass, "mMaxDelay", "I"); sensorOffsets.flags = GetFieldIDOrDie(_env,sensorClass, "mFlags", "I"); sensorOffsets.setType = GetMethodIDOrDie(_env,sensorClass, "setType", "(I)Z"); sensorOffsets.setUuid = GetMethodIDOrDie(_env,sensorClass, "setUuid", "(JJ)V"); sensorOffsets.init = GetMethodIDOrDie(_env,sensorClass, "<init>", "()V"); // java.util.List; ListOffsets& listOffsets = gListOffsets; jclass listClass = (jclass) MakeGlobalRefOrDie(_env, FindClassOrDie(_env, "java/util/List")); listOffsets.clazz = listClass; listOffsets.add = GetMethodIDOrDie(_env,listClass, "add", "(Ljava/lang/Object;)Z"); // initialize java.lang.String and empty string intern StringOffsets& stringOffsets = gStringOffsets; stringOffsets.clazz = MakeGlobalRefOrDie(_env, FindClassOrDie(_env, "java/lang/String")); stringOffsets.intern = GetMethodIDOrDie(_env, stringOffsets.clazz, "intern", "()Ljava/lang/String;"); ScopedLocalRef<jstring> empty(_env, _env->NewStringUTF("")); stringOffsets.emptyString = (jstring) MakeGlobalRefOrDie(_env, _env->CallObjectMethod(empty.get(), stringOffsets.intern)); }
nativeGetSensorAtIndex 获取Sensor列表保存到Java层Sensor对象中
static jboolean
nativeGetSensorAtIndex(JNIEnv *env, jclass clazz, jlong sensorManager, jobject sensor, jint index)
{
SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
Sensor const* const* sensorList;
ssize_t count = mgr->getSensorList(&sensorList);
if (ssize_t(index) >= count) {
return false;
}
return translateNativeSensorToJavaSensor(env, sensor, *sensorList[index]) != NULL;
}
nativeCreate 创建Native层 SensorManager 建立与SensorService的连接
frameworks/native/libs/sensor/SensorManager.cpp:Sensor 在 Native 层的客户端,负责与服务端 SensorService.cpp 的通信
static jlong
nativeCreate
(JNIEnv *env, jclass clazz, jstring opPackageName)
{
ScopedUtfChars opPackageNameUtf(env, opPackageName);
return (jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str()));
}
nativeInitBaseEventQueue : 创建SensorEventQueue\创建一个接收数据的Receiver对象
static const JNINativeMethod gBaseEventQueueMethods[] = { {"nativeInitBaseEventQueue", "(JLjava/lang/ref/WeakReference;Landroid/os/MessageQueue;Ljava/lang/String;ILjava/lang/String;)J", (void*)nativeInitSensorEventQueue }, //...... }; static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager, jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) { SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); ScopedUtfChars packageUtf(env, packageName); String8 clientName(packageUtf.c_str()); sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode)); //创建SensorEventQueue if (queue == NULL) { jniThrowRuntimeException(env, "Cannot construct native SensorEventQueue."); return 0; } sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); return 0; } sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak);//创建一个接收数据的Receiver对象 receiver->incStrong((void*)nativeInitSensorEventQueue); return jlong(receiver.get()); }
获取套接字fd: mSensorQueue->getFd()
实际获取 SensorEventQueue > SensorEventConnection > BitTube 里边mReceiveFd
mReceiveFd添加到looper里边,在 system/core/libutils/Looper.cpp,会通过epoll监听该fd,当有事件时,就会回调Receiver::handleEvent()
virtual void onFirstRef() {
LooperCallback::onFirstRef();
mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0,
ALOOPER_EVENT_INPUT, this, mSensorQueue.get());
}
通过jni回调SystemSensorManager::dispatchSensorEvent(),将数据给SensorManager
virtual int handleEvent(int fd, int events, void* data) { JNIEnv* env = AndroidRuntime::getJNIEnv(); sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data); ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); ssize_t n; ASensorEvent buffer[16]; while ((n = q->read(buffer, 16)) > 0) { for (int i=0 ; i<n ; i++) { if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) { // step-counter returns a uint64, but the java API only deals with floats float value = float(buffer[i].u64.step_counter); env->SetFloatArrayRegion(mFloatScratch, 0, 1, &value); } else if (buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) { float value[2]; value[0] = buffer[i].dynamic_sensor_meta.connected ? 1.f: 0.f; value[1] = float(buffer[i].dynamic_sensor_meta.handle); env->SetFloatArrayRegion(mFloatScratch, 0, 2, value); } else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) { env->SetIntArrayRegion(mIntScratch, 0, 14, buffer[i].additional_info.data_int32); env->SetFloatArrayRegion(mFloatScratch, 0, 14, buffer[i].additional_info.data_float); } else { env->SetFloatArrayRegion(mFloatScratch, 0, 16, buffer[i].data); } if (buffer[i].type == SENSOR_TYPE_META_DATA) { // This is a flush complete sensor event. Call dispatchFlushCompleteEvent // method. if (receiverObj.get()) { env->CallVoidMethod(receiverObj.get(), gBaseEventQueueClassInfo.dispatchFlushCompleteEvent, buffer[i].meta_data.sensor); } } else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) { // This is a flush complete sensor event. Call dispatchAdditionalInfoEvent // method. if (receiverObj.get()) { int type = buffer[i].additional_info.type; int serial = buffer[i].additional_info.serial; env->CallVoidMethod(receiverObj.get(), gBaseEventQueueClassInfo.dispatchAdditionalInfoEvent, buffer[i].sensor, type, serial, mFloatScratch, mIntScratch, buffer[i].timestamp); } }else { int8_t status; switch (buffer[i].type) { case SENSOR_TYPE_ORIENTATION: case SENSOR_TYPE_MAGNETIC_FIELD: case SENSOR_TYPE_ACCELEROMETER: case SENSOR_TYPE_GYROSCOPE: case SENSOR_TYPE_GRAVITY: case SENSOR_TYPE_LINEAR_ACCELERATION: status = buffer[i].vector.status; break; case SENSOR_TYPE_HEART_RATE: status = buffer[i].heart_rate.status; break; default: status = SENSOR_STATUS_ACCURACY_HIGH; break; } // 通过jni回调SystemSensorManager::dispatchSensorEvent(),将数据给SensorManager if (receiverObj.get()) { env->CallVoidMethod(receiverObj.get(), gBaseEventQueueClassInfo.dispatchSensorEvent, buffer[i].sensor, mFloatScratch, status, buffer[i].timestamp); } } if (env->ExceptionCheck()) { mSensorQueue->sendAck(buffer, n); ALOGE("Exception dispatching input event."); return 1; } } mSensorQueue->sendAck(buffer, n); } if (n<0 && n != -EAGAIN) { // FIXME: error receiving events, what to do in this case? } return 1; }
frameworks/native/services/sensorservice/SensorService.cpp
SensorService 是 Android Sensor Framework 最核心的模块,它实现了主要的 Sensor控制流和数据流逻辑,完成 Sensor 参数配置,数据分发,Client 请求处理等功能。
frameworks/native/services/sensorservice/SensorService.h
class SensorService :
public BinderService<SensorService>,
public BnSensorServer,
protected Thread
{
继承BnSensorServer:frameworks/native/libs/sensor/include/sensor/ISensorServer.h
继承Thread
frameworks/native/libs/binder/include/binder/BinderService.h
template<typename SERVICE>
class BinderService
{
public:
static status_t publish(bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
dumpFlags);
}
SERVICE:模板声明是SensorService
defaultServiceManager: 获取ServiceManager对象。
SERVICE::getServiceName():SensorService加入到ServiceManager的key “sensorservice”
new SERVICE():new一个SensorService,然后 以 “sensorservice”为key,把sensorservice实例加入到ServiceManaer
BinderService 是 Android Service 框架的主要类,是个模板类,它提供了 Service 的生命周期管理、进程间通信、请求响应处理等功能。Android 中的绝大部分 Service 都会继承此类。
当 SensorService 第一个实例创建时,其 onFirstRef 接口将会被调用
void SensorService::onFirstRef() { // ① 在 SensorDevice 的构造函数中,会调用 hw_get_module 接口加载 Sensor HAL 的动态库 SensorDevice& dev(SensorDevice::getInstance()); //....... if (dev.initCheck() == NO_ERROR) { // ② 通过 SensorDevice,调用 Sensor HAL 提供的 get_sensors_list 接口,获取所支持的 Sensor 信息获,调用registerSensor函数把Sensor保存起来 sensor_t const* list; ssize_t count = dev.getSensorList(&list); //....... for (ssize_t i=0 ; i<count ; i++) { //....... if (useThisSensor) { registerSensor( new HardwareSensor(list[i]) ); } } // ③ SensorFusion功能,传感融合。它的主要作用就是,按照一定的算法计算系统的多个传感器对某一个值的上报的数据,得到更准确的值。 // it's safe to instantiate the SensorFusion object here // (it wants to be instantiated after h/w sensors have been // registered) SensorFusion::getInstance(); // ④ 注册虚拟传感器:这些虚拟的传感器步会产生真的数据,而是通过SensorFusion功能计算得到的值,作为虚拟传感的数据。 //....... registerSensor(new RotationVectorSensor(), !needRotationVector, true); registerSensor(new OrientationSensor(), !needRotationVector, true); registerSensor(new LinearAccelerationSensor(list, count), !needLinearAcceleration, true); registerSensor( new CorrectedGyroSensor(list, count), true, true); registerSensor( new GyroDriftSensor(), true, true); //....... registerSensor(new GravitySensor(list, count), !needGravitySensor, true); //....... registerSensor(new GameRotationVectorSensor(), !needGameRotationVector, true); //....... registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true); //....... // ⑤ 初始化一些Buffer,用他们保存sensor硬件上报的数据 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; //....... ⑥ 创建一个 Looper 和 SensorEventAckReceiver。其中 Looper 用于 enable sensor 后,进行数据的接收;而 SensorEventAckReceiver 则用于在 dispatch wake up sensor event 给上层后,接收上层返回的确认 ACK。 mAckReceiver = new SensorEventAckReceiver(this); mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY); // ⑦ SensorService 不仅是一个服务,而且他还是一个线程,初始化工作的最后就是启动该线程执行threadLoop函数。threadLoop函数主要的工作就是,循环读取sensor硬件上传上来的数据,然后分发给应用。 run("SensorService", PRIORITY_URGENT_DISPLAY); //....... }
① 在 SensorDevice 的构造函数中,会调用 hw_get_module 接口加载 Sensor HAL 的动态库
② 通过 SensorDevice,调用 Sensor HAL 提供的 get_sensors_list 接口,获取所支持的 Sensor 信息获,调用registerSensor函数把Sensor保存起来
③ SensorFusion功能,传感融合。它的主要作用就是,按照一定的算法计算系统的多个传感器对某一个值的上报的数据,得到更准确的值。
④ registerSensor (…, …, true)注册虚拟传感器:这些虚拟的传感器步会产生真的数据,而是通过SensorFusion功能计算得到的值,作为虚拟传感的数据。分发过程中会有分析到。
⑤ 初始化一些Buffer,用他们保存sensor硬件上报的数据
⑥ 创建一个 Looper 和 SensorEventAckReceiver。其中 Looper 用于 enable sensor 后,进行数据的接收;而 SensorEventAckReceiver 则用于在 dispatch wake up sensor event 给上层后,接收上层返回的确认 ACK。
⑦ SensorService 不仅是一个服务,而且他还是一个线程,初始化工作的最后就是启动该线程执行threadLoop函数。threadLoop函数主要的工作就是,循环读取sensor硬件上传上来的数据,然后分发给应用。
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 vcount = mSensors.getVirtualSensors().size(); const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; const size_t numEventMax = minBufferSize / (1 + vcount); SensorDevice& device(SensorDevice::getInstance()); const int halVersion = device.getHalDeviceVersion(); do { ssize_t count = device.poll(mSensorEventBuffer, numEventMax);//① if (count < 0) { if(count == DEAD_OBJECT && device.isReconnecting()) { device.reconnect(); continue; } else { 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; } ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock, // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and // releasing the wakelock. uint32_t wakeEvents = 0; for (int i = 0; i < count; i++) { if (isWakeUpSensorEvent(mSensorEventBuffer[i])) { wakeEvents++; } } if (wakeEvents > 0) { if (!mWakeLockAcquired) { setWakeLockAcquiredLocked(true); } device.writeWakeLockHandled(wakeEvents); } recordLastValueLocked(mSensorEventBuffer, count); // handle virtual sensors if (count && vcount) { sensors_event_t const * const event = mSensorEventBuffer; if (!mActiveVirtualSensors.empty()) { size_t k = 0; SensorFusion& fusion(SensorFusion::getInstance()); if (fusion.isEnabled()) { for (size_t i=0 ; i<size_t(count) ; i++) { fusion.process(event[i]); } } for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) { for (int handle : mActiveVirtualSensors) { if (count + k >= minBufferSize) { ALOGE("buffer too small to hold all events: " "count=%zd, k=%zu, size=%zu", count, k, minBufferSize); break; } sensors_event_t out; sp<SensorInterface> si = mSensors.getInterface(handle); if (si == nullptr) { ALOGE("handle %d is not an valid virtual sensor", handle); continue; } if (si->process(&out, event[i])) { mSensorEventBuffer[count + k] = out; k++; } } } if (k) { // record the last synthesized values recordLastValueLocked(&mSensorEventBuffer[count], k); count += k; // sort the buffer by time-stamps sortEventBuffer(mSensorEventBuffer, count); } } } // handle backward compatibility for RotationVector sensor if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) { for (int i = 0; i < count; i++) { if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) { // All the 4 components of the quaternion should be available // No heading accuracy. Set it to -1 mSensorEventBuffer[i].data[4] = -1; } } } // Cache the list of active connections, since we use it in multiple places below but won't // modify it here const std::vector<sp<SensorEventConnection>> activeConnections = connLock.getActiveConnections(); for (int i = 0; i < count; ++i) { // Map flush_complete_events in the buffer to SensorEventConnections which called flush // on the hardware sensor. mapFlushEventsToConnections[i] will be the // SensorEventConnection mapped to the corresponding flush_complete_event in // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise). mMapFlushEventsToConnections[i] = nullptr; if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) { const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor; SensorRecord* rec = mActiveSensors.valueFor(sensor_handle); if (rec != nullptr) { mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection(); rec->removeFirstPendingFlushConnection(); } } // handle dynamic sensor meta events, process registration and unregistration of dynamic // sensor based on content of event. if (mSensorEventBuffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) { if (mSensorEventBuffer[i].dynamic_sensor_meta.connected) { int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle; const sensor_t& dynamicSensor = *(mSensorEventBuffer[i].dynamic_sensor_meta.sensor); ALOGI("Dynamic sensor handle 0x%x connected, type %d, name %s", handle, dynamicSensor.type, dynamicSensor.name); if (mSensors.isNewHandle(handle)) { const auto& uuid = mSensorEventBuffer[i].dynamic_sensor_meta.uuid; sensor_t s = dynamicSensor; // make sure the dynamic sensor flag is set s.flags |= DYNAMIC_SENSOR_MASK; // force the handle to be consistent s.handle = handle; SensorInterface *si = new HardwareSensor(s, uuid); // This will release hold on dynamic sensor meta, so it should be called // after Sensor object is created. device.handleDynamicSensorConnection(handle, true /*connected*/); registerDynamicSensorLocked(si); } else { ALOGE("Handle %d has been used, cannot use again before reboot.", handle); } } else { int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle; ALOGI("Dynamic sensor handle 0x%x disconnected", handle); device.handleDynamicSensorConnection(handle, false /*connected*/); if (!unregisterDynamicSensorLocked(handle)) { ALOGE("Dynamic sensor release error."); } for (const sp<SensorEventConnection>& connection : activeConnections) { connection->removeSensor(handle); } } } } // 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; for (const sp<SensorEventConnection>& connection : activeConnections) { connection->sendEvents(mSensorEventBuffer, count, mSensorEventScratch, mMapFlushEventsToConnections); //② needsWakeLock |= connection->needsWakeLock(); // If the connection has one-shot sensors, it may be cleaned up after first trigger. // Early check for one-shot sensors. if (connection->hasOneShotSensors()) { cleanupAutoDisabledSensorLocked(connection, mSensorEventBuffer, count); } } if (mWakeLockAcquired && !needsWakeLock) { setWakeLockAcquiredLocked(false); } } while (!Thread::exitPending()); ALOGW("Exiting SensorService::threadLoop => aborting..."); abort(); return false; }
①通过poll往hal层取sensor数据, 若没有数据的时候就一直阻塞(该阻塞功能由HAL层实现),当有数据时该函数就会返回
②通过SensorEventConnection 将数据给到每个应用,每个应用都有自己的SensorEventConnection
frameworks/native/services/sensorservice/SensorEventConnection.cpp
SensorService::SensorEventConnection::sendEvents()来将数据进一步处理并 SensorEventQueue::write 发送,这边请注意有多个SensorEventConnection各属于不同应用
frameworks/native/libs/sensor/SensorManager.cpp
应用注册sensor监听时,SystemSensorManager.java创建一个java类SensorEventQueue,这里再去创建c++类SensorEventQueue,当sensor数据到来时,SensorEventQueue会通过回调应用实现的onSensorChanged()接口而将数据给到应用,
sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) { sp<SensorEventQueue> queue; Mutex::Autolock _l(mLock); while (assertStateLocked() == NO_ERROR) { sp<ISensorEventConnection> connection = mSensorServer->createSensorEventConnection(packageName, mode, mOpPackageName); if (connection == nullptr) { // SensorService just died or the app doesn't have required permissions. ALOGE("createEventQueue: connection is NULL."); return nullptr; } queue = new SensorEventQueue(connection); break; } return queue; }
1、SensorService请求创建connection,最后调用 SensorService::createSensorEventConnection()
2、SensorEventConnection传递给SensorEventQueue构造函数,创建SensorEventQueue
frameworks/native/libs/sensor/SensorEventQueue.cpp
SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection) : mSensorEventConnection(connection), mRecBuffer(nullptr), mAvailable(0), mConsumed(0), mNumAcksToSend(0) { mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT]; } ssize_t SensorEventQueue::write(const sp<BitTube>& tube, ASensorEvent const* events, size_t numEvents) { return BitTube::sendObjects(tube, events, numEvents); } ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) { if (mAvailable == 0) { ssize_t err = BitTube::recvObjects(mSensorChannel, mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT); if (err < 0) { return err; } mAvailable = static_cast<size_t>(err); mConsumed = 0; } size_t count = min(numEvents, mAvailable); memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent)); mAvailable -= count; mConsumed += count; return static_cast<ssize_t>(count); }
创建mRecBuffer,用来存从SensorEventConnection发送过来的数据,
SensorEventQueue::write()用来给SensorEventConnection发送数据,
SensorEventQueue::read()用来读取数据给应用
ssize_t BitTube::sendObjects(const sp<BitTube>& tube, void const* events, size_t count, size_t objSize) { const char* vaddr = reinterpret_cast<const char*>(events); ssize_t size = tube->write(vaddr, count*objSize); // should never happen because of SOCK_SEQPACKET LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)), "BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were sent!)", count, objSize, size); //ALOGE_IF(size<0, "error %d sending %d events", size, count); return size < 0 ? size : size / static_cast<ssize_t>(objSize); } ssize_t BitTube::write(void const* vaddr, size_t size) { ssize_t err, len; do { len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);//这边通过 socket 域套接字发出去 // cannot return less than size, since we're using SOCK_SEQPACKET err = len < 0 ? errno : 0; } while (err == EINTR); return err == 0 ? len : -err; }
通过 socket 域套接字发出去,JNI层 Receiver对象里的 BitTube 里边mReceiveFd接收
frameworks/native/services/sensorservice/SensorEventConnection.cpp
SensorEventConnection 是基于 Bittube 实现的。主要是是 Sensor 数据的传输通道,当 Client 开始监听某一个 Sensor 是,一个对应的 SensorEventConnection 将会被创建,Server 端在接收到 Sensor 数据后,通过写入到 SensorEventConnection 传递给 Client 端。通过socket进行通信。
一个应用拥有多少个SensorEventConnection,取决于应用创建多少个SensorEventListerner,
可能有的应用开发者注册多个sensor时,只创建一个SensorEventListerner,然后在onSensorChanged()里边做类型区分,
有的一个sensor一个SensorEventListerner,从性能的角度考虑建议一个应用创建一个SensorEventListerner就够了,毕竟每创建一个,就要新建立一个socket连接,多一个poll去等待数据。
SensorService::SensorEventConnection::SensorEventConnection(
const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
const String16& opPackageName, bool hasSensorAccess)
: mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(nullptr),
mCacheSize(0), mMaxCacheSize(0), mTimeOfLastEventDrop(0), mEventsDropped(0),
mPackageName(packageName), mOpPackageName(opPackageName), mDestroyed(false),
mHasSensorAccess(hasSensorAccess) {
mChannel = new BitTube(mService->mSocketBufferSize);
#if DEBUG_CONNECTIONS
mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
mTotalAcksNeeded = mTotalAcksReceived = 0;
#endif
}
frameworks/native/services/sensorservice/SensorDevice.cpp
该类负责管理和维护系统中的所有 Sensor,封装了 Sensor 的使能、配置、数据读取等功能。
SensorDevice::SensorDevice() : mHidlTransportErrors(20), mRestartWaiter(new HidlServiceRegistrationWaiter()), mEventQueueFlag(nullptr), mWakeLockQueueFlag(nullptr), mReconnecting(false) { if (!connectHidlService()) { return; } initializeSensorList(); mIsDirectReportSupported = (checkReturnAndGetStatus(mSensors->unregisterDirectChannel(-1)) != INVALID_OPERATION); } void SensorDevice::initializeSensorList() { float minPowerMa = 0.001; // 1 microAmp checkReturn(mSensors->getSensorsList( [&](const auto &list) { const size_t count = list.size(); mActivationCount.setCapacity(count); Info model; for (size_t i=0 ; i < count; i++) { sensor_t sensor; convertToSensor(list[i], &sensor); // Sanity check and clamp power if it is 0 (or close) if (sensor.power < minPowerMa) { ALOGI("Reported power %f not deemed sane, clamping to %f", sensor.power, minPowerMa); sensor.power = minPowerMa; } mSensorList.push_back(sensor); mActivationCount.add(list[i].sensorHandle, model); checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* enabled */)); } })); }
SensorDevice继承了Singleton类,设计成单例,用getinstance()的方式调用
SensorDevice是实际上与HAL层直接进行交互的类,通过hidl与
sensor在HAL层的服务建立连接(这边所指的HAL层只是指google实现的那部分,
即: android.hardware.sensors@1.0-service,这一层通过dlopen(),会调用第三方如芯片厂商,
手机厂商,开发者等实现的SO库,实际上这些都应该统称为HAL层)。
关键性的成员 :
sp<V2_0::ISensors> sensors = V2_0::ISensors::getService();
sp<V1_0::ISensors> sensors = V1_0::ISensors::getService();
bool SensorDevice::connectHidlService() { HalConnectionStatus status = connectHidlServiceV2_0(); if (status == HalConnectionStatus::DOES_NOT_EXIST) { status = connectHidlServiceV1_0(); } return (status == HalConnectionStatus::CONNECTED); } SensorDevice::HalConnectionStatus SensorDevice::connectHidlServiceV1_0() { // SensorDevice will wait for HAL service to start if HAL is declared in device manifest. size_t retry = 10; HalConnectionStatus connectionStatus = HalConnectionStatus::UNKNOWN; while (retry-- > 0) { sp<V1_0::ISensors> sensors = V1_0::ISensors::getService(); if (sensors == nullptr) { // no sensor hidl service found connectionStatus = HalConnectionStatus::DOES_NOT_EXIST; break; } mSensors = new SensorServiceUtil::SensorsWrapperV1_0(sensors); mRestartWaiter->reset(); // Poke ISensor service. If it has lingering connection from previous generation of // system server, it will kill itself. There is no intention to handle the poll result, // which will be done since the size is 0. if(mSensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) { // ok to continue connectionStatus = HalConnectionStatus::CONNECTED; break; } // hidl service is restarting, pointer is invalid. mSensors = nullptr; connectionStatus = HalConnectionStatus::FAILED_TO_CONNECT; ALOGI("%s unsuccessful, remaining retry %zu.", __FUNCTION__, retry); mRestartWaiter->wait(); } return connectionStatus; } SensorDevice::HalConnectionStatus SensorDevice::connectHidlServiceV2_0() { HalConnectionStatus connectionStatus = HalConnectionStatus::UNKNOWN; sp<V2_0::ISensors> sensors = V2_0::ISensors::getService(); if (sensors == nullptr) { connectionStatus = HalConnectionStatus::DOES_NOT_EXIST; } else { mSensors = new SensorServiceUtil::SensorsWrapperV2_0(sensors); mEventQueue = std::make_unique<EventMessageQueue>( SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT, true /* configureEventFlagWord */); mWakeLockQueue = std::make_unique<WakeLockQueue>( SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT, true /* configureEventFlagWord */); hardware::EventFlag::deleteEventFlag(&mEventQueueFlag); hardware::EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag); hardware::EventFlag::deleteEventFlag(&mWakeLockQueueFlag); hardware::EventFlag::createEventFlag(mWakeLockQueue->getEventFlagWord(), &mWakeLockQueueFlag); CHECK(mSensors != nullptr && mEventQueue != nullptr && mWakeLockQueue != nullptr && mEventQueueFlag != nullptr && mWakeLockQueueFlag != nullptr); status_t status = checkReturnAndGetStatus(mSensors->initialize( *mEventQueue->getDesc(), *mWakeLockQueue->getDesc(), new SensorsCallback())); if (status != NO_ERROR) { connectionStatus = HalConnectionStatus::FAILED_TO_CONNECT; ALOGE("Failed to initialize Sensors HAL (%s)", strerror(-status)); } else { connectionStatus = HalConnectionStatus::CONNECTED; mSensorsHalDeathReceiver = new SensorsHalDeathReceivier(); sensors->linkToDeath(mSensorsHalDeathReceiver, 0 /* cookie */); } } return connectionStatus; }
传感器 HAL 2.0
传感器硬件抽象层 (HAL) 是 Android 传感器框架与设备传感器(如加速度计或陀螺仪)之间的接口。传感器 HAL 定义了一系列函数,要使传感器框架能够控制传感器,必须先实现这些函数。传感器 HAL 2.0 适用于搭载 Android 10 及更高版本的新设备和升级设备。传感器 HAL 2.0 基于传感器 HAL 1.0 构建,但与 1.0 版有几个关键的区别,这使得它无法向后兼容。传感器 HAL 2.0 使用快速消息队列 (FMQ) 将传感器事件从 HAL 发送到 Android 传感器框架。
传感器 HAL 1.0
sensors.h 中声明的传感器 HAL 接口表示 Android 框架与硬件专用软件之间的接口。HAL 实现必须定义 sensors.h 中声明的每个函数。
主要函数如下:
- get_sensors_list - 返回所有传感器的列表。
- activate - 启动或停止传感器。
- batch - 设置传感器的参数,如采样率和最大报告延迟。
- setDelay - 仅用于 1.0 版本的 HAL。设置指定传感器的采样率。
- flush - 清空指定传感器的 FIFO 并在完成后报告清空完成事件。
- poll - 返回可用的传感器事件。
实现必须是线程安全的,并且允许从不同线程调用这些函数。
该接口还定义了这些函数使用的几个类型。主要类型如下:
- sensors_module_t
- sensors_poll_device_t
- sensor_t
- sensors_event_t
sensors.h: hardware/libhardware/include/hardware/sensors.h
sensors.cpp: hardware/libhardware/modules/sensors/dynamic_sensor/sensors.cpp
Sensors Hardware Abstraction Layer (HAL) API 是硬件驱动程序和 Android 框架之间的接口。它包含一个 HAL 接口 sensors.h 和一个我们称之为 sensors.cpp 的 HAL 实现。
接口由 Android 和 AOSP 贡献者定义,并由设备制造商提供实现。
传感器 HAL 接口位于 hardware/libhardware/include/hardware 中。有关详情,请参阅 sensors.h。
HAL 实现通过设置 your_poll_device.common.version 指定实现的 HAL 接口版本。现有的 HAL 接口版本在 sensors.h 中有所定义,相应功能与这些版本绑定在一起。
Android 框架目前支持版本 1.0 和 1.3,不过版本 1.0 很快将不再受支持。本文档介绍了版本 1.3(所有设备均应升级到该版本)的行为。要详细了解如何升级到版本 1.3,请参阅 HAL 版本弃用。
传感器驱动程序可与物理设备进行交互。在某些情况下,HAL 实现和驱动程序是同一软件实体。在其他情况下,硬件集成者会要求传感器芯片制造商提供相应驱动程序,但是它们是用于编写 HAL 实现的驱动程序。
在所有情况下,HAL 实现和内核驱动程序都由硬件制造商负责提供,Android 不提供首选编写方式。
设备的传感器堆栈可视需要添加传感器中枢。在 SoC 可以处于暂停模式时,传感器中枢对执行一些低功耗的低级计算任务非常有用。例如,计步功能或传感器融合功能可以在这些芯片上执行。此外,它也是实施传感器批处理以及为传感器事件添加硬件 FIFO 的理想位置。有关详情,请参阅批处理。
传感器中枢的具体化方式取决于架构。它有时是一个单独的芯片,有时包含在与 SoC 相同的芯片上。传感器中枢的重要特征是,应该包含足够的内存来进行批处理,并消耗极少的电量以便能实现低功耗 Android 传感器。部分传感器中枢包含一个微控制器(用于通用计算)和硬件加速器(用于针对低电耗传感器实现极低功耗计算)。
传感器中枢的架构方式以及与传感器和 SoC(I2C 总线、SPI 总线等)的通信方式并非由 Android 指定,但应该以最大程度减少整体功耗为目标。
有一种方案似乎会对实现的简单性产生重大影响,即从传感器中枢到 SoC 设置两个中断行:一个用于唤醒中断(适用于唤醒传感器),另一个用于非唤醒中断(适用于非唤醒传感器)。
传感器是进行测量操作的物理 MEM 芯片。在很多情况下,同一个芯片上会有多个物理传感器。例如,一些芯片中包含加速度计、陀螺仪和磁力计(此类芯片通常称为 9 轴芯片,因为每个传感器基于 3 个轴提供数据)。
此外,其中的部分芯片还包含用于执行常见计算任务(例如运动状态检测、步数检测以及 9 轴传感器融合)的逻辑。
尽管 CDD 功率和精确度的要求与建议针对的是 Android 传感器而非物理传感器,但这些要求会影响物理传感器的选择。例如,游戏旋转矢量传感器的精确度要求会影响物理陀螺仪的精确度要求。设备制造商负责推算物理传感器的相关要求。
https://blog.csdn.net/goodnight1994/article/details/80259375
https://blog.csdn.net/goodnight1994/article/details/97503586
https://blog.csdn.net/huilin9960/article/details/80654647
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。