1. 程式人生 > >Android Sensor HAL層分析

Android Sensor HAL層分析

   SensorService在SystemServer程序中啟動。

/frameworks/base/ervices/java/com/android/server/SystemServer.java

private void startBootstrapServices() {  
   ...  
   startSensorService();  
}  

  startSensorService是一個native函式,其具體實現在com_android_server_SystemServer.cpp的android_server_SystemServer_startSensorService函式中。

/frameworks/base/services/core/jni/com_android_server_SystemServer.cpp

static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {  
    char propBuf[PROPERTY_VALUE_MAX];  
    property_get("system_init.startsensorservice", propBuf, "1");  
    if (strcmp(propBuf, "1"
) == 0) { // Start the sensor service SensorService::instantiate(); } }

  SensorService::instantiate()的instantiate函式定義在BinderService.h中,目的在於向ServiceManager註冊SensorService元件。new SERVICE()引數的傳入最終結果是建立SensorService的一個強引用。

/frameworks/native/include/binder/BinderService.h

static
void instantiate() { publish(); }

/frameworks/native/include/binder/BinderService.h


static status_t publish(bool allowIsolated = false) {  
        sp<IServiceManager> sm(defaultServiceManager());  
        return sm->addService(  
                String16(SERVICE::getServiceName()),  
                new SERVICE(), allowIsolated);  
}  

  onFirstRef函式是RefBase的一個空實現,SensorService繼承自RefBase,onFirstRef在第一次被強指標引用時呼叫,首先是獲得一個SensorDevice單例物件。

/frameworks/native/services/sensorservice/SensorService.cpp

void SensorService::onFirstRef()  
{  
    ALOGD("nuSensorService starting...");  
    SensorDevice& dev(SensorDevice::getInstance()); 
    ...
}

  看看SensorDevice的預設建構函式:

/frameworks/native/services/sensorservice/SensorDevice.cpp

SensorDevice::SensorDevice()  
    :  mSensorDevice(0),  
       mSensorModule(0)  
{  
    status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,  
            (hw_module_t const**)&mSensorModule);  

    ALOGE_IF(err, "couldn't load %s module (%s)",  
            SENSORS_HARDWARE_MODULE_ID, strerror(-err));  

    if (mSensorModule) {  
        err = sensors_open_1(&mSensorModule->common, &mSensorDevice);  

        ALOGE_IF(err, "couldn't open device for module %s (%s)",  
                SENSORS_HARDWARE_MODULE_ID, strerror(-err));  

        if (mSensorDevice) {  
            if (mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_1 ||  
                mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_2) {  
                ALOGE(">>>> WARNING <<< Upgrade sensor HAL to version 1_3");  
            }  

            sensor_t const* 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(  
                        reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),  
                        list[i].handle, 0);  
            }  
        }  
    }  
}  

  hw_get_module是jni層獲取HAL層module的介面函式,原型為hareware.c中的:int hw_get_module(const char *id, const struct hw_module_t **module),第一個引數為硬體模組的id,第二個引數指向硬體模組對應的hw_module_t結構體地址。

/hardware/libhardware/hardware.c

int hw_get_module(const char *id, const struct hw_module_t **module)
{
    return hw_get_module_by_class(id, NULL, module);
}

/hardware/libhardware/hardware.c

int hw_get_module_by_class(const char *class_id, const char *inst,
                           const struct hw_module_t **module)
{
    int i = 0;
    char prop[PATH_MAX] = {0};
    char path[PATH_MAX] = {0};
    char name[PATH_MAX] = {0};
    char prop_name[PATH_MAX] = {0};


    if (inst)
        snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
    else
        strlcpy(name, class_id, PATH_MAX);//class_id拷貝到name

    /*
     * Here we rely on the fact that calling dlopen multiple times on
     * the same .so will simply increment a refcount (and not load
     * a new copy of the library).
     * We also assume that dlopen() is thread-safe.
     */

    /* First try a property specific to the class and possibly instance */
    //prop_name為ro.hardware.(name),SensorService傳下來的class_id為sensors,則prop_name為ro.hardware.sensors
    snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name);
    //獲取prop_name的屬性值,儲存在prop中
    if (property_get(prop_name, prop, NULL) > 0) {
    //輸出固定的檔名格式到path中
        if (hw_module_exists(path, sizeof(path), name, prop) == 0) {//
            goto found;
        }
    }

    /* Loop through the configuration variants looking for a module */
    for (i=0 ; i<HAL_VARIANT_KEYS_COUNT; i++) {
        if (property_get(variant_keys[i], prop, NULL) == 0) {
            continue;
        }
        if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
            goto found;
        }
    }

    /* Nothing found, try the default */
    if (hw_module_exists(path, sizeof(path), name, "default") == 0) {
        goto found;
    }

    return -ENOENT;

