当前位置: 代码迷 >> Android >> 深入显出 - Android系统移植与平台开发(十三) - Sensor HAL框架分析之三
  详细解决方案

深入显出 - Android系统移植与平台开发(十三) - Sensor HAL框架分析之三

热度:686   发布时间:2016-05-01 13:03:31.0
深入浅出 - Android系统移植与平台开发(十三) - Sensor HAL框架分析之三


让我们来看看SensorManager的代码

SensorManager框架层代码

@frameworks/base/core/java/android/hardware/SensorManager.java

public SensorManager(Looper mainLooper) {

       mMainLooper = mainLooper;    // 上面说了,这是Activity的Looper

 

       synchronized(sListeners) {

            if(!sSensorModuleInitialized) {

               sSensorModuleInitialized = true;

                nativeClassInit();        // 好像是调用本地方法初始化

 

               sWindowManager = IWindowManager.Stub.asInterface(

                       ServiceManager.getService("window"));  // 获得Windows服务,不管它

               if (sWindowManager != null) {

                   // if it's null we're running in the system process

                   // which won't get the rotated values

                   try {

                       sRotation = sWindowManager.watchRotation(

                                newIRotationWatcher.Stub() {

                                    public voidonRotationChanged(int rotation) {

                                       SensorManager.this.onRotationChanged(rotation);

                                    }

                                }

                        );

                   } catch (RemoteException e) {

                   }

                }

 

               // initialize the sensor list

                sensors_module_init();         // 初始化sensor module

               final ArrayList<Sensor> fullList = sFullSensorsList;  // SensorManager维护的Sensor列表

               int i = 0;

               do {

                   Sensor sensor = new Sensor(); // 创建sensor对象,这个是传递给App的哦

                                       //调用module的方法,获得每一个sensor设备

                   i = sensors_module_get_next_sensor(sensor, i); 

                                      

                   if (i>=0) {

                       //Log.d(TAG, "found sensor: " + sensor.getName() +

                       //        ", handle=" +sensor.getHandle());

                       sensor.setLegacyType(getLegacySensorType(sensor.getType()));

                       fullList.add(sensor); // 添加到SM维护的Sensor列表(嘿嘿)

                       sHandleToSensor.append(sensor.getHandle(), sensor);

                   }

                }while (i>0);

 

                sPool= new SensorEventPool( sFullSensorsList.size()*2 );

               sSensorThread = new SensorThread(); // 哟,创建线程了好像

            }

        }

    }

很明显nativeClassInit(),sensors_module_init(),sensors_module_get_next_sensor()都是本地实现的方法。

private static native void nativeClassInit();

private static native int sensors_module_init();

private static native intsensors_module_get_next_sensor(Sensor sensor, int next);

根据之前看代码的经验可知,很可能在frameworks/base/core/对应一个jni目录下的存在其对应的本地代码:

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

frameworks/base/core/jni/android_hardware_SensorManager.cpp

果不其然,在jni存在其本地代码,让我们来看下nativeClassInit函数:

@frameworks/base/core/jni/android_hardware_SensorManager.cpp

static void

nativeClassInit (JNIEnv *_env, jclass _this)

{

    jclasssensorClass = _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");

}

其代码比较简单,将Java框架层的Sensor类中的成员保存在本地代码中的gSensorOffsets 结构体中将来使用。

         sensors_module_init()本地方法的实现:

static jint

sensors_module_init(JNIEnv *env, jclass clazz)

{

   SensorManager::getInstance();

    return 0;

}

         在本地代码中调用了SensorManager的getInstance方法,这又是一个典型的单例模式获得类的对象,注意这儿的SensorManager是本地的类,而不是Java层的SensorManager类。

本地SensorManager的定义

@frameworks/base/include/gui/SensorManager.h

class SensorManager :

    publicASensorManager,

    publicSingleton<SensorManager>

{

public:

   SensorManager();

   ~SensorManager();

 

    ssize_tgetSensorList(Sensor const* const** list) const;

    Sensor const*getDefaultSensor(int type);

   sp<SensorEventQueue> createEventQueue();

 

private:

    //DeathRecipient interface

    voidsensorManagerDied();

 

    status_tassertStateLocked() const;

 

private:

    mutable MutexmLock;

    mutablesp<ISensorServer> mSensorServer;

    mutableSensor const** mSensorList;

    mutableVector<Sensor> mSensors;

    mutablesp<IBinder::DeathRecipient> mDeathObserver;

};

