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

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

編輯:Android開發實例

Sensor本地封裝類SensorDevice

SensorDevice是在本地代碼中SensorService對Sensor設備的抽象類型封裝,它封裝了傳感器硬件的硬件操作,該類繼承了Singleton類,通過getInstance方法獲得單例模式設備操作對象:

@frameworks/base/services/sensorservice/SensorDevice.h

  1. class SensorDevice : public Singleton<SensorDevice> {  
  2.     friend class Singleton<SensorDevice>;  
  3.    struct sensors_poll_device_t* mSensorDevice;  
  4.     struct sensors_module_t* mSensorModule;  
  5.     mutable Mutex mLock;    // protect mActivationCount[].rates  
  6.     // fixed-size array after construction  
  7.     struct Info {  
  8.         Info() : delay(0) { }  
  9.         KeyedVector<void*, nsecs_t> rates;  
  10.         nsecs_t delay;  
  11. status_t setDelayForIdent(void* ident, int64_t ns);  
  12.         nsecs_t selectDelay();  
  13.     };  
  14.     DefaultKeyedVector<int, Info> mActivationCount;  
  15. SensorDevice();  
  16. public:  
  17.     ssize_t getSensorList(sensor_t const** list);  
  18.     status_t initCheck() const;  
  19.     ssize_t poll(sensors_event_t* buffer, size_t count);  
  20.     status_t activate(void* ident, int handle, int enabled);  
  21.     status_t setDelay(void* ident, int handle, int64_t ns);  
  22.     void dump(String8& result, char* buffer, size_t SIZE);  
  23. }; 

通過SensorDevice類的定義可看到它包含的屬性和方法:

屬性:

mSensorDevice:Sensor設備HAL層操作接口封裝結構

mSensorModule:Sensor設備HAL硬件模塊封裝結構

mActivationCount:保存激活Sensor設備向量表

方法:

SensorDevice:構造方法

getSensorList:獲得Sensor設備列表方法

poll:Sensor設備多路監聽方法

activate:設備激活方法

setDelay:設備Sensor設備延遲方法

由前面分析可知,SensorDevice是單例模型,其構造方法僅會調用一次:

@frameworks/base/services/sensorservice/SensorDevice.cpp

  1. SensorDevice::SensorDevice()  
  2.     :  mSensorDevice(0), mSensorModule(0)  
  3. {  
  4.         // 終於看到hw_get_module了,幸福,高興,開心,相見時難別亦難…  
  5.     status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,  
  6.             (hw_module_t const**)&mSensorModule);  
  7.     LOGE_IF(err, "couldn't load %s module (%s)",  
  8.             SENSORS_HARDWARE_MODULE_ID, strerror(-err));  
  9.     if (mSensorModule) {  
  10.             //打開module設備,返回module設備的操作接口,保存在mSensorDevice中  
  11.         err = sensors_open(&mSensorModule->common, &mSensorDevice);  
  12.         LOGE_IF(err, "couldn't open device for module %s (%s)",  
  13.                 SENSORS_HARDWARE_MODULE_ID, strerror(-err));  
  14.         if (mSensorDevice) {  
  15.             sensor_t const* list;  
  16.               // 調用module設備的get_sensors_list接口  
  17.             ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);  
  18.             mActivationCount.setCapacity(count);  
  19.             Info model;  
  20.             for (size_t i=0 ; i<size_t(count) ; i++) {  
  21.                 mActivationCount.add(list[i].handle, model);  
  22.                 mSensorDevice->activate(mSensorDevice, list[i].handle, 0);  
  23.             }  
  24.         }  
  25.     }  

在SensorDevice構造方法裡調用HAL架構的hw_get_module來獲得Sensor設備模塊,之後調用sensors_open這個工具函數,打開Sensor設備模塊(調用其methods->open函數指針),返回Sensor設備的操作接口(這些接口在HAL層實現),保存在mSensorDevice中,調用Sensor模塊的get_sensors_list方法獲得傳感器列表,然後依次激活這些設備並且添加到mActivationCount設備信息向量中。

Sensor HAL模塊代碼及打開模塊工具函數sensors_open:

@hardware/libhardware/include/hardware/sensors.h

  1. struct sensors_module_t {  
  2.     struct hw_module_t common;  
  3.     /**     * Enumerate all available sensors. The list is returned in "list".  
  4.      * @return number of sensors in the list  
  5.      */ 
  6.     int (*get_sensors_list)(struct sensors_module_t* module,  
  7.             struct sensor_t const** list);  
  8. };  
  9. ……  
  10. static inline int sensors_open(const struct hw_module_t* module,  
  11.         struct sensors_poll_device_t** device) {  
  12.     return module->methods->open(module,  
  13.             SENSORS_HARDWARE_POLL, (struct hw_device_t**)device);  

SensorDevice其它幾個方法比較簡單:

  1. ssize_t SensorDevice::getSensorList(sensor_t const** list) {  
  2.     if (!mSensorModule) return NO_INIT;  
  3.        // 直接調用模塊的get_sensors_list方法獲得Sensor列表  
  4.     ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);  
  5.     return count;  
  6. }  
  7.  
  8. ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {  
  9.     if (!mSensorDevice) return NO_INIT;  
  10.     ssize_t c;  
  11.     do {  
  12.            // 調用Sensor設備的poll操作接口,該接口實現在HAL層  
  13.         c = mSensorDevice->poll(mSensorDevice, buffer, count);  
  14.     } while (c == -EINTR);  
  15.     return c;  
  16. }  
  17.  
  18. status_t SensorDevice::activate(void* ident, int handle, int enabled)  
  19. {  
  20.     if (!mSensorDevice) return NO_INIT;  
  21.     status_t err(NO_ERROR);  
  22.     bool actuateHardware = false;  
  23.  
  24.     Info& info( mActivationCount.editValueFor(handle) );  
  25.  
  26.     LOGD_IF(DEBUG_CONNECTIONS,  
  27.             "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",  
  28.             ident, handle, enabled, info.rates.size());  
  29.  
  30.     if (enabled) {  
  31.         Mutex::Autolock _l(mLock);  
  32.         LOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",  
  33.                 info.rates.indexOfKey(ident));  
  34.            // 設置設備為默認延遲級別  
  35.         if (info.rates.indexOfKey(ident) < 0) {  
  36.             info.rates.add(ident, DEFAULT_EVENTS_PERIOD);  
  37.             if (info.rates.size() == 1) {  
  38.                 actuateHardware = true;  
  39.             }  
  40.         } else {  
  41.             // sensor was already activated for this ident  
  42.         }  
  43.     } else {  
  44.         Mutex::Autolock _l(mLock);  
  45.         LOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",  
  46.                 info.rates.indexOfKey(ident));  
  47.  
  48.         ssize_t idx = info.rates.removeItem(ident);  
  49.         if (idx >= 0) {  
  50.             if (info.rates.size() == 0) {  
  51.                 actuateHardware = true;  
  52.             }  
  53.         } else {  
  54.             // sensor wasn't enabled for this ident  
  55.         }  
  56.     }  
  57.  
  58.     if (actuateHardware) {  
  59.         LOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w");  
  60.           // 調用Sensor設備activate操作接口,其實現在HAL層  
  61.         err = mSensorDevice->activate(mSensorDevice, handle, enabled);  
  62.         if (enabled) {  
  63.             LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));  
  64.             if (err == 0) {  
  65.                  // 在電池服務中使能Sensor電源  
  66.                 BatteryService::getInstance().enableSensor(handle);  
  67.             }  
  68.         } else {  
  69.             if (err == 0) {  
  70.                  // 在電池服務中關閉Sensor電源  
  71.                 BatteryService::getInstance().disableSensor(handle);  
  72.             }  
  73.         }  
  74.     }  
  75.  
  76.     { // scope for the lock  
  77.         Mutex::Autolock _l(mLock);  
  78.         nsecs_t ns = info.selectDelay();  
  79.           // 設置延遲值  
  80.         mSensorDevice->setDelay(mSensorDevice, handle, ns);  
  81.     }  
  82.  
  83.     return err;  
  84. }  

由這幾個SensorDevice的方法可知,其具體的實現全部由mSensorDevice 封裝的設備操作接口函數實現,這些設備操作接口在HAL層實現,其實SensorDevice只是SensorService的設備操作對象,封裝了設備的操作,而這些操作實際“干活的”的是HAL層代碼。

一路分析過來,已經到了HAL層了,我們回顧下前面所學的東西。

讓我們從Java應用層到框架層再到本地代碼來總結下:


 

1. Android的應用程序調用getSystemService方法獲得SensorManager對象,該方法實現在ContextImpl.java中,它是Activity的抽象父類Context的實現類。

2. 在應用程序(Activity)初始化時調用registerService創建並注冊SensorManager

3. 創建SensorManager

4. 在SensorManager的構造方法中,調用了本地方法:nativeClassInit(),它用來初始化了Java對象Sensor在本地的引用,方便本地代碼對Java對象操作。

5. 在SensorManager的構造方法中,調用sensors_module_init()來創建SensorManager本地對象。

8. 調用sensors_module_get_next_sensor()方法,通過nativeClassInit中初始化的Sensor引用填充Sensor設備列表,返回給Java框架層。

12. 將sensors_module_get_next_sensor()獲得的設備列表保存在sFullSensorsList中。

13. 創建SensorThread線程准備監聽Sensor硬件事件變化。

14. 應用程序通過getDefaultSensor來獲得指定類型傳感器的對象

16. 通過registerListener注冊Sensor監聽器。
下一節,讓我們來看下SensorThread線程。

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