found:
    /* load the module, if this fails, we're doomed, and we should not try
     * to load a different variant. */
    return load(class_id, path, module);
}

/hardware/libhardware/hardware.c

//緊接上面,32位下生成/vendor/lib/hw.sensors.屬性值.so或/system/lib/hw.sensors.屬性值.so,64位下生成/vendor/lib64/hw.sensors.屬性值.so或/system/lib64/hw.sensors.屬性值.so
static int hw_module_exists(char *path, size_t path_len, const char *name,
                            const char *subname)
{
    snprintf(path, path_len, "%s/%s.%s.so",
             HAL_LIBRARY_PATH2, name, subname);
    if (access(path, R_OK) == 0)
        return 0;

    snprintf(path, path_len, "%s/%s.%s.so",
             HAL_LIBRARY_PATH1, name, subname);
    if (access(path, R_OK) == 0)
        return 0;

    return -ENOENT;
}

/hardware/libhardware/hardware.c

//嘗試去載入上面路徑的so檔案
static int load(const char *id,
        const char *path,
        const struct hw_module_t **pHmi)
{
    int status = -EINVAL;
    void *handle = NULL;
    struct hw_module_t *hmi = NULL;

    /*
     * load the symbols resolving undefined symbols before
     * dlopen returns. Since RTLD_GLOBAL is not or'd in with
     * RTLD_NOW the external symbols will not be global
     */
    //dlopen以暫緩決定模式開啟指定的動態連線庫檔案,並返回一個控制代碼給呼叫程序
    handle = dlopen(path, RTLD_NOW);
    if (handle == NULL) {
        char const *err_str = dlerror();
        ALOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
        status = -EINVAL;
        goto done;
    }

    /* Get the address of the struct hal_module_info. */
    //dlsym通過控制代碼和連線符名稱獲取函式名或者變數名,返回符號的地址
    const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
    hmi = (struct hw_module_t *)dlsym(handle, sym);
    if (hmi == NULL) {
        ALOGE("load: couldn't find symbol %s", sym);
        status = -EINVAL;
        goto done;
    }

    /* Check that the id matches */
    if (strcmp(id, hmi->id) != 0) {
        ALOGE("load: id=%s != hmi->id=%s", id, hmi->id);
        status = -EINVAL;
        goto done;
    }

    hmi->dso = handle;

    /* success */
    status = 0;

    done:
    if (status != 0) {
        hmi = NULL;
        if (handle != NULL) {
            dlclose(handle);
            handle = NULL;
        }
    } else {
        ALOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
                id, path, *pHmi, handle);
    }

    *pHmi = hmi;

    return status;
}

  硬體抽象層模組中總會定義一個HAL_MODULE_INFO_SYM_AS_STR的符號,HAL_MODULE_INFO_SYM_AS_STR在巨集定義中被定義為“HMI”,在這裡HAL_MODULE_INFO_SYM_AS_STR是struct sensors_module_t的變數,struct sensors_module_t第一個成員common為struct hw_module_t型別。因為common成員和HAL_MODULE_INFO_SYM_AS_STR首地址相同,所以load函式末尾可以安全地將第二個引數的地址指向這個符號的地址。所以SensorDevice中型別為struct sensors_module_t*的mSensorModule成員指向了HAL_MODULE_INFO_SYM_AS_STR符號的地址。

/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);

    /**
     *  Place the module in a specific mode. The following modes are defined
     *
     *  0 - Normal operation. Default state of the module.
     *  1 - Loopback mode. Data is injected for the the supported
     *      sensors by the sensor service in this mode.
     * @return 0 on success
     *         -EINVAL if requested mode is not supported
     *         -EPERM if operation is not allowed
     */
    int (*set_operation_mode)(unsigned int mode);
};

  此時,sensor模組的so已載入完成。回到SensorDevice的建構函式中,接著呼叫sensors_open_1函式開啟sensor裝置。sensors_open_1沒有在SensorDevice.cpp中實現,而是在HAL層實現。

/frameworks/native/services/sensorservice/SensorDevice.cpp