注意SensorManager又继承了ASensorManager和泛型类Singleton<SensorManager>,而SensorManager类定义里没有getInstance所以其定义肯定是在ASensorManager或Singleton中。

@frameworks/base/include/utils/Singleton.h

template <typename TYPE>

class ANDROID_API Singleton

{

public:

    staticTYPE& getInstance() {

       Mutex::Autolock _l(sLock);

        TYPE*instance = sInstance;

        if(instance == 0) {

           instance = new TYPE();

           sInstance = instance;

        }

        return*instance;

    }

 

    static boolhasInstance() {

       Mutex::Autolock _l(sLock);

        returnsInstance != 0;

    }

   

protected:

    ~Singleton(){ };

    Singleton() {};

 

private:

   Singleton(const Singleton&);

   Singleton& operator = (const Singleton&);

    static MutexsLock;

    static TYPE*sInstance;

};

//---------------------------------------

}; // namespace android

第一次调用getInstance方法时,创建泛型对象即:SensorManager,随后再调用该方法时返回第一次创建的泛型对象。

1)    本地SensorManager的创建

本地SensorManager是一个单例模式,其构造方法相对比较简单,它的主要工作交给了assertStateLocked方法:

@frameworks/base/libs/gui/SensorManager.cpp

SensorManager::SensorManager()     

    :mSensorList(0)

{

    // okay we'renot locked here, but it's not needed during construction

   assertStateLocked();

}

 

status_t SensorManager::assertStateLocked() const {

    if(mSensorServer == NULL) {

        // tryfor one second

        constString16 name("sensorservice");

        for (inti=0 ; i<4 ; i++) {

            status_t err = getService(name,&mSensorServer);

            if(err == NAME_NOT_FOUND) {

               usleep(250000);

               continue;

            }

            if(err != NO_ERROR) {

               return err;

            }

            break;

        }

 

        classDeathObserver : public IBinder::DeathRecipient {

           SensorManager& mSensorManger;

           virtual void binderDied(const wp<IBinder>& who) {

               LOGW("sensorservice died [%p]", who.unsafe_get());

               mSensorManger.sensorManagerDied();

            }

        public:

           DeathObserver(SensorManager& mgr) : mSensorManger(mgr) { }

        };

 

       mDeathObserver = new DeathObserver(*const_cast<SensorManager*>(this));

        mSensorServer->asBinder()->linkToDeath(mDeathObserver);

 

        mSensors= mSensorServer->getSensorList();

        size_tcount = mSensors.size();

       mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*));

        for(size_t i=0 ; i<count ; i++) {

           mSensorList[i] = mSensors.array() + i;

        }

    }

 

    returnNO_ERROR;

}

在assertStateLocked方法里,先通过getService获得SensorService对象,然后注册了对SensorService的死亡监听器,SensorManager与SensorService不求同年同月同日,只求同年同月同日死。拜完了兄弟之后,调用getSensorList得到所有传感器的对象,存放到mSensorList中,保存在本地空间里。

2)    本地SensorManager中列表的获取

在上面函数调用中首先调用getService来获得SensorService服务,然后执行mSensorServer->getSensorList来获得服务提供的传感器列表:

Vector<Sensor> SensorService::getSensorList()

{

    returnmUserSensorList;

}

大家要注意啊,上面的getSensorList函数只是返回了mUserSensorList,而这个变量是在什么时候初始化的呢?

根据2.1节可知,SensorService在本地被初始化时,构造函数里并没有对mUserSensorList进行初始化,而SensorService里有一个onFirstRef方法,这个方法当SensorService第一次被强引用时被自动调用。那SensorService第一次被强引用是在什么时候呢?

在SensorManager::assertStateLocked方法里调用getService获得SensorService保存到mSensorServer成员变量中。

mSensorServer的定义在frameworks/base/include/gui/SensorManager.h中:

class SensorManager :

    publicASensorManager,

    publicSingleton<SensorManager>

{

 mutable sp<ISensorServer>mSensorServer;

 mutable Sensorconst** mSensorList;

 mutableVector<Sensor> mSensors;

};

