



知识点讲解:光盘:视频\知识点\第5章\Android传感器系统概述.avi
在Android系统中提供的主要传感器有:加速度传感器、磁场、方向、陀螺仪、光线、压力、温度和接近等。传感器系统会主动对上层报告传感器精度和数据的变化,并且提供了设置传感器精度的接口,这些接口可以在Java应用和Java框架中使用。
Android传感器系统的基本层次结构如图5-1所示。
图5-1 传感器系统的层次结构
根据图5-1所示的结构,Android传感器系统从上到下分别是:Java应用层、Java框架对传感器的应用、传感器类、传感器硬件抽象层、传感器驱动。图5-1中各个层的具体说明如下。
(1)传感器系统的Java部分
其代码路径是:
frameworks/base/include/core/java/android/hardware
此部分对应的实现文件是Sensor*.java。
(2)传感器系统的JNI部分
其代码路径是:
frameworks/base/core/jni/android_hardware_SensorManager.cpp
在此部分中提供了对类android.hardware.Sensor.Manage的本地支持。
(3)传感器系统HAL层
头文件路径是:
hardware/libhardware/include/hardware/sensors.h
在Android系统中,传感器系统的硬件抽象层需要特意编码实现。
(4)驱动层
驱动层的代码路径是:
kernel/driver/hwmon/$(PROJECT)/sensor
在库sensor.so中提供了如下8个API函数。
在Android系统的Java层中,Sensor的状态是由SensorService来负责控制的,其Java代码和JNI代码分别位于如下文件中。
frameworks/base/services/java/com/android/server/SensorService.java frameworks/base/services/jni/com_android_server_SensorService.cpp
SensorManager负责在Java层Sensor的数据控制,它的Java代码和JNI代码分别位于如下文件中。
frameworks/base/core/java/android/hardware/SensorManager.java frameworks/base/core/jni/android_hardware_SensorManager.cpp
在Android的Framework中,通过文件sensorService.java和sensorManager.java实现与Sensor传感器通信。文件sensorService.java的通信功能是通过JNI调用sensorService.cpp中的方法实现的。
文件sensorManager.java的具体通信功能是通过JNI调用sensorManager.cpp中的方法实现的。文件sensorService.cpp和sensorManager.cpp通过文件hardware.c与sensor.so通信。其中文件sensorService.cpp实现对sensor的状态控制,文件sensorManger.cpp实现对sensor的数据控制。库sensor.so通过ioctl控制sensor driver的状态,通过打开Sensor Driver(传感器驱动)对应的设备文件读取G-sensor采集的数据。
在本节的内容中,将简要讲解Android传感器系统中各个层次的架构知识。
在Android系统中,传感器系统的Java部分的实现文件是:
\sdk\apps\SdkController\src\com\android\tools\sdkcontroller\activities\SensorActivity.java
通过阅读文件SensorActivity.java的源码可知,在应用程序中使用传感器需要用到hardware包中的SensorManager、SensorListener等相关的类,具体实现代码如下所示。
public class SensorActivity extends BaseBindingActivity
implements android.os.Handler.Callback {
@SuppressWarnings("hiding")
public static String TAG = SensorActivity.class.getSimpleName();
private static boolean DEBUG = true;
private static final int MSG_UPDATE_ACTUAL_HZ = 0x31415;
private TableLayout mTableLayout;
private TextView mTextError;
private TextView mTextStatus;
private TextView mTextTargetHz;
private TextView mTextActualHz;
private SensorChannel mSensorHandler;
private final Map<MonitoredSensor, DisplayInfo> mDisplayedSensors =
new HashMap<SensorChannel.MonitoredSensor, SensorActivity.DisplayInfo>();
private final android.os.Handler mUiHandler = new android.os.Handler(this);
private int mTargetSampleRate;
private long mLastActualUpdateMs;
/** 第一次创建activity时调用 */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sensors);
mTableLayout = (TableLayout) findViewById(R.id.tableLayout);
mTextError = (TextView) findViewById(R.id.textError);
mTextStatus = (TextView) findViewById(R.id.textStatus);
mTextTargetHz = (TextView) findViewById(R.id.textSampleRate);
mTextActualHz = (TextView) findViewById(R.id.textActualRate);
updateStatus("Waiting for connection");
mTextTargetHz.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
updateSampleRate();
return false;
}
});
mTextTargetHz.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
updateSampleRate();
}
});
}
@Override
protected void onResume() {
if (DEBUG) Log.d(TAG, "onResume");
// BaseBindingActivity绑定后套服务
super.onResume();
updateError();
}
@Override
protected void onPause() {
if (DEBUG) Log.d(TAG, "onPause");
super.onPause();
}
@Override
protected void onDestroy() {
if (DEBUG) Log.d(TAG, "onDestroy");
super.onDestroy();
removeSensorUi();
}
//创建传感器UI
private void createSensorUi() {
final LayoutInflater inflater = getLayoutInflater();
if (!mDisplayedSensors.isEmpty()) {
removeSensorUi();
}
mSensorHandler = (SensorChannel) getServiceBinder().getChannel(Channel.SENSOR_CHANNEL);
if (mSensorHandler != null) {
mSensorHandler.addUiHandler(mUiHandler);
mUiHandler.sendEmptyMessage(MSG_UPDATE_ACTUAL_HZ);
assert mDisplayedSensors.isEmpty();
List<MonitoredSensor> sensors = mSensorHandler.getSensors();
for (MonitoredSensor sensor : sensors) {
final TableRow row = (TableRow) inflater.inflate(R.layout.sensor_row,
mTableLayout,
false);
mTableLayout.addView(row);
mDisplayedSensors.put(sensor, new DisplayInfo(sensor, row));
}
}
}
//删除传感器UI
private void removeSensorUi() {
if (mSensorHandler != null) {
mSensorHandler.removeUiHandler(mUiHandler);
mSensorHandler = null;
}
mTableLayout.removeAllViews();
for (DisplayInfo info : mDisplayedSensors.values()) {
info.release();
}
mDisplayedSensors.clear();
}
private class DisplayInfo implements CompoundButton.OnCheckedChangeListener {
private MonitoredSensor mSensor;
private CheckBox mChk;
private TextView mVal;
public DisplayInfo(MonitoredSensor sensor, TableRow row) {
mSensor = sensor;
// Initialize displayed checkbox for this sensor, and register
// checked state listener for it
mChk = (CheckBox) row.findViewById(R.id.row_checkbox);
mChk.setText(sensor.getUiName());
mChk.setEnabled(sensor.isEnabledByEmulator());
mChk.setChecked(sensor.isEnabledByUser());
mChk.setOnCheckedChangeListener(this);
//初始化显示该传感器的文本框
mVal = (TextView) row.findViewById(R.id.row_textview);
mVal.setText(sensor.getValue());
}
/**
*为相关的复选框选中状态进行变化的处理。当复选框被选中时会注册传感器变化
*如果不加以控制会取消传感器的变化
*/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (mSensor != null) {
mSensor.onCheckedChanged(isChecked);
}
}
public void release() {
mChk = null;
mVal = null;
mSensor = null;
}
public void updateState() {
if (mChk != null && mSensor != null) {
mChk.setEnabled(mSensor.isEnabledByEmulator());
mChk.setChecked(mSensor.isEnabledByUser());
}
}
public void updateValue() {
if (mVal != null && mSensor != null) {
mVal.setText(mSensor.getValue());
}
}
}
/**实现回调处理程序*/
@Override
public boolean handleMessage(Message msg) {
DisplayInfo info = null;
switch (msg.what) {
case SensorChannel.SENSOR_STATE_CHANGED:
info = mDisplayedSensors.get(msg.obj);
if (info != null) {
info.updateState();
}
break;
case SensorChannel.SENSOR_DISPLAY_MODIFIED:
info = mDisplayedSensors.get(msg.obj);
if (info != null) {
info.updateValue();
}
if (mSensorHandler != null) {
updateStatus(Integer.toString(mSensorHandler.getMsgSentCount()) + " events sent");
//如果值已经修改则更新 "actual rate"
long ms = mSensorHandler.getActualUpdateMs();
if (ms != mLastActualUpdateMs) {
mLastActualUpdateMs = ms;
String hz = mLastActualUpdateMs <= 0 ? "--" :
Integer.toString((int) Math.ceil(1000. / ms));
mTextActualHz.setText(hz);
}
}
break;
case MSG_UPDATE_ACTUAL_HZ:
if (mSensorHandler != null) {
//如果值已经修改则更新 "actual rate"
long ms = mSensorHandler.getActualUpdateMs();
if (ms != mLastActualUpdateMs) {
mLastActualUpdateMs = ms;
String hz = mLastActualUpdateMs <= 0 ? "--" :
Integer.toString((int) Math.ceil(1000. / ms));
mTextActualHz.setText(hz);
}
mUiHandler.sendEmptyMessageDelayed(MSG_UPDATE_ACTUAL_HZ, 1000 /*1s*/);
}
}
return true; // we consumed this message
}
private void updateSampleRate() {
String str = mTextTargetHz.getText().toString();
try {
int hz = Integer.parseInt(str.trim());
//上限值50,模拟器的最大值是50赫兹
if (hz <= 0 || hz > 50) {
hz = 50;
}
if (hz != mTargetSampleRate) {
mTargetSampleRate = hz;
if (mSensorHandler != null) {
mSensorHandler.setUpdateTargetMs(hz <= 0 ? 0 : (int)(1000.0f / hz));
}
}
} catch (Exception ignore) { }
}
}
通过上述代码可知,整个Java层利用观察者模式对传感器的数据进行了监听处理。
在Android系统中,Frameworks层是Android系统提供的应用程序开发接口和应用程序框架,与应用程序的调用是通过类实例化或类继承进行的。对应用程序来说,最重要的就是把SensorListener注册到SensorManager上,从而才能以观察者身份接收到数据的变化,因此,我们把目光落在SensorManager的构造函数、RegisterListener函数和通知机制相关的代码上。在Android传感器系统中,Frameworks层的代码路径是frameworks/base/include/core/java/android/hardware。在本节的内容中,将详细讲解传感器系统的Frameworks层的具体实现流程。
1.监听传感器的变化
在Android传感器系统的Frameworks层中,文件SensorListener.java用于监听从Java应用层中传递过来的变化。文件SensorListener.java比较简单,具体代码如下所示。
package android.hardware;
@Deprecated
public interface SensorListener {
public void onSensorChanged(int sensor, float[] values);
public void onAccuracyChanged(int sensor, int accuracy);
}
2.注册监听
当文件SensorListener.java监听到变化之后,会通过文件SensorManager.java向服务注册监听变化,并调度Sensor的具体任务。例如在开发Android传感器应用程序时,在上层的通用开发流程如下。
(1)通过“getSystemService(SENSOR_SERVICE);”语句得到传感器服务。这样得到一个用来管理分配调度处理Sensor工作的SensorManager。SensorManager并不服务运行于后台,真正属于Sensor的系统服务是SensorService,在终端下的#service list中可以看到sensorservice:[android.gui.SensorServer]。
(2)通过“getDefaultSensor(Sensor.TYPE_GRAVITY);”得到传感器类型,当然还有各种千奇百怪的传感器,具体可以查阅Android官网的API或者源码中的文件Sensor.java。
(3)注册监听器SensorEventListener。在应用程序中打开一个监听接口,专门用于处理传感器的数据。
(4)通过回调函数onSensorChanged和onAccuracyChanged实现实时监听。例如对重力感应器的xyz值经算法变换得到左右上下前后方向等,就由这个回调函数实现。
综上所述,传感器顶层的处理流程如图5-2所示。
图5-2 传感器顶层的处理流程
文件SensorManager.java的具体实现流程如下。
(1)定义类SensorManager,然后设置各种传感器的初始变量值,具体代码如下所示。
public abstract class SensorManager {
protected static final String TAG = "SensorManager";
private static final float[ ] mTempMatrix = new float[16];
// Cached lists of sensors by type. Guarded by mSensorListByType
private final SparseArray<List<Sensor>> mSensorListByType =
new SparseArray<List<Sensor>>();
// Legacy sensor manager implementation. Guarded by mSensorListByType during initialization
private LegacySensorManager mLegacySensorManager;
@Deprecated
public static final int SENSOR_ORIENTATION = 1 << 0;
@Deprecated
public static final int SENSOR_ACCELEROMETER = 1 << 1;
@Deprecated
public static final int SENSOR_TEMPERATURE = 1 << 2;
@Deprecated
public static final int SENSOR_MAGNETIC_FIELD = 1 << 3;
@Deprecated
public static final int SENSOR_LIGHT = 1 << 4;
@Deprecated
public static final int SENSOR_PROXIMITY = 1 << 5;
@Deprecated
public static final int SENSOR_TRICORDER = 1 << 6;
@Deprecated
public static final int SENSOR_ORIENTATION_RAW = 1 << 7;
@Deprecated
public static final int SENSOR_ALL = 0x7F;
@Deprecated
public static final int SENSOR_MIN = SENSOR_ORIENTATION;
@Deprecated
public static final int SENSOR_MAX = ((SENSOR_ALL + 1)>>1);
@Deprecated
public static final int DATA_X = 0;
@Deprecated
public static final int DATA_Y = 1;
@Deprecated
public static final int DATA_Z = 2;
@Deprecated
public static final int RAW_DATA_INDEX = 3;
@Deprecated
public static final int RAW_DATA_X = 3;
@Deprecated
public static final int RAW_DATA_Y = 4;
@Deprecated
public static final int RAW_DATA_Z = 5;
public static final float STANDARD_GRAVITY = 9.80665f;
public static final float GRAVITY_SUN = 275.0f;
public static final float GRAVITY_MERCURY = 3.70f;
public static final float GRAVITY_VENUS = 8.87f;
public static final float GRAVITY_EARTH = 9.80665f;
public static final float GRAVITY_MOON = 1.6f;
public static final float GRAVITY_MARS = 3.71f;
public static final float GRAVITY_JUPITER = 23.12f;
public static final float GRAVITY_SATURN = 8.96f;
public static final float GRAVITY_URANUS = 8.69f;
public static final float GRAVITY_NEPTUNE = 11.0f;
public static final float GRAVITY_PLUTO = 0.6f;
public static final float GRAVITY_DEATH_STAR_I = 0.000000353036145f;
public static final float GRAVITY_THE_ISLAND = 4.815162342f;
/**对地球表面的最大磁场*/
public static final float MAGNETIC_FIELD_EARTH_MAX = 60.0f;
/**对地球表面的最小磁场*/
public static final float MAGNETIC_FIELD_EARTH_MIN = 30.0f;
/** 标准大气压 */
public static final float PRESSURE_STANDARD_ATMOSPHERE = 1013.25f;
public static final float LIGHT_SUNLIGHT_MAX = 120000.0f;
public static final float LIGHT_SUNLIGHT = 110000.0f;
public static final float LIGHT_SHADE = 20000.0f;
public static final float LIGHT_OVERCAST = 10000.0f;
public static final float LIGHT_SUNRISE = 400.0f;
public static final float LIGHT_CLOUDY = 100.0f;
public static final float LIGHT_FULLMOON = 0.25f;
public static final float LIGHT_NO_MOON = 0.001f;
/**尽可能快地获得传感器数据*/
public static final int SENSOR_DELAY_FASTEST = 0;
/**适合游戏速度*/
public static final int SENSOR_DELAY_GAME = 1;
/**适合于用户接口速率*/
public static final int SENSOR_DELAY_UI = 2;
/**(默认值)适合屏幕方向的变化*/
public static final int SENSOR_DELAY_NORMAL = 3;
/**
*返回的值,该传感器是不可信的,需要进行校准或环境不允许读数
*/
public static final int SENSOR_STATUS_UNRELIABLE = 0;
/**
*该传感器是报告的低精度的数据,与环境的校准是必要的
*/
public static final int SENSOR_STATUS_ACCURACY_LOW = 1;
/**
*这种传感器是精确的平均频率的报告数据,与环境的校准可以提高精确度
*/
public static final int SENSOR_STATUS_ACCURACY_MEDIUM = 2;
/**该传感报告准确性最大的数据*/
public static final int SENSOR_STATUS_ACCURACY_HIGH = 3;
public static final int AXIS_X = 1;
public static final int AXIS_Y = 2;
public static final int AXIS_Z = 3;
public static final int AXIS_MINUS_X = AXIS_X | 0x80;
public static final int AXIS_MINUS_Y = AXIS_Y | 0x80;
public static final int AXIS_MINUS_Z = AXIS_Z | 0x80;
(2)定义各种设备类型和设备数据的方法,这些方法非常重要,在编写的应用程序中,可以通过AIDL接口远程调用(RPC)的方式得到SensorManager。这样通过在类SensorManager中的方法,可以得到底层的各种传感器数据。上述方法的具体实现代码如下所示。
public int getSensors() {
return getLegacySensorManager().getSensors();
}
public List<Sensor> getSensorList(int type) {
//第一次缓存返回列表
List<Sensor> list;
final List<Sensor> fullList = getFullSensorList();
synchronized (mSensorListByType) {
list = mSensorListByType.get(type);
if (list == null) {
if (type == Sensor.TYPE_ALL) {
list = fullList;
} else {
list = new ArrayList<Sensor>();
for (Sensor i : fullList) {
if (i.getType() == type)
list.add(i);
}
}
list = Collections.unmodifiableList(list);
mSensorListByType.append(type, list);
}
}
return list;
}
…
上述方法的功能非常重要,其实就是我们在开发传感器应用程序时用到的API接口。有关上述方法的具体说明,读者可以查阅官网SDK API中对于类android.hardware.SensorManager的具体说明,如图5-3所示。
图5-3 Android SDK API中对android.hardware.SensorManager的具体说明
在Android系统中,传感器系统的JNI部分的代码路径是:
frameworks/base/core/jni/android_hardware_SensorManager.cpp
在此文件中提供了对类android.hardware.Sensor.Manager的本地支持。上层和JNI层的调用关系如图5-4所示。
图5-4 上层和JNI层的调用关系
在图5-4所示的调用关系中涉及了如下的API接口方法。
1.实现本地函数
文件android_hardware_SensorManager.cpp的功能是实现文件SensorManager.java中的native(本地)函数,主要是通过调用文件SensorManager.cpp和文件SensorEventQueue.cpp中的相关类来完成相关的工作。文件android_hardware_SensorManager.cpp的具体实现代码如下所示。
static struct {
jclass clazz;
jmethodID dispatchSensorEvent;
} gBaseEventQueueClassInfo;
namespace android {
struct SensorOffsets
{
jfieldID name;
jfieldID vendor;
jfieldID version;
jfieldID handle;
jfieldID type;
jfieldID range;
jfieldID resolution;
jfieldID power;
jfieldID minDelay;
} gSensorOffsets;
/*
*下面的方法是非线程安全的和不打算用的
*/
static void
nativeClassInit (JNIEnv *_env, jclass _this)
{
jclass sensorClass = _env->FindClass("android/hardware/Sensor");
SensorOffsets& sensorOffsets = gSensorOffsets;
sensorOffsets.name = _env->GetFieldID(sensorClass, "mName", "Ljava/lang/String;");
sensorOffsets.vendor = _env->GetFieldID(sensorClass, "mVendor", "Ljava/lang/String;");
sensorOffsets.version = _env->GetFieldID(sensorClass, "mVersion", "I");
sensorOffsets.handle = _env->GetFieldID(sensorClass, "mHandle", "I");
sensorOffsets.type = _env->GetFieldID(sensorClass, "mType", "I");
sensorOffsets.range = _env->GetFieldID(sensorClass, "mMaxRange", "F");
sensorOffsets.resolution = _env->GetFieldID(sensorClass, "mResolution","F");
sensorOffsets.power = _env->GetFieldID(sensorClass, "mPower", "F");
sensorOffsets.minDelay = _env->GetFieldID(sensorClass, "mMinDelay", "I");
}
static jint
nativeGetNextSensor(JNIEnv *env, jclass clazz, jobject sensor, jint next)
{
SensorManager& mgr(SensorManager::getInstance());
Sensor const* const* sensorList;
size_t count = mgr.getSensorList(&sensorList);
if (size_t(next) >= count)
return -1;
Sensor const* const list = sensorList[next];
const SensorOffsets& sensorOffsets(gSensorOffsets);
jstring name = env->NewStringUTF(list->getName().string());
jstring vendor = env->NewStringUTF(list->getVendor().string());
env->SetObjectField(sensor, sensorOffsets.name, name);
env->SetObjectField(sensor, sensorOffsets.vendor, vendor);
env->SetIntField(sensor, sensorOffsets.version, list->getVersion());
env->SetIntField(sensor, sensorOffsets.handle, list->getHandle());
env->SetIntField(sensor, sensorOffsets.type, list->getType());
env->SetFloatField(sensor, sensorOffsets.range, list->getMaxValue());
env->SetFloatField(sensor, sensorOffsets.resolution, list->getResolution());
env->SetFloatField(sensor, sensorOffsets.power, list->getPowerUsage());
env->SetIntField(sensor, sensorOffsets.minDelay, list->getMinDelay());
next++;
return size_t(next) < count ? next : 0;
}
2.处理客户端数据
文件frameworks\native\libs\gui\SensorManager.cpp功能是提供了对传感器数据部分的操作,实现了sensor_data_XXX()格式的函数。另外在Native层的客户端,文件SensorManager.cpp还负责与服务端SensorService.cpp之间的通信工作。文件SensorManager.cpp的具体实现代码如下所示。
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
ANDROID_SINGLETON_STATIC_INSTANCE(SensorManager)
SensorManager::SensorManager()
: mSensorList(0)
{
// we're not locked here, but it's not needed during construction
assertStateLocked();
}
SensorManager::~SensorManager()
{
free(mSensorList);
}
void SensorManager::sensorManagerDied()
{
Mutex::Autolock _l(mLock);
mSensorServer.clear();
free(mSensorList);
mSensorList = NULL;
mSensors.clear();
}
3.处理服务端数据
文件frameworks\native\services\sensorservice\SensorService.cpp能够实现Sensor真正的后台服务,是服务端的数据处理中心。在Android的传感器系统中,SensorService作为一个轻量级的System Service,在SystemServer内运行,在system_init<system_init.cpp>中调用了SensorService::instantiate()。具体来说,SensorService的主要功能如下。
(1)通过SensorService::instantiate创建实例对象,并增加到ServiceManager中,然后创建并启动线程,并执行threadLoop。
(2)threadLoop从sensor驱动获取原始数据,然后通过SensorEventConnection把事件发送给客户端。
(3)BnSensorServer的成员函数负责让客户端获取sensor列表和创建SensorEventConnection。
文件SensorService.cpp的具体实现代码如下所示。
namespace android {
const char* SensorService::WAKE_LOCK_NAME = "SensorService";
SensorService::SensorService()
: mInitCheck(NO_INIT)
{
}
void SensorService::onFirstRef()
{
ALOGD("nuSensorService starting...");
SensorDevice& dev(SensorDevice::getInstance());
if (dev.initCheck() == NO_ERROR) {
sensor_t const* list;
ssize_t count = dev.getSensorList(&list);
if (count > 0) {
ssize_t orientationIndex = -1;
bool hasGyro = false;
uint32_t virtualSensorsNeeds =
(1<<SENSOR_TYPE_GRAVITY) |
(1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
(1<<SENSOR_TYPE_ROTATION_VECTOR);
mLastEventSeen.setCapacity(count);
for (ssize_t i=0 ; i<count ; i++) {
registerSensor( new HardwareSensor(list[i]) );
switch (list[i].type) {
case SENSOR_TYPE_ORIENTATION:
orientationIndex = i;
break;
case SENSOR_TYPE_GYROSCOPE:
hasGyro = true;
break;
case SENSOR_TYPE_GRAVITY:
case SENSOR_TYPE_LINEAR_ACCELERATION:
case SENSOR_TYPE_ROTATION_VECTOR:
virtualSensorsNeeds &= ~(1<<list[i].type);
break;
}
}
//它是安全的,在这里实例化SensorFusion对象
//如果要被实例化后,H/W传感器已注册
const SensorFusion& fusion(SensorFusion::getInstance());
if (hasGyro) {
//总是实例化Android的虚拟传感器。因为它们是实例化落后于HAL的传感器,它们不会干扰
应用程序,除非它们看起来特别像它们的名字
registerVirtualSensor( new RotationVectorSensor() );
registerVirtualSensor( new GravitySensor(list, count) );
registerVirtualSensor( new LinearAccelerationSensor(list, count) );
// 这是选项
registerVirtualSensor( new OrientationSensor() );
registerVirtualSensor( new CorrectedGyroSensor(list, count) );
}
// build the sensor list returned to users
mUserSensorList = mSensorList;
if (hasGyro) {
// virtual debugging sensors are not added to mUserSensorList
registerVirtualSensor( new GyroDriftSensor() );
}
if (hasGyro &&
(virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR))) {
// if we have the fancy sensor fusion, and it's not provided by the
// HAL, use our own (fused) orientation sensor by removing the
// HAL supplied one form the user list.
if (orientationIndex >= 0) {
mUserSensorList.removeItemsAt(orientationIndex);
}
}
//调试传感器列表
for (size_t i=0 ; i<mSensorList.size() ; i++) {
switch (mSensorList[i].getType()) {
case SENSOR_TYPE_GRAVITY:
case SENSOR_TYPE_LINEAR_ACCELERATION:
case SENSOR_TYPE_ROTATION_VECTOR:
if (strstr(mSensorList[i].getVendor().string(), "Google")) {
mUserSensorListDebug.add(mSensorList[i]);
}
break;
default:
mUserSensorListDebug.add(mSensorList[i]);
break;
}
}
run("SensorService", PRIORITY_URGENT_DISPLAY);
mInitCheck = NO_ERROR;
}
}
}
通过上述实现代码,可以了解SensorService服务的创建、启动过程,整个过程的C/S通信架构如图5-5所示。
图5-5 C/S通信架构图
在此需要注意,并没有在系统中使用BpSensorServer,即使从ISensorServer.cpp中把它删除也不会对Sensor的工作有任何影响。这是因为它的工作已经被文件SensorManager.cpp所取代,ServiceManager会直接获取上面文件System_init中添加的SensorService对象。
4.封装HAL层的代码
在Android系统中,通过文件frameworks\native\services\sensorservice\SensorDevice.cpp封装了HAL层的代码,此文件的主要功能如下:
文件SensorDevice.cpp的主要实现代码如下所示。
status_t SensorDevice::activate(void* ident, int handle, int enabled)
{
if (!mSensorDevice) return NO_INIT;
status_t err(NO_ERROR);
bool actuateHardware = false;
Info& info( mActivationCount.editValueFor(handle) );
ALOGD_IF(DEBUG_CONNECTIONS,
"SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",
ident, handle, enabled, info.rates.size());
if (enabled) {
Mutex::Autolock _l(mLock);
ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
info.rates.indexOfKey(ident));
if (info.rates.indexOfKey(ident) < 0) {
info.rates.add(ident, DEFAULT_EVENTS_PERIOD);
if (info.rates.size() == 1) {
actuateHardware = true;
}
} else {
//传感器已经激活此IDENT
}
} else {
Mutex::Autolock _l(mLock);
ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
info.rates.indexOfKey(ident));
ssize_t idx = info.rates.removeItem(ident);
if (idx >= 0) {
if (info.rates.size() == 0) {
actuateHardware = true;
}
} else {
//没有启用这个传感器的ident
}
}
if (actuateHardware) {
ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w");
err = mSensorDevice->activate(mSensorDevice, handle, enabled);
ALOGE_IF(err, "Error %s sensor %d (%s)",
enabled ? "activating" : "disabling",
handle, strerror(-err));
}
{ //范围为锁
Mutex::Autolock _l(mLock);
nsecs_t ns = info.selectDelay();
mSensorDevice->setDelay(mSensorDevice, handle, ns);
}
return err;
}
status_t SensorDevice::setDelay(void* ident, int handle, int64_t ns)
{
if (!mSensorDevice) return NO_INIT;
Mutex::Autolock _l(mLock);
Info& info( mActivationCount.editValueFor(handle) );
status_t err = info.setDelayForIdent(ident, ns);
if (err < 0) return err;
ns = info.selectDelay();
return mSensorDevice->setDelay(mSensorDevice, handle, ns);
}
int SensorDevice::getHalDeviceVersion() const {
if (!mSensorDevice) return -1;
return mSensorDevice->common.version;
}
// ---------------------------------------------------------------------------
status_t SensorDevice::Info::setDelayForIdent(void* ident, int64_t ns)
{
ssize_t index = rates.indexOfKey(ident);
if (index < 0) {
ALOGE("Info::setDelayForIdent(ident=%p, ns=%lld) failed (%s)",
ident, ns, strerror(-index));
return BAD_INDEX;
}
rates.editValueAt(index) = ns;
return NO_ERROR;
}
nsecs_t SensorDevice::Info::selectDelay()
{
nsecs_t ns = rates.valueAt(0);
for (size_t i=1 ; i<rates.size() ; i++) {
nsecs_t cur = rates.valueAt(i);
if (cur < ns) {
ns = cur;
}
}
delay = ns;
return ns;
}
// ---------------------------------------------------------------------------
}; // namespace android
这样SensorService会把任务交给SensorDevice,而SensorDevice会调用标准的抽象层接口。由此可见,Sensor架构的抽象层接口是最标准的一种,它很好地实现了抽象层与本地框架的分离。
5.处理消息队列
在Android传感器系统中,文件frameworks\native\libs\gui\SensorEventQueue.cpp的功能是处理消息。文件SensorEventQueue.cpp能够在创建其实例时传入SensorEventConnection实例,SensorEventConnection继承于ISensorEventConnection。SensorEventConnection其实是客户端调用SensorService的createSensorEventConnection()方法创建的,是客户端与服务端沟通的桥梁,通过这个桥梁可以完成如下功能:
文件frameworks\native\libs\gui\SensorEventQueue.cpp的具体实现代码如下所示。
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection)
: mSensorEventConnection(connection)
{
}
SensorEventQueue::~SensorEventQueue()
{
}
void SensorEventQueue::onFirstRef()
{
mSensorChannel = mSensorEventConnection->getSensorChannel();
}
int SensorEventQueue::getFd() const
{
return mSensorChannel->getFd();
}
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)
{
return BitTube::recvObjects(mSensorChannel, events, numEvents);
}
sp<Looper> SensorEventQueue::getLooper() const
{
Mutex::Autolock _l(mLock);
if (mLooper == 0) {
mLooper = new Looper(true);
mLooper->addFd(getFd(), getFd(), ALOOPER_EVENT_INPUT, NULL, NULL);
}
return mLooper;
}
status_t SensorEventQueue::waitForEvent() const
{
const int fd = getFd();
sp<Looper> looper(getLooper());
int events;
int32_t result;
do {
result = looper->pollOnce(-1, NULL, &events, NULL);
if (result == ALOOPER_POLL_ERROR) {
ALOGE("SensorEventQueue::waitForEvent error (errno=%d)", errno);
result = -EPIPE; // unknown error, so we make up one
break;
}
if (events & ALOOPER_EVENT_HANGUP) {
// the other-side has died
ALOGE("SensorEventQueue::waitForEvent error HANGUP");
result = -EPIPE; // unknown error, so we make up one
break;
}
} while (result != fd);
return (result == fd) ? status_t(NO_ERROR) : result;
}
status_t SensorEventQueue::wake() const
{
sp<Looper> looper(getLooper());
looper->wake();
return NO_ERROR;
}
status_t SensorEventQueue::enableSensor(Sensor const* sensor) const {
return mSensorEventConnection->enableDisable(sensor->getHandle(), true);
}
status_t SensorEventQueue::disableSensor(Sensor const* sensor) const {
return mSensorEventConnection->enableDisable(sensor->getHandle(), false);
}
status_t SensorEventQueue::enableSensor(int32_t handle, int32_t us) const {
status_t err = mSensorEventConnection->enableDisable(handle, true);
if (err == NO_ERROR) {
mSensorEventConnection->setEventRate(handle, us2ns(us));
}
return err;
}
status_t SensorEventQueue::disableSensor(int32_t handle) const {
return mSensorEventConnection->enableDisable(handle, false);
}
status_t SensorEventQueue::setEventRate(Sensor const* sensor, nsecs_t ns) const {
return mSensorEventConnection->setEventRate(sensor->getHandle(), ns);
}
// ----------------------------------------------------------------------------
}; // namespace android
由此可见,SensorManager负责控制流,通过C/S的Binder机制与SensorService实现通信。具体过程如图5-6所示。
图5-6 SensorManager控制流的处理流程
而SensorEventQueue负责数据流,功能是通过管道机制来读写底层的数据。具体过程如图5-7所示。
图5-7 SensorEventQueue数据流的处理流程
在Android系统中,HAL层提供了Android独立于具体硬件的抽象接口。其中HAL层的头文件路径是:
hardware/libhardware/include/hardware/sensors.h
而具体实现文件需要开发者个人编写,具体可以参考:
hardware\invensense\libsensors_iio\sensors_mpl.cpp
文件sensors.h的主要实现代码如下所示。
typedef struct {
union {
float v[3];
struct {
float x;
float y;
float z;
};
struct {
float azimuth;
float pitch;
float roll;
};
};
int8_t status;
uint8_t reserved[3];
} sensors_vec_t;
/**
*未校准陀螺仪和磁强计数据事件
*/
typedef struct {
union {
float uncalib[3];
struct {
float x_uncalib;
float y_uncalib;
float z_uncalib;
};
};
union {
float bias[3];
struct {
float x_bias;
float y_bias;
float z_bias;
};
};
} uncalibrated_event_t;
/**
*各种类型的传感器数据中的联合
*可以返回
*/
typedef struct sensors_event_t {
int32_t version;
int32_t sensor;
/* 传感器类型 */
int32_t type;
int32_t reserved0;
/* 事件微秒 */
int64_t timestamp;
union {
float data[16];
sensors_vec_t acceleration;
sensors_vec_t magnetic;
sensors_vec_t orientation;
sensors_vec_t gyro;
float temperature;
float distance;
float light;
float pressure;
float relative_humidity;
uint64_t step_counter;
uncalibrated_event_t uncalibrated_gyro;
uncalibrated_event_t uncalibrated_magnetic;
};
uint32_t reserved1[4];
} sensors_event_t;
struct sensor_t;
struct sensors_module_t {
struct hw_module_t common;
int (*get_sensors_list)(struct sensors_module_t* module,
struct sensor_t const** list);
};
struct sensor_t {
const char* name;
const char* vendor;
int version;
int handle;
int type;
float maxRange;
float resolution;
float power;
int32_t minDelay;
void* reserved[8];
};
struct sensors_poll_device_t {
struct hw_device_t common;
int (*activate)(struct sensors_poll_device_t *dev,
int handle, int enabled);
int (*setDelay)(struct sensors_poll_device_t *dev,
int handle, int64_t ns);
int (*poll)(struct sensors_poll_device_t *dev,
sensors_event_t* data, int count);
};
typedef struct sensors_poll_device_1 {
union {
struct sensors_poll_device_t v0;
struct {
struct hw_device_t common;
int (*activate)(struct sensors_poll_device_t *dev,
int handle, int enabled);
int (*setDelay)(struct sensors_poll_device_t *dev,
int handle, int64_t period_ns);
int (*poll)(struct sensors_poll_device_t *dev,
sensors_event_t* data, int count);
};
};
int (*batch)(struct sensors_poll_device_1* dev,
int handle, int flags, int64_t period_ns, int64_t timeout);
void (*reserved_procs[8])(void);
} sensors_poll_device_1_t;
/**用于打开和关闭的装置方便的API */
static inline int sensors_open(const struct hw_module_t* module,
struct sensors_poll_device_t** device) {
return module->methods->open(module,
SENSORS_HARDWARE_POLL, (struct hw_device_t**)device);
}
static inline int sensors_close(struct sensors_poll_device_t* device) {
return device->common.close(&device->common);
}
static inline int sensors_open_1(const struct hw_module_t* module,
sensors_poll_device_1_t** device) {
return module->methods->open(module,
SENSORS_HARDWARE_POLL, (struct hw_device_t**)device);
}
static inline int sensors_close_1(sensors_poll_device_1_t* device) {
return device->common.close(&device->common);
}
__END_DECLS
#endif // ANDROID_SENSORS_INTERFACE_H
而具体的实现文件是Linux Kernel层,也就是具体的硬件设备驱动程序,例如可以将其命名为sensors.c,然后编写如下定义struct sensors_poll_device_t的代码。
struct sensors_poll_device_t {
struct hw_device_t common;
//激活/停用一个传感器
int (*activate)(struct sensors_poll_device_t *dev,
int handle, int enabled);
//对于一个给定的传感器,设置在微秒传感器事件之间的延迟
int (*setDelay)(struct sensors_poll_device_t *dev,
int handle, int64_t ns);
//返回传感器数据的数组
int (*poll)(struct sensors_poll_device_t *dev,
sensors_event_t* data, int count);
};
也可以编写如下定义struct sensors_module_t的代码。
struct sensors_module_t {
struct hw_module_t common;
/**
*枚举所有可用的传感器。这份名单是在“名单”返回
*@传感器在列表中返回数
*/
int (*get_sensors_list)(struct sensors_module_t* module,
struct sensor_t const** list);
};
也可以编写如下定义struct sensor_t的代码。
struct sensor_t {
const char* name;
int version;
int handle;
int type;
float maxRange;
float resolution;
float power;
int32_t minDelay;
void* reserved[8];
};
也可以编写如下定义struct sensors_event_t的代码。
typedef struct {
union {
float v[3];
struct {
float x;
float y;
float z;
};
struct {
float azimuth;
float pitch;
float roll;
};
};
int8_t status;
uint8_t reserved[3];
} sensors_vec_t;
typedef struct sensors_event_t {
int32_t version;
int32_t sensor;
int32_t type;
int32_t reserved0;
int64_t timestamp;
union {
float data[16];
sensors_vec_t acceleration;
sensors_vec_t magnetic;
sensors_vec_t orientation;
sensors_vec_t gyro;
float temperature;
float distance;
float light;
float pressure;
float relative_humidity;
};
uint32_t reserved1[4];
} sensors_event_t;
也可以编写如下定义struct sensors_module_t的代码。
static const struct sensor_t sSensorList[] = {
{ "MMA8452Q 3-axis Accelerometer",
"Freescale Semiconductor",
1, SENSORS_HANDLE_BASE+ID_A,
SENSOR_TYPE_ACCELEROMETER, 4.0f*9.81f, (4.0f*9.81f)/256.0f, 0.2f, 0, { } },
{ "AK8975 3-axis Magnetic field sensor",
"Asahi Kasei",
1, SENSORS_HANDLE_BASE+ID_M,
SENSOR_TYPE_MAGNETIC_FIELD, 2000.0f, 1.0f/16.0f, 6.8f, 0, { } },
{ "AK8975 Orientation sensor",
"Asahi Kasei",
1, SENSORS_HANDLE_BASE+ID_O,
SENSOR_TYPE_ORIENTATION, 360.0f, 1.0f, 7.0f, 0, { } },
{ "ST 3-axis Gyroscope sensor",
"STMicroelectronics",
1, SENSORS_HANDLE_BASE+ID_GY,
SENSOR_TYPE_GYROSCOPE, RANGE_GYRO, CONVERT_GYRO, 6.1f, 1190, { } },
{ "AL3006Proximity sensor",
"Dyna Image Corporation",
1, SENSORS_HANDLE_BASE+ID_P,
SENSOR_TYPE_PROXIMITY,
PROXIMITY_THRESHOLD_CM, PROXIMITY_THRESHOLD_CM,
0.5f, 0, { } },
{ "AL3006 light sensor",
"Dyna Image Corporation",
1, SENSORS_HANDLE_BASE+ID_L,
SENSOR_TYPE_LIGHT, 10240.0f, 1.0f, 0.5f, 0, { } },
};
static int open_sensors(const struct hw_module_t* module, const char* name,
struct hw_device_t** device);
static int sensors__get_sensors_list(struct sensors_module_t* module,
struct sensor_t const** list)
{
*list = sSensorList;
return ARRAY_SIZE(sSensorList);
}
static struct hw_module_methods_t sensors_module_methods = {
.open = open_sensors
};
const struct sensors_module_t HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id = SENSORS_HARDWARE_MODULE_ID,
.name = "MMA8451Q & AK8973A & gyro Sensors Module",
.author = "The Android Project",
.methods = &sensors_module_methods,
},
.get_sensors_list = sensors__get_sensors_list
};
static int open_sensors(const struct hw_module_t* module, const char* name,
struct hw_device_t** device)
{
return init_nusensors(module, device); //待后面讲解
}
到此为止,整个Android系统中传感器模块的源码分析完毕。由此可见,整个传感器系统的总体调用关系如图5-8所示。
图5-8 传感器系统的总体调用关系
客户端读取数据时的调用时序如图5-9所示。
图5-9 客户端读取数据时的调用时序图
服务器端的调用时序如图5-10所示。
图5-10 服务器端的调用时序图