...
if (mSensorModule) {
        err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
        ...

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

static inline int sensors_open_1(const struct hw_module_t* module,
        sensors_poll_device_1_t** device) {
    return module->methods->open(module,
            SENSORS_HARDWARE_POLL, (struct hw_device_t**)device);
}

  該函式接收sensors_module_t的common成員的指標(struct hw_module_t*型別)作為第一個引數,呼叫引數的struct hw_module_methods_t*型別的methods成員的唯一函式指標成員,即open函式。其中,SENSORS_HARDWARE_POLL在巨集定義被定義為“poll”。

/hardware/libhardware/include/hardware/hardware.h

typedef struct hw_module_t {
    /** tag must be initialized to HARDWARE_MODULE_TAG */
    uint32_t tag;

    /**
     * The API version of the implemented module. The module owner is
     * responsible for updating the version when a module interface has
     * changed.
     *
     * The derived modules such as gralloc and audio own and manage this field.
     * The module user must interpret the version field to decide whether or
     * not to inter-operate with the supplied module implementation.
     * For example, SurfaceFlinger is responsible for making sure that
     * it knows how to manage different versions of the gralloc-module API,
     * and AudioFlinger must know how to do the same for audio-module API.
     *
     * The module API version should include a major and a minor component.
     * For example, version 1.0 could be represented as 0x0100. This format
     * implies that versions 0x0100-0x01ff are all API-compatible.
     *
     * In the future, libhardware will expose a hw_get_module_version()
     * (or equivalent) function that will take minimum/maximum supported
     * versions as arguments and would be able to reject modules with
     * versions outside of the supplied range.
     */
    uint16_t module_api_version;
#define version_major module_api_version
    /**
     * version_major/version_minor defines are supplied here for temporary
     * source code compatibility. They will be removed in the next version.
     * ALL clients must convert to the new version format.
     */

    /**
     * The API version of the HAL module interface. This is meant to
     * version the hw_module_t, hw_module_methods_t, and hw_device_t
     * structures and definitions.
     *
     * The HAL interface owns this field. Module users/implementations
     * must NOT rely on this value for version information.
     *
     * Presently, 0 is the only valid value.
     */
    uint16_t hal_api_version;
#define version_minor hal_api_version

    /** Identifier of module */
    const char *id;

    /** Name of this module */
    const char *name;

    /** Author/owner/implementor of the module */
    const char *author;

    /** Modules methods */
    struct hw_module_methods_t* methods;

    /** module's dso */
    void* dso;

#ifdef __LP64__
    uint64_t reserved[32-7];
#else
    /** padding to 128 bytes, reserved for future use */
    uint32_t reserved[32-7];
#endif

} hw_module_t;

/hardware/libhardware/include/hardware/hardware.h

typedef struct hw_module_methods_t {
    /** Open a specific device */
    int (*open)(const struct hw_module_t* module, const char* id,
            struct hw_device_t** device);

} hw_module_methods_t;

  sensors.h為我們提供了HAL層的介面,實現部分則在sensors.c或sensors.cpp完成。sensors.cpp定義了一個hw_module_methods_t型別的變數sensors_module_methods,並且指定open函式的實現為open_sensors函式。

/hardware/akm/AK8975_FS/libsensors/Sensors.cpp

static struct hw_module_methods_t sensors_module_methods = {
        .open = open_sensors
};

/hardware/akm/AK8975_FS/libsensors/Sensors.cpp

static int open_sensors(const struct hw_module_t* module, const char* id,
                        struct hw_device_t** device)
{
    UNUSE(id);

    LOGD("open_sensors()");
    int status = -EINVAL;
    sensors_poll_context_t *dev = new sensors_poll_context_t();

    if (!dev->isValid()) {
        ALOGE("Failed to open the sensors");
        return status;
    }

    memset(&dev->device, 0, sizeof(sensors_poll_device_t));

    dev->device.common.tag = HARDWARE_DEVICE_TAG;
    dev->device.common.version  = SENSORS_DEVICE_API_VERSION_1_0;
    dev->device.common.module   = const_cast<hw_module_t*>(module);
    dev->device.common.close    = poll__close;
    dev->device.activate        = poll__activate;
    dev->device.setDelay        = poll__setDelay;
    dev->device.poll            = poll__poll;

    *device = &dev->device.common;
    status = 0;

    return status;
}

  open_sensors函式首先new了一個sensors_poll_context_t物件。

/hardware/akm/AK8975_FS/libsensors/Sensors.cpp

struct sensors_poll_context_t {
    struct sensors_poll_device_t device; // must be first

    sensors_poll_context_t();
    ~sensors_poll_context_t();
    int activate(int handle, int enabled);
    int setDelay(int handle, int64_t ns);
    int setDelay_sub(int handle, int64_t ns);
    int pollEvents(sensors_event_t* data, int count);

private:
    enum {
        acc          = 0,
        akm          = 1,
        numSensorDrivers,
        numFds,
    };

    static const size_t wake = numFds - 1;
    static const char WAKE_MESSAGE = 'W';
    struct pollfd mPollFds[numFds];
    int mWritePipeFd;
    SensorBase* mSensors[numSensorDrivers];

    /* These function will be different depends on
     * which sensor is implemented in AKMD program.
     */
    int handleToDriver(int handle);
    int proxy_enable(int handle, int enabled);
    int proxy_setDelay(int handle, int64_t ns);
};

/hardware/akm/AK8975_FS/libsensors/Sensors.cpp

sensors_poll_context_t::sensors_poll_context_t()
{
#ifdef SENSORHAL_ACC_ADXL346
    mSensors[acc] = new AdxlSensor();
#endif
#ifdef SENSORHAL_ACC_KXTF9
    mSensors[acc] = new KionixSensor();
#endif
    mPollFds[acc].fd = mSensors[acc]->getFd();
    mPollFds[acc].events = POLLIN;
    mPollFds[acc].revents = 0;

    mSensors[akm] = new AkmSensor();
    mPollFds[akm].fd = mSensors[akm]->getFd();
    mPollFds[akm].events = POLLIN;
    mPollFds[akm].revents = 0;

    int wakeFds[2];
    int result = pipe(wakeFds);
    ALOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno));
    fcntl(wakeFds[0], F_SETFL, O_NONBLOCK);
    fcntl(wakeFds[1], F_SETFL, O_NONBLOCK);
    mWritePipeFd = wakeFds[1];

    mPollFds[wake].fd = wakeFds[0];
    mPollFds[wake].events = POLLIN;
    mPollFds[wake].revents = 0;
}

  sensors_poll_context_t的建構函式主要工作是使用poll監聽AdxlSensor,KionixSensor和建立的管道讀端的POLLIN事件。
  回到open_sensors函式,接著對sensors_poll_context_t的成員作初始化。sensors_poll_context_t的首個成員為sensors_poll_device_t,而sensors_poll_device_t的首個成員是hw_device_t,這三個型別的變數首地址是相同的,所以它們的指標可以相互安全地進行轉換。最後把傳下來的第二個指標引數指向已被初始化的hw_device_t成員地址。
  hw_get_module和sensors_open_1這兩個函式儲存了HAL層對應的hw_module_t型別和hw_device_t型別的指標。再次返回SenosrDevice的建構函式,接下來用get_sensors_list去獲取sensor的列表。

