Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> [Android的系統移植與平台開發]Sensor HAL框架分析[3]

[Android的系統移植與平台開發]Sensor HAL框架分析[3]

編輯:Android開發實例

讓我們來看看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");  

 

其代碼比較簡單,將Java框架層的Sensor類中的成員保存在本地代碼中的gSensorOffsets 結構體中將來使用。

         sensors_module_init()本地方法的實現:

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

         在本地代碼中調用了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 const* const** 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;  

在assertStateLocked方法裡,先通過getService獲得SensorService對象,然後注冊了對SensorService的死亡監聽器,SensorManager與SensorService不求同年同月同日,只求同年同月同日死。拜完了兄弟之後,調用getSensorList得到所有傳感器的對象,存放到mSensorList中,保存在本地空間裡。

2)    本地SensorManager中列表的獲取

在上面函數調用中首先調用getService來獲得SensorService服務,然後執行mSensorServer->getSensorList來獲得服務提供的傳感器列表:

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

大家要注意啊,上面的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.     }  

上面代碼首先通過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;  

我們看到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.向客戶端發送傳感器事件信息

轉自:http://blog.csdn.net/mr_raptor/article/details/8128912

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved