android中Sensor 工作流程

来源:互联网 发布:美的集团社会关系网络 编辑:程序博客网 时间:2024/05/16 08:49

转自http://www.apkbus.com/forum.php?mod=viewthread&tid=2740

JAVA 程序
我们使用 sensor 接口一般只要注册一下 SensorListener 像下面这样
ApiDemo:
 
  1. mGraphView = new GraphView(this);
  2.      mSensorManager.registerListener(mGraphView,....);
复制代码

这里的 listener 是因为 sensor 状态变化要产生变化的控件
然后在控件里重载 on

SensorChanged 和 onAccuracyChanged 方法

  1. public void onSensorChanged(int sensor, float[] values)
  2. public void onAccuracyChanged(int sensor, int accuracy)
复制代码


SensorManager
Sensor 主体代码和流程在 frameworks/base/core/java/android/hardware/SensorManager.java 里面
1.registerListener 其实是调用 registerLegacyListener:

  1. public boolean registerListener(SensorListener listener, int sensors, int rate) {
  2. ...
  3. result = registerLegacyListener(...);
  4. ...
  5. }
复制代码



2. registerLegacyListener 其实就是构造一个 LegacyListener 对象并将其加入 HashMap 中去

  1. private boolean registerLegacyListener(int legacyType, int type,
  2.                  SensorListener listener, int sensors, int rate)
  3. {
  4. ...
  5.      legacyListener = new LegacyListener(listener);
  6.      mLegacyListenersMap.put(listener, legacyListener); //private HashMap<SensorListener,
  7. LegacyListener> mLegacyListenersMap
  8. ...
  9. }
复制代码



3. LegacyListener 做了 2 件事 一个是调用我们重载的那 2 个接口 还有一个就是将 sensor 的
数据刷到我们的设备显示界面上去

  1. private class LegacyListener implements SensorEventListener {
  2. ...
  3. LegacyListener(SensorListener target) {
  4.                  mTarget = target;
  5.                  mSensors = 0;
  6. }
  7. public void onSensorChanged(SensorEvent event) {
  8. ...
  9. mapSensorDataToWindow();
  10. mTarget.onSensorChanged(...);//private SensorListener mTarget;
  11. ...
  12. }
  13. public void onAccuracyChanged(Sensor sensor, int accuracy) {
  14. ...
  15. }
  16. }
复制代码



代码最后是一些 native 方法:
   

  1. private static native void nativeClassInit();//SensorManager 构造函数里调用
  2.      private static native int sensors_module_init();//SensorManager 构造函数里调用
  3.      private static native int sensors_module_get_next_sensor(Sensor sensor, int
  4. next);//SensorManager 构造函数里调用
  5.       // Used within this module from outside SensorManager, don't make private
  6.       static native int sensors_data_init();//SensorThread 构造里调用
  7.       static native int sensors_data_uninit();//SensorThread 析构里调用
  8.       static native int sensors_data_open(FileDescriptor fd); //SensorThread 的 run()循环调用
  9.       static native int sensors_data_close();//SensorThread 的 run()循环调用
  10.       static native int sensors_data_poll(float[] values, int[] status, long[] timestamp);//SensorThread
  11. 的 run()循环调用
复制代码



SensorManager 与 IsensorService 的关系
SensorManager 调用 IsensorService 其实只是调用了 service 的方法来控制 thread 是 Lock

  1. void startLocked(ISensorService service) {
  2. ...
  3.      ParcelFileDescriptor fd = service.getDataChanel();
  4. ...
  5. }
复制代码


或者打开
mSensorService.enableSensor(l, name, handle, delay);
IsensorService 的实例是这么获得的

  1. mSensorService = ISensorService.Stub.asInterface(
  2.                        ServiceManager.getService(Context.SENSOR_SERVICE));
复制代码



IsensorService 是通过 aidl 定义的

  1. interface ISensorService
  2. {
  3.        ParcelFileDescriptor getDataChanel();
  4.        boolean enableSensor(IBinder listener, String name, int sensor, int enable);
  5. }
  6. SensorService
  7. frameworks/base/services/java/com/android/server/SensorService.java
  8. class SensorService extends ISensorService.Stub {
  9. ...
  10. }
复制代码