/frameworks/native/services/sensorservice/SensorDevice.cpp

...
sensor_t const* list;
ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
mActivationCount.setCapacity(count);
...

  同樣地,get_sensors_list方法的設定出現在HMI符號中,然後調到sensors__get_sensors_list方法,最後獲取到struct sensor_t陣列,並使傳下來的第二個引數指向該陣列的地址,其中sensor_t的作用是記錄sensor的資訊引數,一個sensor裝置對應一個sensor_t結構體。

/hardware/akm/AK8975_FS/libsensors/Sensors.cpp

struct sensors_module_t HAL_MODULE_INFO_SYM = {
        .common = {
                .tag = HARDWARE_MODULE_TAG,
                .version_major = 1,
                .version_minor = 0,
                .id = SENSORS_HARDWARE_MODULE_ID,
                .name = "AKM Sensor module",
                .author = "Asahi Kasei Microdevices",
                .methods = &sensors_module_methods,
                .dso  = NULL,
                .reserved = {0},
        },
        .get_sensors_list = sensors__get_sensors_list,
};

/hardware/akm/AK8975_FS/libsensors/Sensors.cpp

static int sensors__get_sensors_list(struct sensors_module_t* module,
                                     struct sensor_t const** list)
{
        *list = sSensorList;
        return ARRAY_SIZE(sSensorList);
}

/hardware/akm/AK8975_FS/libsensors/Sensors.cpp

