dwlinux_gs / 重力感应专题 / 深入浅出

0 0

   

深入浅出

2014-07-18  dwlinux_gs


让我们来看看SensorManager的代码

SensorManager框架层代码

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

  1. public SensorManager(Looper mainLooper) {  
  2.        mMainLooper = mainLooper;    // 上面说了,这是Activity的Looper  
  3.   
  4.        synchronized(sListeners) {  
  5.             if(!sSensorModuleInitialized) {  
  6.                 sSensorModuleInitialized = true;  
  7.                 nativeClassInit();        // 好像是调用本地方法初始化  
  8.                   sWindowManager = IWindowManager.Stub.asInterface(  
  9.                        ServiceManager.getService("window"));  // 获得Windows服务,不管它  
  10.                   if (sWindowManager != null) {  
  11.                    // if it's null we're running in the system process  
  12.                    // which won't get the rotated values  
  13.                    try {  
  14.                        sRotation = sWindowManager.watchRotation(  
  15.                                 newIRotationWatcher.Stub() {  
  16.                                     public voidonRotationChanged(int rotation) {  
  17.                                        SensorManager.this.onRotationChanged(rotation);  
  18.                                     }  
  19.                                 }  
  20.                         );  
  21.                    } catch (RemoteException e) {  
  22.                    }  
  23.                 }  
  24.   
  25.                // initialize the sensor list  
  26.                sensors_module_init();         // 初始化sensor module  
  27.                final ArrayList<Sensor> fullList = sFullSensorsList;  // SensorManager维护的Sensor列表  
  28.                  int i = 0;  
  29.                do {  
  30.                    Sensor sensor = new Sensor(); // 创建sensor对象,这个是传递给App的哦  
  31.                    //调用module的方法,获得每一个sensor设备  
  32.                    i = sensors_module_get_next_sensor(sensor, i);   
  33.                 if (i>=0) {  
  34.                        //Log.d(TAG, "found sensor: " + sensor.getName() +  
  35.                        //        ", handle=" +sensor.getHandle());  
  36.                        sensor.setLegacyType(getLegacySensorType(sensor.getType()));  
  37.                        fullList.add(sensor); // 添加到SM维护的Sensor列表(嘿嘿)  
  38.                        sHandleToSensor.append(sensor.getHandle(), sensor);  
  39.                    }  
  40.                 }while (i>0);  
  41.   
  42.                 sPool= new SensorEventPool( sFullSensorsList.size()*2 );  
  43.                sSensorThread = new SensorThread(); // 哟,创建线程了好像  
  44.             }  
  45.         }  
  46.     }  

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

  1. private static native void nativeClassInit();  
  2. private static native int sensors_module_init();  
  3. private static native intsensors_module_get_next_sensor(Sensor sensor, int next);  

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

  1. frameworks/base/core/java/android/hardware/SensorManager.java  
  2. frameworks/base/core/jni/android_hardware_SensorManager.cpp  

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

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

  1. static void  
  2. nativeClassInit (JNIEnv *_env, jclass _this)  
  3. {  
  4.    jclasssensorClass = _env->FindClass("android/hardware/Sensor");  
  5.    SensorOffsets& sensorOffsets = gSensorOffsets;  
  6.    sensorOffsets.name        =_env->GetFieldID(sensorClass, "mName",      "Ljava/lang/String;");  
  7.    sensorOffsets.vendor      =_env->GetFieldID(sensorClass, "mVendor",    "Ljava/lang/String;");  
  8.    sensorOffsets.version     =_env->GetFieldID(sensorClass, "mVersion",   "I");  
  9.    sensorOffsets.handle      =_env->GetFieldID(sensorClass, "mHandle",    "I");  
  10.    sensorOffsets.type        = _env->GetFieldID(sensorClass,"mType",      "I");  
  11.    sensorOffsets.range       =_env->GetFieldID(sensorClass, "mMaxRange",  "F");  
  12.    sensorOffsets.resolution  =_env->GetFieldID(sensorClass, "mResolution","F");  
  13.    sensorOffsets.power       =_env->GetFieldID(sensorClass, "mPower",     "F");  
  14.    sensorOffsets.minDelay    =_env->GetFieldID(sensorClass, "mMinDelay",  "I");  
  15. }  

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

         sensors_module_init()本地方法的实现:

  1. static jint  
  2. sensors_module_ini(JNIEnv *env, jclass clazz)  
  3. {  
  4.    SensorManager::getInstance();  
  5.     return 0;  
  6. }  

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