可以看出mSensroServer为强引用类型。所以在创建本地中的SensorManager类对象时,自动强引用SensorService,自动调用onFirstRef方法:

@frameworks/base/services/sensorservice/SensorService.cpp的onFirstRef简化方法如下:

void SensorService::onFirstRef()

{  

   LOGD("nuSensorService starting...");

   SensorDevice& dev(SensorDevice::getInstance());                //创建SensorDevice对象dev

   

    if(dev.initCheck() == NO_ERROR) {

        sensor_tconst* list;

        ssize_tcount = dev.getSensorList(&list);                          //获得传感器设备列表

        if (count> 0) {

            …

            for(ssize_t i=0 ; i<count ; i++) {

                registerSensor( new HardwareSensor(list[i]) );  // 注册在本地获得的传感器

                           …

                      }

            constSensorFusion& fusion(SensorFusion::getInstance());

                     

            if(hasGyro) {            // 如果有陀螺仪设备,则先注册和陀螺仪有关的虚拟传感器设备

                registerVirtualSensor( newRotationVectorSensor() );     // 虚拟旋转传感器

               registerVirtualSensor( new GravitySensor(list, count) ); // 虚拟重力传感器

               registerVirtualSensor( new LinearAccelerationSensor(list, count) ); // 虚拟加速器

 

                // these are optional

               registerVirtualSensor( new OrientationSensor() ); // 虚拟方向传感器

               registerVirtualSensor( new CorrectedGyroSensor(list, count) );        // 真正陀螺仪

 

               // virtual debugging sensors...

                char value[PROPERTY_VALUE_MAX];

               property_get("debug.sensors", value, "0");

               if (atoi(value)) {

                   registerVirtualSensor( new GyroDriftSensor() );      // 虚拟陀螺测漂传感器

                }

            }

                   

            // build the sensor list returned tousers

            mUserSensorList = mSensorList;

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

                }

            }

 

            run("SensorService",PRIORITY_URGENT_DISPLAY);

           mInitCheck = NO_ERROR;

        }

    }

}

上面代码首先通过SensorDevice::getInstance()创建对象dev,调用dev.getSensorList(&list)获得传感器列表,将取出的sensor_t类型list传感器列表,塑造了HardwareSensor对象,传递给了registerSensor方法,通过registerSensor注册传感器,然后通过单例模型创建了SensorFusion对象,创建并注册了一系列的虚拟传感器,疑惑,极大的疑惑,怎么传感器还有虚拟的??其实你注意看这几个传感器最前面的条件,if(hasGyro),表示如果存在陀螺仪的话,会创建这些虚拟设备,再看这些虚拟设备:旋转,重力,加速器,方向等,这些设备都对应一个物理硬件:陀螺仪,所以这些逻辑上存在,物理上不存在的设备叫虚拟设备。在初始化了虚拟设备后,将mSensorList传感器列表赋值给mUserSensorList,mSensorList是由registerSensor初始化的,mUserSensorList是要提交给Java框架层的传感器列表,最后通过run方法运行了SensorService线程,我们先来看下registerSensor的代码:

void SensorService::registerSensor(SensorInterface* s)

{

   sensors_event_t event;

    memset(&event,0, sizeof(event));

 

    const Sensorsensor(s->getSensor());

    // add to thesensor list (returned to clients)

    mSensorList.add(sensor);

    // add to ourhandle->SensorInterface mapping

   mSensorMap.add(sensor.getHandle(), s);

    // create anentry in the mLastEventSeen array

   mLastEventSeen.add(sensor.getHandle(), event);

}

通过分析上面代码可知,将传入的HardwareSensor对象塑造了Sensor,添加到mSensorList向量表里,然后将HardwareSensor对象添加到mSensroMap键值对里,将新建的传感器事件数据封装对象event添加到mLastEventSeen键值对中。

我们通过下面的时序图来看下Sensor列表的获取过程。


1)    SensorService监听线程及传感器事件的捕获

让我们再来看看SensorService线程,还记得前面SensorService的父类中有一个Thread类,当调用run方法时会创建线程并调用threadLoop方法。

bool SensorService::threadLoop()