static const struct sensor_t sSensorList[] = {
        { "AK8975 3-axis Magnetic field sensor",
          "Asahi Kasei Microdevices",
          1,
          SENSORS_MAGNETIC_FIELD_HANDLE,
          SENSOR_TYPE_MAGNETIC_FIELD, 1228.8f,
          CONVERT_M, 0.35f, 10000, 0, 0, 0, 0, 0, 0, { } },
#ifdef SENSORHAL_ACC_ADXL346
        { "Analog Devices ADXL345/6 3-axis Accelerometer",
          "ADI",
          1, SENSORS_ACCELERATION_HANDLE,
          SENSOR_TYPE_ACCELEROMETER, (GRAVITY_EARTH * 16.0f),
          (GRAVITY_EARTH * 16.0f) / 4096.0f, 0.145f, 10000, 0, 0, 0, 0, 0, 0, { } },
        { "AK8975 Orientation sensor",
          "Asahi Kasei Microdevices",
          1, SENSORS_ORIENTATION_HANDLE,
          SENSOR_TYPE_ORIENTATION, 360.0f,
          CONVERT_O, 0.495f, 10000, 0, 0, 0, 0, 0, 0, { } }
#endif
#ifdef SENSORHAL_ACC_KXTF9
        { "Kionix KXTF9 3-axis Accelerometer",
          "Kionix",
          1, SENSORS_ACCELERATION_HANDLE,
          SENSOR_TYPE_ACCELEROMETER, (GRAVITY_EARTH * 2.0f),
          (GRAVITY_EARTH) / 1024.0f, 0.7f, 10000, 0, 0, 0, 0, 0, 0, { } },
        { "AK8975 Orientation sensor",
          "Asahi Kasei Microdevices",
          1, SENSORS_ORIENTATION_HANDLE,
          SENSOR_TYPE_ORIENTATION, 360.0f,
          CONVERT_O, 1.05f, 10000, 0, 0, 0, 0, 0, 0, { } }
#endif
};

  回到SensorDevice的建構函式中,最後一步是使用activate方法對上面sensor列表的sensor進行啟用。同理,activate方法最終會調到sensors_poll_context_t::activate方法。

/hardware/akm/AK8975_FS/libsensors/Sensors.cpp

static int poll__activate(struct sensors_poll_device_t *dev,
        int handle, int enabled) {
    sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
    return ctx->activate(handle, enabled);
}

/hardware/akm/AK8975_FS/libsensors/Sensors.cpp

int sensors_poll_context_t::activate(int handle, int enabled) {
    int drv = handleToDriver(handle);
    int err;

    switch (handle) {
        case ID_A:
        case ID_M:
            /* No dependencies */
            break;

        case ID_O:
            /* These sensors depend on ID_A and ID_M */
            mSensors[handleToDriver(ID_A)]->setEnable(ID_A, enabled);
            mSensors[handleToDriver(ID_M)]->setEnable(ID_M, enabled);
            break;

        default:
            return -EINVAL;
    }
    err = mSensors[drv]->setEnable(handle, enabled);

    if (enabled && !err) {
        const char wakeMessage(WAKE_MESSAGE);
        int result = write(mWritePipeFd, &wakeMessage, 1);
        ALOGE_IF(result<0, "error sending wake message (%s)", strerror(errno));
    }
    return err;
}

  下面以AdxlSensor為例進行說明:
  如果AdxlSensor沒有被啟用且enabled引數為1,只將mEnables加1。
  如果AdxlSensor已經被首次激活了,則往/sys/class/input/(input_name)/device/device/disable中寫入“1”,將mEnable減1。注意到這裡傳下來的enabled引數為0,AdxlSensor建構函式中把mEnabled初始化為0,也就是說SensorDevice初始化時不會將相關Sensor使能,要使Sensor使能,需要應用層調到native層使能。

/hardware/akm/AK8975_FS/libsensors/AdxlSensor.cpp

int AdxlSensor::setEnable(int32_t handle, int enabled) {
    int err = 0;
    char buffer[2];

    /* handle check */
    if (handle != ID_A) {
        ALOGE("AdxlSensor: Invalid handle (%d)", handle);
        return -EINVAL;
    }

    buffer[0] = '\0';
    buffer[1] = '\0';

    if (mEnabled <= 0) {
        if(enabled) buffer[0] = '0';
    } else if (mEnabled == 1) {
        if(!enabled) buffer[0] = '1';
    }
    if (buffer[0] != '\0') {
        strcpy(&input_sysfs_path[input_sysfs_path_len], "disable");
        err = write_sys_attribute(input_sysfs_path, buffer, 1);
        if (err != 0) {
            return err;
        }
        ALOGD("AdxlSensor: Control set %s", buffer);
        setInitialState();
    }

    if (enabled) {
        mEnabled++;
        if (mEnabled > 32767) mEnabled = 32767;
    } else {
        mEnabled--;
        if (mEnabled < 0) mEnabled = 0;
    }
    ALOGD("AdxlSensor: mEnabled = %d", mEnabled);

    return err;
}

  AdxlSensor傳給SensorBase建構函式的兩個引數分別是NULL, ADXL_DATA_NAME,在巨集定義被定義為”ADXL34x accelerometer”。之後呼叫openInput(ADXL_DATA_NAME)開啟輸入裝置。