service 最终被 manager 调到走的是 android 的标准流程我们不 care,我们想知道的其实就是
enableSensor 的实现
首先,得有电

  1. if (enable == SENSOR_DISABLE) {
  2.                   mBatteryStats.noteStopSensor(uid, sensor);
  3.              } else {
  4.                   mBatteryStats.noteStartSensor(uid, sensor);
  5. }
复制代码



看是不是能打开 sensor

  1. if (enable!=SENSOR_DISABLE && !_sensors_control_activate(sensor, true)) {
  2.                        Log.w(TAG, "could not enable sensor " + sensor);
  3.                        return false;
  4.                   }
复制代码



如果 sensor 打开了 我们要监听状态还要对外面报告状态变化

  1. if (l == null && enable!=SENSOR_DISABLE) {
  2.                        l = new Listener(binder);
  3.                        binder.linkToDeath(l, 0);
  4.                        mListeners.add(l);
  5.                        mListeners.notify();
  6.                   }
复制代码



如果 sensor 被关闭了 我们要取消监听并且告诉外面关闭了传感
  

  1. if (enable != SENSOR_DISABLE) {
  2.                        l.addSensor(sensor, enable);
  3.                   } else {
  4.                        l.removeSensor(sensor);
  5.                        deactivateIfUnused(sensor);
  6.                        if (l.mSensors == 0) {
  7.                              mListeners.remove(l);
  8.                              binder.unlinkToDeath(l, 0);
  9.                              mListeners.notify();
  10.                        }
  11.                   }
复制代码



另外还有一些唤醒和设置延迟的动作

  1. if (mListeners.size() == 0) {
  2.                        _sensors_control_wake();
  3.                   }
  4.    if (minDelay >= 0) {
  5.                        _sensors_control_set_delay(minDelay);
  6.                   }
复制代码



从上面可以看出来 对于底层而言只要知道上层怎么调用传感的接口就好 所以最关心的还是
我标绿的 native 方法 上层的传感流程其实比较简单 就是标准的 service 管理和 notify 流程
  

  1.   private static native int _sensors_control_init();
  2.        private static native ParcelFileDescriptor _sensors_control_open();
  3.        private static native boolean _sensors_control_activate(int sensor, boolean activate);
  4.        private static native int _sensors_control_set_delay(int ms);
  5.        private static native int _sensors_control_wake();
复制代码



native 方法
1. manager 部分
frameworks/base/core/jni/android_hardware_SensorManager.cpp
先看一眼它的方法注册

  1. static JNINativeMethod gMethods[] = {
  2.        {"nativeClassInit", "()V",          (void*)nativeClassInit },
  3.        {"sensors_module_init","()I",          (void*)sensors_module_init },
  4.        {"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",
  5.                                                            (void*)sensors_module_get_next_sensor },
  6.        {"sensors_data_init", "()I",         (void*)sensors_data_init },
  7.        {"sensors_data_uninit", "()I",        (void*)sensors_data_uninit },
  8.        {"sensors_data_open", "(Ljava/io/FileDescriptor;)I", (void*)sensors_data_open },
  9.        {"sensors_data_close", "()I",         (void*)sensors_data_close },
  10.        {"sensors_data_poll", "([F[I[J)I", (void*)sensors_data_poll },
  11. };
复制代码



小贴一个例子作为代表

  1. static jint
  2. sensors_data_open(JNIEnv *env, jclass clazz, jobject fdo)
  3. {
  4.        jclass FileDescriptor = env->FindClass("java/io/FileDescriptor");
  5.        jfieldID offset = env->GetFieldID(FileDescriptor, "descriptor", "I");
  6.        int fd = env->GetIntField(fdo, offset);
  7.        return sSensorDevice->data_open(sSensorDevice, fd); // doesn't take ownership of fd
  8. }
复制代码



调用到最后其实都是用的 sSensorDevice 的方法

  1. /*
  2.    * The method below are not thread-safe and not intended to be
  3.    */
  4. static sensors_data_device_t* sSensorDevice = 0;
复制代码



2.service 部分
frameworks/base/services/jni/com_android_server_SensorService.cpp
先看一眼它的方法注册

  1. static JNINativeMethod gMethods[] = {
  2.        {"_sensors_control_init", "()I", (void*) android_init },
  3.        {"_sensors_control_open", "()Landroid/os/ParcelFileDescriptor;", (void*) android_open },
  4.        {"_sensors_control_activate", "(IZ)Z", (void*) android_activate },
  5.       {"_sensors_control_wake", "()I", (void*) android_data_wake },
  6.       {"_sensors_control_set_delay","(I)I", (void*) android_set_delay },
  7. };