本地SensorManager的定义

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

  1. class SensorManager :  
  2.     publicASensorManager,  
  3.     publicSingleton<SensorManager>  
  4. {  
  5. public:  
  6.    SensorManager();  
  7.    ~SensorManager();  
  8.   
  9.     ssize_tgetSensorList(Sensor constconst** list) const;  
  10.   
  11.     Sensor const*getDefaultSensor(int type);  
  12.    sp<SensorEventQueue> createEventQueue();  
  13. private:  
  14.     //DeathRecipient interface  
  15.     voidsensorManagerDied();  
  16.     status_tassertStateLocked() const;  
  17. private:  
  18.     mutable MutexmLock;  
  19.     mutablesp<ISensorServer> mSensorServer;  
  20.     mutableSensor const** mSensorList;  
  21.     mutableVector<Sensor> mSensors;  
  22.     mutablesp<IBinder::DeathRecipient> mDeathObserver;  
  23. };  

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

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

  1. template <typename TYPE>  
  2. class ANDROID_API Singleton  
  3. {  
  4. public:  
  5.   
  6.     staticTYPE& getInstance() {  
  7.        Mutex::Autolock _l(sLock);  
  8.         TYPE*instance = sInstance;  
  9.         if(instance == 0) {  
  10.            instance = new TYPE();  
  11.            sInstance = instance;  
  12.         }  
  13.   
  14.         return*instance;  
  15.     }  
  16.   
  17.     static boolhasInstance() {  
  18.        Mutex::Autolock _l(sLock);  
  19.         returnsInstance != 0;  
  20.     }  
  21.   
  22. protected:  
  23.     ~Singleton(){ };  
  24.     Singleton() {};  
  25.   
  26. private:  
  27.    Singleton(const Singleton&);  
  28.    Singleton& operator = (const Singleton&);  
  29.     static MutexsLock;  
  30.     static TYPE*sInstance;  
  31. };  
  32. //---------------------------------------------------------------------------  
  33. }; // namespace android  
第一次调用getInstance方法时,创建泛型对象即:SensorManager,随后再调用该方法时返回第一次创建的泛型对象。

1)    本地SensorManager的创建

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

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

  1. SensorManager::SensorManager()        
  2.     :mSensorList(0)  
  3. {  
  4.     // okay we'renot locked here, but it's not needed during construction  
  5.    assertStateLocked();  
  6. }  
  7.   
  8. status_t SensorManager::assertStateLocked() const {  
  9.     if(mSensorServer == NULL) {  
  10.         // try for one second  
  11.         constString16 name("sensorservice");  
  12.         for (inti=0 ; i<4 ; i++) {  
  13.             status_t err = getService(name,&mSensorServer);  
  14.             if(err == NAME_NOT_FOUND) {  
  15.                usleep(250000);  
  16.                continue;  
  17.             }  
  18.   
  19.             if(err != NO_ERROR) {  
  20.                return err;  
  21.             }  
  22.             break;  
  23.         }  
  24.   
  25.         classDeathObserver : public IBinder::DeathRecipient {  
  26.            SensorManager& mSensorManger;  
  27.            virtual void binderDied(const wp<IBinder>& who) {  
  28.                LOGW("sensorservice died [%p]", who.unsafe_get());  
  29.                mSensorManger.sensorManagerDied();  
  30.             }  
  31.         public:  
  32.            DeathObserver(SensorManager& mgr) : mSensorManger(mgr) { }  
  33.         };  
  34.   
  35.        mDeathObserver = new DeathObserver(*const_cast<SensorManager*>(this));  
  36.         mSensorServer->asBinder()->linkToDeath(mDeathObserver);  
  37.   
  38.         mSensors= mSensorServer->getSensorList();  
  39.        size_tcount = mSensors.size();  
  40.        mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*));  
  41.         for(size_t i=0 ; i<count ; i++) {  
  42.            mSensorList[i] = mSensors.array() + i;  
  43.         }  
  44.     }  
  45.   
  46.     returnNO_ERROR;  
  47. }  

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