/hardware/akm/AK8975_FS/libsensors/SensorBase.cpp

SensorBase::SensorBase(
        const char* dev_name,
        const char* data_name)
    : dev_name(dev_name), data_name(data_name),
      dev_fd(-1), data_fd(-1)
{
    if (data_name) {
        data_fd = openInput(data_name);
    }
}

  openInput函式在/dev/input目錄下查詢裝置名稱。Linux核心提供了一個Input子系統,Input子系統會在/dev/input/路徑下建立我們硬體輸入裝置的節點,一般情況下在我們的手機中這些節點是以eventXX來命名的,如event0,event1等等,可以利用EVIOCGNAME獲取此事件結點名稱。open(devname, O_RDONLY)打開了裝置節點,strcpy(input_name, filename)將裝置名拷貝到input_name中。
/hardware/akm/AK8975_FS/libsensors/SensorBase.cpp

int SensorBase::openInput(const char* inputName) {
    int fd = -1;
    const char *dirname = "/dev/input";
    char devname[PATH_MAX];
    char *filename;
    DIR *dir;
    struct dirent *de;
    dir = opendir(dirname);
    if(dir == NULL)
        return -1;
    strcpy(devname, dirname);
    filename = devname + strlen(devname);
    *filename++ = '/';
    while((de = readdir(dir))) {
        if(de->d_name[0] == '.' &&
                (de->d_name[1] == '\0' ||
                        (de->d_name[1] == '.' && de->d_name[2] == '\0')))
            continue;
        strcpy(filename, de->d_name);
        fd = open(devname, O_RDONLY);
        if (fd>=0) {
            char name[80];
            if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
                name[0] = '\0';
            }
            if (!strcmp(name, inputName)) {
                strcpy(input_name, filename);
                break;
            } else {
                close(fd);
                fd = -1;
            }
        }
    }
    closedir(dir);
    ALOGE_IF(fd<0, "couldn't find '%s' input device", inputName);
    return fd;
}

  這樣,SensorDevice的建構函式便介紹完畢。
  回到SensorService的onFirstRef函式,SensorService繼承自Thread,函式末尾呼叫run進入threadLoop方法。

/frameworks/native/services/sensorservice/SensorService.cpp

...
run("SensorService", PRIORITY_URGENT_DISPLAY);
...

  threadLoop方法中呼叫了SensorDevice::poll方法,mSensorEventBuffer是一個struct sensors_event_t陣列。每個感測器的資料都由struct sensors_event_t表示。

/frameworks/native/services/sensorservice/SensorService.cpp

