讓我們來看看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.javaframeworks/base/core/jni/android_hardware_SensorManager.cpp
果不其然,在jni存在其本地代碼,讓我們來看下nativeClassInit函數:
@frameworks/base/core/jni/android_hardware_SensorManager.cpp
static voidnativeClassInit (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 jintsensors_module_ini(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) { // try for 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(){ return mUserSensorList;}
大家要注意啊,上面的getSensorList函數只是返回了mUserSensorList,而這個變數是在什麼時候初始化的呢?
根據2.1節可知,SensorService在本地被初始化時,建構函式裡並沒有對mUserSensorList進行初始化,而SensorService裡有一個onFirstRef方法,這個方法當SensorService第一次被強引用時被自動調用。那SensorService第一次被強引用是在什麼時候呢?
在SensorManager::assertStateLocked方法裡調用getService獲得SensorService儲存到mSensorServer成員變數中。
mSensorServer的定義在frameworks/base/include/gui/SensorManager.h中:
class SensorManager : public ASensorManager, public Singleton<SensorManager>{ mutable sp<ISensorServer>mSensorServer; mutable Sensorconst** mSensorList; mutable Vector<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.向用戶端發送感應器事件資訊