2)    本地SensorManager中列表的获取

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

  1. Vector<Sensor> SensorService::getSensorList()  
  2. {  
  3.     return mUserSensorList;  
  4. }  

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

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

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

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

  1. class SensorManager :  
  2.     public ASensorManager,  
  3.     public Singleton<SensorManager>  
  4. {  
  5.  mutable sp<ISensorServer>mSensorServer;  
  6.  mutable Sensorconst** mSensorList;  
  7.  mutable Vector<Sensor> mSensors;  
  8. };  

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

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

  1. void SensorService::onFirstRef()  
  2. {     
  3.    LOGD("nuSensorService starting...");  
  4.    SensorDevice& dev(SensorDevice::getInstance());                //创建SensorDevice对象dev  
  5.       
  6.   
  7.     if(dev.initCheck() == NO_ERROR) {  
  8.         sensor_tconst* list;  
  9.         ssize_tcount = dev.getSensorList(&list);                          //获得传感器设备列表  
  10.         if (count> 0) {  
  11.             …   
  12.             for(ssize_t i=0 ; i<count ; i++) {  
  13.                 registerSensor( new HardwareSensor(list[i]) );  // 注册在本地获得的传感器  
  14.                            …  
  15.                       }  
  16.             constSensorFusion& fusion(SensorFusion::getInstance());  
  17.                        
  18.             if(hasGyro) {            // 如果有陀螺仪设备,则先注册和陀螺仪有关的虚拟传感器设备  
  19.                 registerVirtualSensor( newRotationVectorSensor() );     // 虚拟旋转传感器  
  20.                registerVirtualSensor( new GravitySensor(list, count) ); // 虚拟重力传感器  
  21.                registerVirtualSensor( new LinearAccelerationSensor(list, count) ); // 虚拟加速器  
  22.   
  23.                 // these are optional  
  24.                registerVirtualSensor( new OrientationSensor() ); // 虚拟方向传感器  
  25.                registerVirtualSensor( new CorrectedGyroSensor(list, count) );        // 真正陀螺仪  
  26.   
  27.                // virtual debugging sensors...  
  28.                 char value[PROPERTY_VALUE_MAX];  
  29.                property_get("debug.sensors", value, "0");  
  30.                if (atoi(value)) {  
  31.                    registerVirtualSensor( new GyroDriftSensor() );      // 虚拟陀螺测漂传感器  
  32.                 }  
  33.             }  
  34.                       
  35.             // build the sensor list returned tousers  
  36.             mUserSensorList = mSensorList;  
  37.             if(hasGyro &&  
  38.                    (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR))) {  
  39.                // if we have the fancy sensor fusion, and it's not provided by the  
  40.                // HAL, use our own (fused) orientation sensor by removing the  
  41.                // HAL supplied one form the user list.  
  42.                if (orientationIndex >= 0) {  
  43.                    mUserSensorList.removeItemsAt(orientationIndex);  
  44.                 }  
  45.             }  
  46.   
  47.             run("SensorService",PRIORITY_URGENT_DISPLAY);  
  48.            mInitCheck = NO_ERROR;  
  49.         }  
  50.     }  
  51. }  

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

  1. void SensorService::registerSensor(SensorInterface* s)  
  2. {  
  3.     sensors_event_t event;  
  4.     memset(&event,0, sizeof(event));  
  5.   
  6.     const Sensorsensor(s->getSensor());  
  7.     // add to thesensor list (returned to clients)  
  8.     mSensorList.add(sensor);  
  9.     // add to ourhandle->SensorInterface mapping  
  10.    mSensorMap.add(sensor.getHandle(), s);  
  11.     // create anentry in the mLastEventSeen array  
  12.    mLastEventSeen.add(sensor.getHandle(), event);  
  13. }  

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

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


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

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

  1. bool SensorService::threadLoop()  
  2. {  
  3.    LOGD("nuSensorService thread starting...");  
  4.   
  5.     const size_tnumEventMax = 16 * (1 + mVirtualSensorList.size());  
  6.    sensors_event_t buffer[numEventMax];  
  7.    sensors_event_t scratch[numEventMax];  
  8.    SensorDevice& device(SensorDevice::getInstance());  
  9.     const size_tvcount = mVirtualSensorList.size();  
  10.   
  11.     ssize_tcount;  
  12.     do {  
  13.              // 调用SensorDevice的poll方法看样子要多路监听了  
  14.         count = device.poll(buffer,numEventMax);       
  15.         if(count<0) {  
  16.            LOGE("sensor poll failed (%s)", strerror(-count));  
  17.            break;  
  18.         }  
  19.               // 记录poll返回的每一个传感器中的最后一个数据信息到mLastEventSeen中  
  20.         recordLastValue(buffer, count);  
  21.   
  22.         // handlevirtual sensors 处理虚拟传感器数据  
  23.         if (count&& vcount) {  
  24.            sensors_event_t const * const event = buffer;  
  25.                       // 获得虚拟传感器列表  
  26.             constDefaultKeyedVector<int, SensorInterface*> virtualSensors(  
  27.                    getActiveVirtualSensors());  
  28.             constsize_t activeVirtualSensorCount = virtualSensors.size();  // 虚拟传感器个数  
  29.             if(activeVirtualSensorCount) {  
  30.                size_t k = 0;  
  31.                SensorFusion& fusion(SensorFusion::getInstance());  
  32.                if (fusion.isEnabled()) {  
  33.                    for (size_t i=0 ; i<size_t(count) ; i++) {  
  34.                        fusion.process(event[i]);              //处理虚拟传感器设备事件  
  35.                     }  
  36.                 }  
  37.                for (size_t i=0 ; i<size_t(count) ; i++) {  
  38.                    for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {  
  39.                        sensors_event_t out;  
  40.                        if (virtualSensors.valueAt(j)->process(&out, event[i])) {  
  41.                             buffer[count + k] =out;  
  42.                             k++;  
  43.                        }  
  44.                    }  
  45.                 }  
  46.                if (k) {  
  47.                    // record the last synthesized values  
  48.                    recordLastValue(&buffer[count], k);  
  49.                    count += k;  
  50.                    // sort the buffer by time-stamps  
  51.                    sortEventBuffer(buffer, count);  
  52.                 }  
  53.             }  
  54.         }  
  55.   
  56.         // sendour events to clients...   
  57.              // 获得传感器连接对象列表  
  58.         constSortedVector< wp<SensorEventConnection> > activeConnections(  
  59.                getActiveConnections());  
  60.         size_tnumConnections = activeConnections.size();  
  61.         for(size_t i=0 ; i<numConnections ; i++) {  
  62.            sp<SensorEventConnection> connection(  
  63.                    activeConnections[i].promote());  
  64.             if(connection != 0) {  
  65.                                // 向指定的传感器连接客户端发送传感器数据信息  
  66.                 connection->sendEvents(buffer, count, scratch);  
  67.             }  
  68.         }  
  69.     } while (count>= 0 || Thread::exitPending());   // 传感器循环监听线程  
  70.   
  71.    LOGW("Exiting SensorService::threadLoop => aborting...");  
  72.     abort();  
  73.     return false;  
  74. }  

我们看到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.向客户端发送传感器事件信息




    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。如发现有害或侵权内容,请点击这里 或 拨打24小时举报电话:4000070609 与我们联系。

    猜你喜欢

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多
    喜欢该文的人也喜欢 更多