...
do {
        ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
        if (count < 0) {
            ALOGE("sensor poll failed (%s)", strerror(-count));
            break;
        }
...

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

typedef struct sensors_event_t {
    /* must be sizeof(struct sensors_event_t) */
    int32_t version;

    /* sensor identifier */
    int32_t sensor;

    /* sensor type */
    int32_t type;

    /* reserved */
    int32_t reserved0;

    /* time is in nanosecond */
    int64_t timestamp;

    union {
        union {
            float           data[16];

            /* acceleration values are in meter per second per second (m/s^2) */
            sensors_vec_t   acceleration;

            /* magnetic vector values are in micro-Tesla (uT) */
            sensors_vec_t   magnetic;

            /* orientation values are in degrees */
            sensors_vec_t   orientation;

            /* gyroscope values are in rad/s */
            sensors_vec_t   gyro;

            /* temperature is in degrees centigrade (Celsius) */
            float           temperature;

            /* distance in centimeters */
            float           distance;

            /* light in SI lux units */
            float           light;

            /* pressure in hectopascal (hPa) */
            float           pressure;

            /* relative humidity in percent */
            float           relative_humidity;

            /* uncalibrated gyroscope values are in rad/s */
            uncalibrated_event_t uncalibrated_gyro;

            /* uncalibrated magnetometer values are in micro-Teslas */
            uncalibrated_event_t uncalibrated_magnetic;

            /* heart rate data containing value in bpm and status */
            heart_rate_event_t heart_rate;

            /* this is a special event. see SENSOR_TYPE_META_DATA above.
             * sensors_meta_data_event_t events are all reported with a type of
             * SENSOR_TYPE_META_DATA. The handle is ignored and must be zero.
             */
            meta_data_event_t meta_data;
        };

        union {
            uint64_t        data[8];

            /* step-counter */
            uint64_t        step_counter;
        } u64;
    };

    /* Reserved flags for internal use. Set to zero. */
    uint32_t flags;

    uint32_t reserved1[3];
} sensors_event_t;

  SensorDevice::poll函式最終會調到sensors_poll_context_t::pollEvents函式。

/frameworks/native/services/sensorservice/SensorDevice.cpp

ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
    if (!mSensorDevice) return NO_INIT;
    ssize_t c;
    do {
        c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
                                buffer, count);
    } while (c == -EINTR);
    return c;
}

  如果前面監聽的Sensor描述符(AdxlSensor和KionixSensor)發生了POLLIN事件或者有未處理的事件,則呼叫readEvents去處理這些事件。readEvents返回值nb為讀得的事件數量,count為傳回上層的事件容量,data記錄了sensors_event_t結構體陣列的當前儲存位置。每次讀出事件後,都會對這三個變數作處理。
  如果還有剩餘容量(count>0),則會抓住最後機會使用poll爭取獲得事件,nbEvents記錄了每次進入pollEvents讀到的事件總數量。若nbEvents大於0,poll的時間引數為0,表示立即返回;若nbEvents等於0,poll的時間引數為-1,表示一直阻塞到讀取到事件。若此時有執行緒從管道喚醒poll,則會對喚醒事件作處理(實質就是使 mPollFds[wake]的revents恢復預設值)。若poll成功讀取到事件且還有剩餘容量,則再次進入pollEvents的主迴圈。
  第一次進入pollEvents函式時,由於還沒有poll,mPollFds中的所有Sensor的fd都不會有變化,所以會阻塞在poll呼叫中,直到Sensor發生了事件或者有執行緒從管道將其喚醒。之後再次進入主迴圈呼叫readEvents讀取Sensor事件(如果Sensor發生POLLIN事件的話),count沒有滿的情況下,然後再次進入poll函式,這樣一直迴圈下去,直到poll沒有事件返回且沒有事件容量才會退出迴圈。

/hardware/akm/AK8975_FS/libsensors/Sensors.cpp

int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count)
{
    int nbEvents = 0;
    int n = 0;

    do {
        // see if we have some leftover from the last poll()
        for (int i=0 ; count && i<numSensorDrivers ; i++) {
            SensorBase* const sensor(mSensors[i]);
            if ((mPollFds[i].revents & POLLIN) || (sensor->hasPendingEvents())) {
                int nb = sensor->readEvents(data, count);
                if (nb < count) {
                    // no more data for this sensor
                    mPollFds[i].revents = 0;
                }
                if ((0 != nb) && (acc == i)) {
                    ((AkmSensor*)(mSensors[akm]))->setAccel(&data[nb-1]);
                }
                count -= nb;
                nbEvents += nb;
                data += nb;
            }
        }

        if (count) {
            // we still have some room, so try to see if we can get
            // some events immediately or just wait if we don't have
            // anything to return
            n = poll(mPollFds, numFds, nbEvents ? 0 : -1);
            if (n<0) {
                ALOGE("poll() failed (%s)", strerror(errno));
                return -errno;
            }
            if (mPollFds[wake].revents & POLLIN) {
                char msg;
                int result = read(mPollFds[wake].fd, &msg, 1);
                ALOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno));
                ALOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg));
                mPollFds[wake].revents = 0;
            }
        }
        // if we have events and space, go read them
    } while (n && count);

    return nbEvents;
}

  readEvents中如果有未處理事件,則將sensors_event_t型別的未處理事件指標儲存在第一個引數中。mInputReader型別為class InputEventCircularReader,是用來填充struct input_event輸入事件的環形緩衝區。data_fd為openInput的返回值,即開啟的輸入裝置的fd。AdxlSensor的建構函式將4傳給InputEventCircularReader建構函式引數,mBuffer初始化為8個input_event大小的記憶體,以暫存讀取超出環形緩衝區的部分。mBufferEnd指向環形緩衝的末尾,mHead記錄了下次填充input_event的位置,mCurr記錄了最後一個填充的input_event的位置,mFreeSpace記錄了空閒的input_event大小的記憶體塊數量。fill函式從輸入裝置中讀取input_event事件到環形緩衝區中,當讀取的大小超過緩衝區大小時,會將超出部分覆蓋到緩衝區起始部分。
  while迴圈裡讀取mCurr記錄的input_event的型別來執行操作,迴圈的條件是環形緩衝區還有資料可以讀且需要讀取事件的餘量count大於0。AdxlSensor是一個加速度感測器,讀取的事件型別為EV_ABS,可以用來判斷手機螢幕的方向。x軸,y軸是以螢幕左下角為原點向右和向上的方向,z軸是垂直於螢幕指向螢幕外面的方向。在一個時刻,只有一個軸讀取到加速度值。使用ADXL_UNIT_CONVERSION巨集將核心層讀到的重力加速度值轉化為標準單位重力加速度值。在三軸上計算得到的資料用以初始化一個mPendingEvent。讀取事件型別為EV_SYN時(EV_SYN是用於事件間的分割標誌。事件可能按時間或空間進行分割,就像在多點觸控協議中的例子),設定mPendingEvent的時間戳為輸入事件發生的時間,將mPendingEvent指標儲存在data引數中。這樣,readEvents函式將底層傳上來的input_event填充到入參data中。SensorService便儲存了來自底層的input_event包裝而成的sensors_event_t事件。readEvents的返回值就是儲存到data引數中的
