购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

5.1 Android传感器系统概述

知识点讲解:光盘:视频\知识点\第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函数。

  • int(*open_data_source)(struct sensors_control_device_t *dev)
  • int(*activate)(struct sensors_control_device_t *dev,int handle,int enabled)
  • int(*set_delay)(struct sensors_control_device_t *dev,int32_t ms)
  • int(*wake)(struct sensors_control_device_t *dev)
  • int(*data_open)(struct sensors_data_device_t *dev,int fd)
  • int(*data_close)(struct sensors_data_device_t *dev)
  • int(*poll)(struct sensors_data_device_t *dev,sensors_data_t* data)
  • int(*get_sensors_list)(struct sensors_module_t* module,struct sensor_t const** list)

在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传感器系统中各个层次的架构知识。

5.1.1 传感器系统的层详解

在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层利用观察者模式对传感器的数据进行了监听处理。

5.1.2 Frameworks层详解

在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的具体说明

5.1.3 JNI层详解

在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数据流的处理流程

5.1.4 HAL层详解

在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 服务器端的调用时序图 cLQ0lrGhbJHlpDLUUiiKf54zBD479oXZOO7dqHCjp4Fc62wDXhWLFJNy7wPAiVhj

点击中间区域
呼出菜单
上一章
目录
下一章
×