复制代码



然后上面的那些方法我就不一一贴了 给出一个例子 其实这么实现的

  1. static jboolean
  2. android_activate(JNIEnv *env, jclass clazz, jint sensor, jboolean activate)
  3. {
  4.       int active = sSensorDevice->activate(sSensorDevice, sensor, activate);
  5.       return (active<0) ? false : true;
  6. }
复制代码



所以最后调用的其实都是 sSensorDevice 的方法 其他的几个也是这样 sSensorDevice 是这个
(不是线程安全的)

  1. /*
  2. * The method below are not thread-safe and not intended to be
  3. */
  4. static sensors_control_device_t* sSensorDevice = 0;
复制代码



3.继续追 终于到了硬件层了 最后一切的方法其实就在这里了
hardware/libhardware/include/hardware/sensor.h

  1. struct sensors_control_device_t {
  2.       struct hw_device_t common;
  3.       /**
  4.         * Returns the fd which will be the parameter to
  5.         * sensors_data_device_t:pen_data().
  6.         * The caller takes ownership of this fd. This is intended to be
  7.         * passed cross processes.
  8.         *
  9.         * @return a fd if successful, < 0 on error
  10.         */
  11.       int (*open_data_source)(struct sensors_control_device_t *dev);
  12.       /** Activate/deactivate one sensor.
  13.         *
  14.         * @param handle is the handle of the sensor to change.
  15.         * @param enabled set to 1 to enable, or 0 to disable the sensor.
  16.         *
  17.         * @return 0 on success, negative errno code otherwise
  18.         */
  19.       int (*activate)(struct sensors_control_device_t *dev,
  20.                  int handle, int enabled);
  21.       /**
  22.        * Set the delay between sensor events in ms
  23.        *
  24.        * @return 0 if successful, < 0 on error
  25.        */
  26.      int (*set_delay)(struct sensors_control_device_t *dev, int32_t ms);
  27.      /**
  28.        * Causes sensors_data_device_t.poll() to return -EWOULDBLOCK immediately.
  29.        */
  30.      int (*wake)(struct sensors_control_device_t *dev);
  31. };
  32. struct sensors_data_device_t {
  33.      struct hw_device_t common;
  34.      /**
  35.        * Prepare to read sensor data.
  36.        *
  37.        * This routine does NOT take ownership of the fd
  38.        * and must not close it. Typically this routine would
  39.        * use a duplicate of the fd parameter.
  40.        *
  41.        * @param fd from sensors_control_open.
  42.        *
  43.        * @return 0 if successful, < 0 on error
  44.        */
  45.      int (*data_open)(struct sensors_data_device_t *dev, int fd);
  46.      /**
  47.        * Caller has completed using the sensor data.
  48.        * The caller will not be blocked in sensors_data_poll
  49.        * when this routine is called.
  50.        *
  51.        * @return 0 if successful, < 0 on error
  52.        */
  53.      int (*data_close)(struct sensors_data_device_t *dev);
  54.      /**
  55.        * Return sensor data for one of the enabled sensors.
  56.        *
  57.        * @return sensor handle for the returned data, 0x7FFFFFFF when
  58.        * sensors_control_device_t.wake() is called and -errno on error
  59.        *
  60.         */
  61.       int (*poll)(struct sensors_data_device_t *dev,
  62.                  sensors_data_t* data);
  63. };
复制代码



最后一组函数

  1. /** convenience API for opening and closing a device */
  2. static inline int sensors_control_open(const struct hw_module_t* module,
  3.             struct sensors_control_device_t** device) {
  4.       return module->methods->open(module,
  5.                  SENSORS_HARDWARE_CONTROL, (struct hw_device_t**)device);
  6. }
  7. static inline int sensors_control_close(struct sensors_control_device_t* device) {
  8.       return device->common.close(&device->common);
  9. }
  10. static inline int sensors_data_open(const struct hw_module_t* module,
  11.             struct sensors_data_device_t** device) {
  12.       return module->methods->open(module,
  13.                  SENSORS_HARDWARE_DATA, (struct hw_device_t**)device);
  14. }
  15. static inline int sensors_data_close(struct sensors_data_device_t* device) {
  16.       return device->common.close(&device->common);
  17. }
复制代码