input_event數量。
  值得注意的是,readEvents的入參data是對sensors_poll_context_t::pollEvents的入參data指標值的拷貝,readEvents中能改變data指向的陣列的內容,但不能改變指標的指向的位置。所以,當readEvents函式返回了讀取的事件數時,sensors_poll_context_t::pollEvents的入參data表示的陣列內容已經改變,指向的位置和呼叫readEvents前的位置相同。

/hardware/akm/AK8975_FS/libsensors/AdxlSensor.cpp

int AdxlSensor::readEvents(sensors_event_t* data, int count)
{
    if (count < 1)
        return -EINVAL;

    if (mHasPendingEvent) {
        mHasPendingEvent = false;
        mPendingEvent.timestamp = getTimestamp();
        *data = mPendingEvent;
        return mEnabled ? 1 : 0;
    }

    ssize_t n = mInputReader.fill(data_fd);
    if (n < 0)
        return n;

    int numEventReceived = 0;
    input_event const* event;

    while (count && mInputReader.readEvent(&event)) {
        int type = event->type;
        if (type == EV_ABS) {
            float value = event->value;
            if (event->code == EVENT_TYPE_ACCEL_X) {
                mPendingEvent.acceleration.x = ADXL_UNIT_CONVERSION(value);
            } else if (event->code == EVENT_TYPE_ACCEL_Y) {
                mPendingEvent.acceleration.y = ADXL_UNIT_CONVERSION(value);
            } else if (event->code == EVENT_TYPE_ACCEL_Z) {
                mPendingEvent.acceleration.z = ADXL_UNIT_CONVERSION(value);
            }
        } else if (type == EV_SYN) {
            mPendingEvent.timestamp = timevalToNano(event->time);
            if (mEnabled) {
                *data++ = mPendingEvent;
                count--;
                numEventReceived++;
            }
        } else {
            ALOGE("AdxlSensor: unknown event (type=%d, code=%d)",
                    type, event->code);
        }
        mInputReader.next();
    }

    return numEventReceived;
}

/hardware/akm/AK8975_FS/libsensors/InputEventReader.h

class InputEventCircularReader
{
    struct input_event* const mBuffer;
    struct input_event* const mBufferEnd;
    struct input_event* mHead;
    struct input_event* mCurr;
    ssize_t mFreeSpace;

public:
    InputEventCircularReader(size_t numEvents);
    ~InputEventCircularReader();
    ssize_t fill(int fd);
    ssize_t readEvent(input_event const** events);
    void next();
};

/hardware/akm/AK8975_FS/libsensors/InputEventReader.h

InputEventCircularReader::InputEventCircularReader(size_t numEvents)
    : mBuffer(new input_event[numEvents * 2]),
      mBufferEnd(mBuffer + numEvents),
      mHead(mBuffer),
      mCurr(mBuffer),
      mFreeSpace(numEvents)
{
}

/hardware/akm/AK8975_FS/libsensors/InputEventReader.cpp

ssize_t InputEventCircularReader::fill(int fd)
{
    size_t numEventsRead = 0;