{

   LOGD("nuSensorService thread starting...");

 

    const size_tnumEventMax = 16 * (1 + mVirtualSensorList.size());

   sensors_event_t buffer[numEventMax];

   sensors_event_t scratch[numEventMax];

   SensorDevice& device(SensorDevice::getInstance());

    const size_tvcount = mVirtualSensorList.size();

 

    ssize_tcount;

    do {

             // 调用SensorDevice的poll方法看样子要多路监听了

        count = device.poll(buffer,numEventMax);    

        if(count<0) {

           LOGE("sensor poll failed (%s)", strerror(-count));

           break;

        }

              // 记录poll返回的每一个传感器中的最后一个数据信息到mLastEventSeen中

        recordLastValue(buffer, count);

 

        // handlevirtual sensors 处理虚拟传感器数据

        if (count&& vcount) {

           sensors_event_t const * const event = buffer;

                      // 获得虚拟传感器列表

            constDefaultKeyedVector<int, SensorInterface*> virtualSensors(

                   getActiveVirtualSensors());

            constsize_t activeVirtualSensorCount = virtualSensors.size();  // 虚拟传感器个数

            if(activeVirtualSensorCount) {

               size_t k = 0;

               SensorFusion& fusion(SensorFusion::getInstance());

               if (fusion.isEnabled()) {

                   for (size_t i=0 ; i<size_t(count) ; i++) {

                       fusion.process(event[i]);              //处理虚拟传感器设备事件

                    }

                }

               for (size_t i=0 ; i<size_t(count) ; i++) {

                   for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {

                       sensors_event_t out;

                       if (virtualSensors.valueAt(j)->process(&out, event[i])) {

                            buffer[count + k] =out;

                            k++;

                       }

                   }

                }

               if (k) {

                   // record the last synthesized values

                   recordLastValue(&buffer[count], k);

                   count += k;

                   // sort the buffer by time-stamps

                   sortEventBuffer(buffer, count);

                }

            }

        }

 

        // sendour events to clients...

             // 获得传感器连接对象列表

        constSortedVector< wp<SensorEventConnection> > activeConnections(

               getActiveConnections());

        size_tnumConnections = activeConnections.size();

        for(size_t i=0 ; i<numConnections ; i++) {

           sp<SensorEventConnection> connection(

                   activeConnections[i].promote());

            if(connection != 0) {

                               // 向指定的传感器连接客户端发送传感器数据信息

                connection->sendEvents(buffer, count, scratch);

            }

        }

    } while (count>= 0 || Thread::exitPending());   // 传感器循环监听线程

 

   LOGW("Exiting SensorService::threadLoop => aborting...");

    abort();

    return false;

}

我们看到device.poll方法,阻塞在了SensorDevice的poll方法上,它肯定就是读取Sensor硬件上的数据了,将传感器数据保存在buff中,然后调用recordLastValue方法,只保存同一类型传感器的最新数据(最后采集的一组数据)到键值对象mLastEventSeen里对应传感器的值域中。如果传感器设备是虚拟设备则调用SensorFusion.Process()方法对虚拟设备数据进行处理。SensorFusion关联一个SensorDevice,它是虚拟传感器设备的一个加工类,负责虚拟传感器数据的计算、处理、设备激活、设置延迟、获得功耗信息等操作。

让我们来回顾下整个过程吧。


1. SensorManager对象创建并调用assertStateLocked方法

2. 在assertStateLocked方法中调用getService,获得SensorService服务

3. 当SensorService第一次强引用时,自动调用OnFirstRef方法

4.获得SensorDevice单例对象

6. 调用SensorDevice.getSensorList方法sensor_t列表保存在SensorService中

8. 调用registerSensor注册传感器,添加到mSensorList列表中

9. 启动SensorService线程,准备监听所有注册的传感器设备

12. 多路监听注册的传感器设备,当有传感器事件时,返回sensor_event_t封装的事件信息

16. 记录产生传感器事件的设备信息

17. 调用getActiveConnections获得所有的活动的客户端SensorEventConnection类对象

19.向客户端发送传感器事件信息



5楼gdt_A20昨天 09:44
真棒~
4楼gdt_A20昨天 18:36
^.^~
3楼a3248235昨天 14:06
很好 很 强大
2楼lushengchu_qq_com前天 18:33
不明但觉厉害
1楼philofly前天 18:33
挺好,正准备研究这玩意。
  相关解决方案