Sensor注册流程

本文详细介绍了在高通855平台中,Android sensor的注册流程,从APP进程创建SensorEventQueue,到system_server进程接收并转发数据,再到android.hardware.sensors@1.0-service进程与子系统通信。注册过程中涉及REPORTING_MODE类型的设置,以及SensorEventQueue的建立和事件回调机制。同时提供了调试关键点和调用栈分析。
摘要由CSDN通过智能技术生成

一.概要

       我们在android中经常会注册sensor然后监听sensor的数据来做一些特殊的功能,但是之前一直没有关注过整个注册的流程,本文将会告诉你高通855平台中sensor的整个完整的注册流程是什么样子的,先大概总结一下:

APP进程创建一个SensorEventQueue,等待接收system_server发送过来的数据
system_server进程会保存app端的SensorEventQueue,有一个线程会循环的读取android.hardware.sensors@1.0-service进程发送过来的消息,当有消息来到时会往APP端的SensorEventQueue中发送sensor 数据,
android.hardware.sensors@1.0-service进程会初始化一个socket和子系统通信,并且创建一个线程一直等待BP发送上来的数据,当接收到数据时会发给system_server。
注册流程图参考绿色部分

二.APP进程注册:

sensorEventListener = new MySensorEventListener();

//获取方向传感器

Sensor orientationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);// NO.1 获取sensor

sensorManager.registerListener(sensorEventListener, orientationSensor, SensorManager.SENSOR_DELAY_NORMAL); // NO.2注册sensor

 

private final class MySensorEventListener implements SensorEventListener

{

    //可以得到传感器实时测量出来的变化值

    @Override

    public void onSensorChanged(SensorEvent event)

    {

        //得到方向的值

        if(event.sensor.getType()==Sensor.TYPE_ORIENTATION)

        {

            float x = event.values[SensorManager.DATA_X];

            float y = event.values[SensorManager.DATA_Y];

            float z = event.values[SensorManager.DATA_Z];

            orientationView.setText("Orientation: " + x + ", " + y + ", " + z);

        }

    }

    //重写变化

    @Override

    public void onAccuracyChanged(Sensor sensor, int accuracy)

    {

    }

}

首先我们先写一个SensorEventListener,之后sensor有数据之后会回调onSensorChanged/onAccuracyChanged,先不管怎么回调的,先看看注册过程
NO.1获取对应type的sensor

public Sensor getDefaultSensor(int type) {

    // TODO: need to be smarter, for now, just return the 1st sensor

    // NO.1.1 这里是从所有的sensor中获得对应type的sensor.

    List l = getSensorList(type);

    boolean wakeUpSensor = false;

    // For the following sensor types, return a wake-up sensor. These types are by default

    // defined as wake-up sensors. For the rest of the SDK defined sensor types return a

    // non_wake-up version.

    if (type == Sensor.TYPE_PROXIMITY || type == Sensor.TYPE_SIGNIFICANT_MOTION ||

            type == Sensor.TYPE_TILT_DETECTOR || type == Sensor.TYPE_WAKE_GESTURE ||

            type == Sensor.TYPE_GLANCE_GESTURE || type == Sensor.TYPE_PICK_UP_GESTURE ||

            type == Sensor.TYPE_WRIST_TILT_GESTURE || type == Sensor.TYPE_DYNAMIC_SENSOR_META) {

        wakeUpSensor = true;

    }

     

    // NO.1.2 一般sensor有一个wakeup sensor,一个non wakeup sensor

    for (Sensor sensor : l) {

        if (sensor.isWakeUpSensor() == wakeUpSensor) return sensor;

    }

    return null;

}

NO.1.1 这里是从所有的sensor中获得对应type的sensor.

public List getSensorList(int type) {

    // cache the returned lists the first time

    List list;

    // 获取所有sensor

    final List fullList = getFullSensorList();

    synchronized (mSensorListByType) {

        // 看看缓存里有没有要组成的sensor,如果有的话直接返回

        list = mSensorListByType.get(type);

        if (list == null) {

            if (type == Sensor.TYPE_ALL) {

                list = fullList;

            else {

                list = new ArrayList();

                // 遍历所有sensor,找到对应type的sensor

                for (Sensor i : fullList) {

                    if (i.getType() == type)

                        list.add(i);

                }

            }

            list = Collections.unmodifiableList(list);

            // 存入缓存

            mSensorListByType.append(type, list);

        }

    }

    return list;

}

 

// NO.1.2 一般sensor有一个wakeup sensor,一个non wakeup sensor,我们返回wakeup sensor。
若是注册Non-Wakeup的sensor的话,在系统suspend时,不会有任何数据上报.若是注册Wakeup的sensor的话,系统会被wakelock住,根本睡不下去,这时系统功耗非常高
 

NO.2注册sensor

   public boolean registerListener(SensorEventListener listener, Sensor sensor,

           int samplingPeriodUs) {

       return registerListener(listener, sensor, samplingPeriodUs, null);

   }

    

   public boolean registerListener(SensorEventListener listener, Sensor sensor,

           int samplingPeriodUs, Handler handler) {

       // SensorManager.SENSOR_DELAY_NORMAL默认采样率 200000us

       int delay = getDelay(samplingPeriodUs);

       return registerListenerImpl(listener, sensor, delay, handler, 00);

   }

@Override

   protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,

           int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {

       android.util.SeempLog.record_sensor_rate(381, sensor, delayUs);

       if (listener == null || sensor == null) {

           Log.e(TAG, "sensor or listener is null");

           return false;

       }

       // Trigger Sensors should use the requestTriggerSensor call.

       // NO2.1如果sensor类型是Sensor.REPORTING_MODE_ONE_SHOT就返回,requestTriggerSensor注册的sensor

       if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {

           Log.e(TAG, "Trigger Sensors should use the requestTriggerSensor.");

           return false;

       }

       // Sensor.REPORTING_MODE_ONE_SHOT ,判断时间

       if (maxBatchReportLatencyUs < 0 || delayUs < 0) {

           Log.e(TAG, "maxBatchReportLatencyUs and delayUs should be non-negative");

           return false;

       }

       // 判断Listener数量是否超过超过MAX_LISTENER_COUNT

       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) {

           // 从缓存里获取listener

           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();

               // NO2.2 新建一个SensorEventQueue

               queue = new SensorEventQueue(listener, looper, this, fullClassName);

               // NO2.3 添加sennsor

               if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {

                   queue.dispose();

                   return false;

               }

               // 将listener放入缓存

               mSensorListeners.put(listener, queue);

               return true;

           else {

               return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);

           }

       }

   }


sensor的模式类型有:
REPORTING_MODE_CONTINUOUS 常用的都是CONTINUOUS类型,例如light,acc,gryo等等
REPORTING_MODE_ON_CHANGE 
REPORTING_MODE_ONE_SHOT 例如:计步
REPORTING_MODE_SPECIAL_TRIGGER

 

NO2.2 新建一个SensorEventQueue

frameworks/base/core/java/android/hardware/SystemSensorManager.java

static final class SensorEventQueue extends BaseEventQueue {

        private final SensorEventListener mListener;

        private final SparseArray mSensorsEvents = new SparseArray();

 

        public SensorEventQueue(SensorEventListener listener, Looper looper,

                SystemSensorManager manager, String packageName) {

            // NO2.2.1调用父类方法

            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);

            }

        }

        ......

        // Called from native code.

        @SuppressWarnings("unused")

        @Override

        // NO2.2.2数据分发,调用onAccuracyChanged,onSensorChanged

        protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,

                long timestamp) {

            final Sensor sensor = mManage

  • 8
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值