深入淺出 – Android系統移植與平台開發(十四) – Sensor HAL架構分析之四

來源:互聯網
上載者:User
Sensor本地封裝類SensorDevice

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

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

class SensorDevice : public Singleton<SensorDevice> {    friend class Singleton<SensorDevice>;   struct sensors_poll_device_t* mSensorDevice;    struct sensors_module_t* mSensorModule;    mutable Mutex mLock; // protect mActivationCount[].rates    // fixed-size array after construction    struct Info {        Info() : delay(0) { }        KeyedVector<void*, nsecs_t> rates;        nsecs_t delay;status_t setDelayForIdent(void* ident, int64_t ns);        nsecs_t selectDelay();    };    DefaultKeyedVector<int, Info> mActivationCount;SensorDevice();public:    ssize_t getSensorList(sensor_t const** list);    status_t initCheck() const;    ssize_t poll(sensors_event_t* buffer, size_t count);    status_t activate(void* ident, int handle, int enabled);    status_t setDelay(void* ident, int handle, int64_t ns);    void dump(String8& result, char* buffer, size_t SIZE);};

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

屬性:

mSensorDevice:Sensor裝置HAL層操作介面封裝結構

mSensorModule:Sensor裝置HAL硬體模組封裝結構

mActivationCount:儲存啟用Sensor裝置向量表

方法:

SensorDevice:構造方法

getSensorList:獲得Sensor裝置列表方法

poll:Sensor裝置多路監聽方法

activate:裝置啟用方法

setDelay:裝置Sensor裝置延遲方法

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

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

SensorDevice::SensorDevice()    :  mSensorDevice(0), mSensorModule(0){    // 終於看到hw_get_module了,幸福,高興,開心,相見時難別亦難…    status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,            (hw_module_t const**)&mSensorModule);    LOGE_IF(err, "couldn't load %s module (%s)",            SENSORS_HARDWARE_MODULE_ID, strerror(-err));    if (mSensorModule) {        //開啟module裝置,返回module裝置的操作介面,儲存在mSensorDevice中        err = sensors_open(&mSensorModule->common, &mSensorDevice);        LOGE_IF(err, "couldn't open device for module %s (%s)",                SENSORS_HARDWARE_MODULE_ID, strerror(-err));        if (mSensorDevice) {            sensor_t const* list;  // 調用module裝置的get_sensors_list介面            ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);            mActivationCount.setCapacity(count);            Info model;            for (size_t i=0 ; i<size_t(count) ; i++) {                mActivationCount.add(list[i].handle, model);                mSensorDevice->activate(mSensorDevice, list[i].handle, 0);            }        }    }}

在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

struct sensors_module_t {    struct hw_module_t common;    /**     * Enumerate all available sensors. The list is returned in "list".     * @return number of sensors in the list     */    int (*get_sensors_list)(struct sensors_module_t* module,            struct sensor_t const** list);};……static inline int sensors_open(const struct hw_module_t* module,        struct sensors_poll_device_t** device) {    return module->methods->open(module,            SENSORS_HARDWARE_POLL, (struct hw_device_t**)device);}

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

ssize_t SensorDevice::getSensorList(sensor_t const** list) {    if (!mSensorModule) return NO_INIT;   // 直接調用模組的get_sensors_list方法獲得Sensor列表    ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);    return count;}ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {    if (!mSensorDevice) return NO_INIT;    ssize_t c;    do {   // 調用Sensor裝置的poll操作介面,該介面實現在HAL層        c = mSensorDevice->poll(mSensorDevice, buffer, count);    } while (c == -EINTR);    return c;}status_t SensorDevice::activate(void* ident, int handle, int enabled){    if (!mSensorDevice) return NO_INIT;    status_t err(NO_ERROR);    bool actuateHardware = false;    Info& info( mActivationCount.editValueFor(handle) );    LOGD_IF(DEBUG_CONNECTIONS,            "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",            ident, handle, enabled, info.rates.size());    if (enabled) {        Mutex::Autolock _l(mLock);        LOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",                info.rates.indexOfKey(ident));   // 設定裝置為預設延遲層級        if (info.rates.indexOfKey(ident) < 0) {            info.rates.add(ident, DEFAULT_EVENTS_PERIOD);            if (info.rates.size() == 1) {                actuateHardware = true;            }        } else {            // sensor was already activated for this ident        }    } else {        Mutex::Autolock _l(mLock);        LOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",                info.rates.indexOfKey(ident));        ssize_t idx = info.rates.removeItem(ident);        if (idx >= 0) {            if (info.rates.size() == 0) {                actuateHardware = true;            }        } else {            // sensor wasn't enabled for this ident        }    }    if (actuateHardware) {        LOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w");  // 調用Sensor裝置activate操作介面,其實現在HAL層        err = mSensorDevice->activate(mSensorDevice, handle, enabled);        if (enabled) {            LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));            if (err == 0) { // 在電池服務中使能Sensor電源                BatteryService::getInstance().enableSensor(handle);            }        } else {            if (err == 0) { // 在電池服務中關閉Sensor電源                BatteryService::getInstance().disableSensor(handle);            }        }    }    { // scope for the lock        Mutex::Autolock _l(mLock);        nsecs_t ns = info.selectDelay();  // 設定延遲值        mSensorDevice->setDelay(mSensorDevice, handle, ns);    }    return err;}

由這幾個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監聽器。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.