Android Sensor Input类型 (五) Sensor HAL NativeSensorManager

NativeSensorManager

代码路径:

code/hardware/qcom/sensors/NativeSensorManager.cpp

code/hardware/qcom/sensors/NativeSensorManager.h

NativeSensorManager类定义

class NativeSensorManager : public Singleton<NativeSensorManager> {
    friend class Singleton<NativeSensorManager>;
    NativeSensorManager();
    ~NativeSensorManager();
    struct sensor_t sensor_list[MAX_SENSORS]; //!< sensorlist数组 >! NoteBy: yujixuan
    struct SensorContext context[MAX_SENSORS]; //!< context数组 >! NoteBy: yujixuan
    struct SensorEventMap event_list[MAX_SENSORS]; //!< 用于上报的evnet 数组 >! NoteBy: yujixuan
    static const struct SysfsMap node_map[]; //sysfs 设备节点名
    static const struct sensor_t virtualSensorList[];
    static char virtualSensorName[][SYSFS_MAXLEN];  //虚拟sensor相关
 
    int mSensorCount;
    bool mScanned;
    int mEventCount;
 
    DefaultKeyedVector<int32_t, struct SensorContext*> type_map;
    DefaultKeyedVector<int32_t, struct SensorContext*> handle_map;
    DefaultKeyedVector<int, struct SensorContext*> fd_map;
 
    void compositeVirtualSensorName(const char *sensor_name, char *chip_name, int type);
    int getNode(char *buf, char *path, const struct SysfsMap *map);
    int getSensorListInner();
    int getDataInfo();
    int registerListener(struct SensorContext *hw, struct SensorContext *virt);
    int initCalibrate(const SensorContext *list);
    int initVirtualSensor(struct SensorContext *ctx, int handle, struct sensor_t info);
    int addDependency(struct SensorContext *ctx, int handle);
    int getEventPath(const char *sysfs_path, char *event_path);
    int getEventPathOld(const struct SensorContext *list, char *event_path);
public:
    int getSensorList(const sensor_t **list);  //!< 获取sensor列表 >! NoteBy: yujixuan
    inline SensorContext* getInfoByFd(int fd) { return fd_map.valueFor(fd); };
    inline SensorContext* getInfoByHandle(int handle) { return handle_map.valueFor(handle); };
    inline SensorContext* getInfoByType(int type) { return type_map.valueFor(type); };
    int getSensorCount() {return mSensorCount;}
    void dump();
    int hasPendingEvents(int handle);
    int activate(int handle, int enable);
    int setDelay(int handle, int64_t ns);
    int readEvents(int handle, sensors_event_t *data, int count); //!< 读取events >! NoteBy: yujixuan
    int calibrate(int handle, struct cal_cmd_t *para);
    int batch(int handle, int64_t sample_ns, int64_t latency_ns);
    int flush(int handle);
};

class NativeSensorManager 继承了Singleton,单例模式,只存在一个实例对象,即在SensorHal 中被多次访问使用的sm;

通过NativeSensorManager class的定义可知 主要有以下内容:

  • 定义维护了 在SensorHAL 中由 sensor_t 组成的 sensor_list 数组;
  • 定义由SensorContext 组成的 Context数组;
  • 定义了SensorEventMap 组成的 event_list 数组;
  • 定义了用于记录sensor 在sys中设备节点路径的 SysfsMap

SysfsMap node_map

struct SysfsMap {
    int offset;
    const char *node;
    int type;
    int required;
};
const struct SysfsMap NativeSensorManager::node_map[] = {
    {offsetof(struct sensor_t, name), SYSFS_NAME, TYPE_STRING, 1},
    {offsetof(struct sensor_t, vendor), SYSFS_VENDOR, TYPE_STRING, 1},
    {offsetof(struct sensor_t, version), SYSFS_VERSION, TYPE_INTEGER, 1},
    {offsetof(struct sensor_t, type), SYSFS_TYPE, TYPE_INTEGER, 1},
    {offsetof(struct sensor_t, maxRange), SYSFS_MAXRANGE, TYPE_FLOAT, 1},
    {offsetof(struct sensor_t, resolution), SYSFS_RESOLUTION, TYPE_FLOAT, 1},
    {offsetof(struct sensor_t, power), SYSFS_POWER, TYPE_FLOAT, 1},
......
};

SensorEventMap

struct SensorEventMap {
  char data_name[80];
  char data_path[PATH_MAX];
};

继承Singleton 单例模式

前面可知,NativeSensorManager : public Singleton,集成了Sigleton, 是单例模式

Singleton模板类,指定了 template的类型,T为 NativeSensorManager; (note:C++模板

在NativeSensorManager.cpp的最开始,创建了实例;

ANDROID_SINGLETON_STATIC_INSTANCE(NativeSensorManager);

代码路径:system/core/include/utils/Singleton.h

template <typename TYPE>
class ANDROID_API Singleton
{
public:
    static TYPE& getInstance() {
        Mutex::Autolock _l(sLock);
        TYPE* instance = sInstance;
        if (instance == 0) {
            instance = new TYPE();
            sInstance = instance;
        }
        //如果实例对象不存在,实例化一个对象, 已存在直接返回;
        //TYPE == NativeSensorManager
        return *instance;
    }
    static bool hasInstance() {
        Mutex::Autolock _l(sLock);
        return sInstance != 0;
    }
protected:
    ~Singleton() { };
    Singleton() { };
private:
    Singleton(const Singleton&);
    Singleton& operator = (const Singleton&);
    static Mutex sLock;
    static TYPE* sInstance;
};
#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE)                 \
    template<> ::android::Mutex  \
        (::android::Singleton< TYPE >::sLock)(::android::Mutex::PRIVATE);  \
    template<> TYPE* ::android::Singleton< TYPE >::sInstance(0);  \
    template class ::android::Singleton< TYPE >;

由上分析可知,NativeSensorManager未实例化在第一次调用时有 instance = new TYPE(); 即 new NativeSensorManager();

以下是 NativeSensorManager类构造器的实现:

NativeSensorManager::NativeSensorManager():
    mSensorCount(0), mScanned(false), mEventCount(0), type_map(NULL), handle_map(NULL), fd_map(NULL)
{
    int i;
    memset(sensor_list, 0, sizeof(sensor_list));
    memset(context, 0, sizeof(context));
    type_map.setCapacity(MAX_SENSORS);
    handle_map.setCapacity(MAX_SENSORS);
    fd_map.setCapacity(MAX_SENSORS);
    for (i = 0; i < MAX_SENSORS; i++) {
        context[i].sensor = &sensor_list[i];
        sensor_list[i].name = context[i].name;
        sensor_list[i].vendor = context[i].vendor;
        list_init(&context[i].listener);
        list_init(&context[i].dep_list);
    }
    if(getDataInfo()) {
        ALOGE("Get data info failed\n");
    }
    dump();
}

通过getDataInfo 初始化sensor list数组,sensor context数组,对NativeSensorManager 做实际的数据填充;

dump 显示当前NativeSensorManager的主要内容;

getDataInfo 填充数据

NativeSensorManager是管理sensor HAL 处理的核心,getDataInfo是对填充构建内部细节的实际实现,一下是其主要内容:

int NativeSensorManager::getDataInfo() {
    int i, j;
    struct SensorContext *list;
    int has_acc = 0;
    int has_compass = 0;
    int has_gyro = 0;
    int has_light = 0;
    int has_proximity = 0;
    struct sensor_t sensor_mag;
    struct sensor_t sensor_acc;
    struct sensor_t sensor_light;
    struct sensor_t sensor_proximity;
    struct sensor_t sensor_gyro;
    mSensorCount = getSensorListInner();
    //1:完成SensorContext list 获取和填充 包含sensor_t
    for (i = 0; i < mSensorCount; i++) {
        struct SensorRefMap *item;
        list = &context[i];
        list->is_virtual = false;
        item = new struct SensorRefMap;
        item->ctx = list;
        /* hardware sensor depend on itself */
        list_add_tail(&list->dep_list, &item->list);
        if (strlen(list->data_path) != 0)
            list->data_fd = open(list->data_path, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
        //open event 路径,获取文件描述符
        if (list->data_fd > 0) {
            fd_map.add(list->data_fd, list);
        // DefaultKeyedVector<int, struct SensorContext*> fd_map;
        // 添加到sm的fd_map中;
        }
        type_map.add(list->sensor->type, list);
        //  DefaultKeyedVector<int32_t, struct SensorContext*> type_map;
        // 添加到sm的type_map中;
        handle_map.add(list->sensor->handle, list);
        //  DefaultKeyedVector<int32_t, struct SensorContext*> handle_map;
        // 添加到sm的handle_map中;
        //根据不同的sensor type,创建不同的SensorBase子类实例;
        switch (list->sensor->type) {
            case SENSOR_TYPE_ACCELEROMETER:
                has_acc = 1;
                list->driver = new AccelSensor(list);
        //假设,type是acc,new一个 AccelSensor; 一个SensorBase子类实例
                sensor_acc = *(list->sensor);
                break;
            case SENSOR_TYPE_MAGNETIC_FIELD:
                has_compass = 1;
                list->driver = new CompassSensor(list);
                sensor_mag = *(list->sensor);
                break;
            case SENSOR_TYPE_PROXIMITY:
                has_proximity = 1;
        //......
                list->driver = new LightSensor(list);
                sensor_light = *(list->sensor);
                break;
	    //......
            default:
                list->driver = NULL;
                ALOGE("No handle %d for this type sensor!", i);
                break;
        }
        initCalibrate(list);
        //校准相关
    }

    //virtual sensors 
    //......
}

校准相关,virtual sensor相关暂不分析; 通过以上代码,可知在getDataInfo 中主要实现了:

  • 通过getSensorListInner 完成SensorContext list 获取和填充 包含sensor_t
  • 通过for循环,对每一个sensor做处理,打开其event patch,记录得到的文件描述符fd到map中;
  • 判断sensor type 根据返回的结果 创建基于SensorBase的sensor driver实例;

getSensorListInner获取

通过前面的blog可知,sensor kernel driver 注册了sensor class类,提供了若干api 用于往sensor class注册;

sensor driver的具体实现中注册了 input device;通过adb, 可以直观的相关的device node如下:

msm8909:/sys/class/sensors # ls
MPU6050-accel MPU6050-gyro mmc3416x-mag stk3x1x-light stk3x1x-proximity
    
msm8909:/sys/class/sensors/MPU6050-accel # ls
calibrate enable_wakeup             flags  max_delay   min_delay  power      sensor_power uevent
device    fifo_max_event_count      flush  max_latency name       resolution subsystem    vendor
enable    fifo_reserved_event_count handle max_range   poll_delay self_test  type         version
    
msm8909:/sys/class/sensors/MPU6050-accel/device # ls
MPU6050-accel capabilities enable id       name poll_delay properties subsystem uniq
addr          device       event4 modalias phys power      reg        uevent    write
    
msm8909:/sys/class/sensors/MPU6050-accel/device # cat uevent
PRODUCT=18/0/0/0
NAME="MPU6050-accel"
PROP=0
EV=9
ABS=100 7
MODALIAS=input:b0018v0000p0000e0000-e0,3,kra0,1,2,28,mlsfw

通过adb 可以直接与这些device node做交互,控制sensor,读取event数据等, 在sensor hal的代码中如何完成这些操作?

前面的内容提到,getDataInfo 填充NativeSensorManager,其中关键是getSensorListInner 完成SensorContext list 获取和填充,下面是它的具体实现:

int NativeSensorManager::getSensorListInner()
{
    int number = 0;
    int err = -1;
    const char *dirname = SYSFS_CLASS;
    //1: SYSFS_CLASS == "/sys/class/sensors/"
    char devname[PATH_MAX];
    char *filename;
    char *nodename;
    DIR *dir;
    struct dirent *de;
    struct SensorContext *list;
    unsigned int i;
    dir = opendir(dirname);
    strlcpy(devname, dirname, PATH_MAX);
    filename = devname + strlen(dirname);
   //2:filename指针指在SYSFS_CLASS之后,即/sys/class/sensors/ 后
    while ((de = readdir(dir))) {
        if(de->d_name[0] == '.' &&
            (de->d_name[1] == '\0' ||
                (de->d_name[1] == '.' && de->d_name[2] == '\0')))
            continue; 
   //3:去掉. .. 等无关目录
        list = &context[number];
   //4:发现一个目标目录,实现一个list 元素;
        strlcpy(filename, de->d_name, PATH_MAX - strlen(SYSFS_CLASS));
   //5:把读到目录名赋值到file name指针的位置;即填充了 devname[PATH_MAX]中 /sys/class/sensors/ 后的内容
        nodename = filename + strlen(de->d_name);
   //6:同样的,nodename 指针指向 filename后的位置
        *nodename++ = '/';
        for (i = 0; i < ARRAY_SIZE(node_map); i++) {
            strlcpy(nodename, node_map[i].node, PATH_MAX - strlen(SYSFS_CLASS) - strlen(de->d_name));
   //7:把node_map中的 预设的name 传入
            err = getNode((char*)(list->sensor), devname, &node_map[i]);
            if (err) {
                ALOGE("Get node for %s failed.\n", devname);
                break;
            }
        //8;过程与上相同,获取每个node的具体路径
        }

        list->sensor->handle = SENSORS_HANDLE(number);
   //#define SENSORS_HANDLE(x) (SENSORS_HANDLE_BASE + x + 1)
        strlcpy(nodename, "", SYSFS_MAXLEN);
        strlcpy(list->enable_path, devname, PATH_MAX);
        /* initialize data path */
        strlcpy(nodename, "device", SYSFS_MAXLEN);
   //路径指向:  /sys/class/sensors/MPU6050-accel/device
        if (getEventPath(devname, list->data_path) == -ENODEV) {
            getEventPathOld(list, list->data_path);
        }
   //9:获取event 节点路径,用来读取数据, 比如 MPU6050-accel, 注册的input event路径是:
   ///dev/input/event4
        number++;
    }
    closedir(dir);
    return number;
}

在/code/hardware/qcom/sensors/sensors.h 中已经预设了 若干信息,例如:

#define SYSFS_CLASS         "/sys/class/sensors/"
#define SYSFS_NAME          "name"
#define SYSFS_VENDOR        "vendor"                                                                                              
#define SYSFS_VERSION       "version"

getSensorListInner 完成对sys中sensor class下每一个sensor的处理;

通过getNode把每一个sensor下的节点数据获取到,并填充保存到相应的数据结构中;

通过getEventPatch 获取到sensor driver驱动中注册的 input device在 input 下的路径;

比如通过adb 可以看到/sys/class/sensors/MPU6050-accel/device

下event的编号是event4, 则记录input device的device node 是/dev/input/event4, 后续读取sensor data 则是通过这个路径。

以下是getNode的实现:

getNode
int NativeSensorManager::getNode(char *buf, char *path, const struct SysfsMap *map) {
    char * fret;
    ssize_t len = 0;
    int fd;
    char tmp[SYSFS_MAXLEN];
    //......
    memset(tmp, 0, sizeof(tmp));
    fd = open(path, O_RDONLY);
    //......
    len = read(fd, tmp, sizeof(tmp) - 1);
    //......
    tmp[len - 1] = '\0';
    if (tmp[strlen(tmp) - 1] == '\n')
        tmp[strlen(tmp) - 1] = '\0';
    //把p 指向sensor_t map->offset 的位置,以name为例,指向指向sensor_t 的name
    if (map->type == TYPE_INTEGER) {
        int *p = (int *)(buf + map->offset);
        *p = atoi(tmp);
    } else if (map->type == TYPE_STRING) {
        char **p = (char **)(buf + map->offset);
        strlcpy(*p, tmp, SYSFS_MAXLEN);
    } else if (map->type == TYPE_FLOAT) {
        float *p = (float*)(buf + map->offset);
        *p = atof(tmp);
    } else if (map->type == TYPE_INTEGER64) {
        int64_t *p = (int64_t *)(buf + map->offset);
        *p = atoll(tmp);
    }
    //read node中的内容,并根据node map中预设的类型 做好转换,把每个sesnor_t 的内容填充上
    close(fd);
    return 0;
}

getNode把每一个sensor下的节点数据获取到,根据map->type 做好指的转换并记录下;

node_map 前面提过,它是SysfsMap元素组成的 预设的数组

struct SysfsMap {
    int offset;
    const char *node;
    int type;
    int required;
};
const struct SysfsMap NativeSensorManager::node_map[] = {
    {offsetof(struct sensor_t, name), SYSFS_NAME, TYPE_STRING, 1},
    {offsetof(struct sensor_t, vendor), SYSFS_VENDOR, TYPE_STRING, 1},
    {offsetof(struct sensor_t, version), SYSFS_VERSION, TYPE_INTEGER, 1},
    {offsetof(struct sensor_t, type), SYSFS_TYPE, TYPE_INTEGER, 1},
    {offsetof(struct sensor_t, maxRange), SYSFS_MAXRANGE, TYPE_FLOAT, 1},
    {offsetof(struct sensor_t, resolution), SYSFS_RESOLUTION, TYPE_FLOAT, 1},
    {offsetof(struct sensor_t, power), SYSFS_POWER, TYPE_FLOAT, 1},
    {offsetof(struct sensor_t, minDelay), SYSFS_MINDELAY, TYPE_INTEGER, 1},
    {offsetof(struct sensor_t, fifoReservedEventCount), SYSFS_FIFORESVCNT, TYPE_INTEGER, 0},
    {offsetof(struct sensor_t, fifoMaxEventCount), SYSFS_FIFOMAXCNT, TYPE_INTEGER, 0},
#if defined(SENSORS_DEVICE_API_VERSION_1_3)
#if defined(__LP64__)
    {offsetof(struct sensor_t, maxDelay), SYSFS_MAXDELAY, TYPE_INTEGER64, 0},
    {offsetof(struct sensor_t, flags), SYSFS_FLAGS, TYPE_INTEGER64, 0},
#else
    {offsetof(struct sensor_t, maxDelay), SYSFS_MAXDELAY, TYPE_INTEGER, 0},
    {offsetof(struct sensor_t, flags), SYSFS_FLAGS, TYPE_INTEGER, 0},
#endif
#endif
};

SensorBase

在前面的getDataInfo处理过程中,其中判断sensor type 根据返回的结果 创建基于SensorBase的sensor driver实例是很关键的一步;

HAL中完成框架性的处理,实际操作需要根据每个sensor的特性对不同的sensor种类做不同的定义处理,以下是以acc为例:

在getDataInfo中,new了一个AccelSensor:

        switch (list->sensor->type) {
            case SENSOR_TYPE_ACCELEROMETER:
                has_acc = 1;
                list->driver = new AccelSensor(list);

AccelSensor类的定义如下:

class AccelSensor : public SensorBase {
    InputEventCircularReader mInputReader;
    sensors_event_t mPendingEvent;
    bool mHasPendingEvent;
    int64_t mEnabledTime;
    int setInitialState();
public:
            AccelSensor();
            AccelSensor(char *name);
            AccelSensor(struct SensorContext *context);
    virtual ~AccelSensor();
    virtual int readEvents(sensors_event_t* data, int count);
    virtual bool hasPendingEvents() const;
    virtual int setDelay(int32_t handle, int64_t ns);
    virtual int enable(int32_t handle, int enabled);
    virtual int calibrate(int32_t handle, struct cal_cmd_t *para,
                    struct cal_result_t *cal_result);
    virtual int initCalibrate(int32_t handle, struct cal_result_t *cal_result);
};

它继承自SensorBase类, SensorBase也是各类sensor类的父类,以下是SensorBase的类的定义:

class SensorBase {
protected:
    const char* dev_name;
    const char* data_name;
    const sensor_cal_algo_t*    algo;
    char        input_name[PATH_MAX];
    int     dev_fd;
    int     data_fd;
    int64_t report_time;
    bool mUseAbsTimeStamp;
    sensors_meta_data_event_t   meta_data;
    char input_sysfs_path[PATH_MAX];
    int input_sysfs_path_len;
    int mEnabled;
    int mHasPendingMetadata;
    int64_t sysclk_sync_offset;
    int openInput(const char* inputName);
    static int64_t getTimestamp();
    static int64_t getClkOffset();

    static int64_t timevalToNano(timeval const& t) {
        return t.tv_sec*1000000000LL + t.tv_usec*1000;
    }
    int open_device();
    int close_device();
public:
    SensorBase(const char* dev_name, const char* data_name,
                    const struct SensorContext* context = NULL);
    virtual ~SensorBase();
    virtual int readEvents(sensors_event_t* data, int count) = 0;
    virtual int injectEvents(sensors_event_t* data, int count);
    virtual bool hasPendingEvents() const;
    virtual int getFd() const;
    virtual int setDelay(int32_t handle, int64_t ns);
    virtual int enable(int32_t handle, int enabled) = 0;
    virtual int calibrate(int32_t handle, struct cal_cmd_t *para, struct cal_result_t *cal_result);
    virtual int initCalibrate(int32_t handle, struct cal_result_t *cal_result);
    virtual int setLatency(int32_t handle, int64_t ns);
    virtual int flush(int32_t handle);
};

SensorBase类中定义了如,readEvents,enable,flush等操作函数,AccelSensor继承了这些虚函数,并且完成了重写;

前文提到,读取poll_poll是调用了NativeSensorManager::readEvents,

list->driver->readEvents(data, count); 即是取出SensorBase指针指向的对象,调用它的readEvents函数;(note:多态的应用,通过指向父类类型对象,调用虚函数,实际调用到子类重写的具体的readEvents函数)

InputEventCircularReader

AccelSensor类定义的首个元素是:mInputReader,它是InputEventCircularReader 类对象;如其名称,输入事件循环读取,它主要用于对sensor event data的获取;

InputEventCircularReader 类定义如下:

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();
};
ssize_t InputEventCircularReader::fill(int fd)
{
    size_t numEventsRead = 0;
    if (mFreeSpace) {
        const ssize_t nread = read(fd, mHead, mFreeSpace * sizeof(input_event));
        if (nread<0 || nread % sizeof(input_event)) {
            // we got a partial event!!
            return nread<0 ? -errno : -EINVAL;
        }
        numEventsRead = nread / sizeof(input_event);
        if (numEventsRead) {
            mHead += numEventsRead;
            mFreeSpace -= numEventsRead;
            if (mHead > mBufferEnd) {
                size_t s = mHead - mBufferEnd;
                memcpy(mBuffer, mBufferEnd, s * sizeof(input_event));
                mHead = mBuffer + s;
            }
        }
    }
    return numEventsRead;
}
ssize_t InputEventCircularReader::readEvent(input_event const** events)
{
    *events = mCurr;
    ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace;
    return available ? 1 : 0;
}
void InputEventCircularReader::next()
{
    mCurr++;
    mFreeSpace++;
    if (mCurr >= mBufferEnd) {
        mCurr = mBuffer;
    }
}

InputEventCircularReader 提供了fill,和 readEvent函数;

AccelSensor中的readEvents函数是使用它们来完成;以下是 readEvents的实现,这也是 读取HAL读取event data的最终实现的部分;

int AccelSensor::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;
    }
    if (mHasPendingMetadata) {
        mHasPendingMetadata--;
        meta_data.timestamp = getTimestamp();
        *data = meta_data;
        return mEnabled ? 1 : 0;
    }
    ssize_t n = mInputReader.fill(data_fd);
    if (n < 0)
        return n;
    int numEventReceived = 0;
    input_event const* event;
#if FETCH_FULL_EVENT_BEFORE_RETURN
again:
#endif
    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.data[0] = value * CONVERT_ACCEL_X;
            } else if (event->code == EVENT_TYPE_ACCEL_Y) {
                mPendingEvent.data[1] = value * CONVERT_ACCEL_Y;
            } else if (event->code == EVENT_TYPE_ACCEL_Z) {
                mPendingEvent.data[2] = value * CONVERT_ACCEL_Z;
            }
        } else if (type == EV_SYN) {
            switch (event->code){
                case SYN_TIME_SEC:
                    {
                        mUseAbsTimeStamp = true;
                        report_time = event->value*1000000000LL;
                    }
                    break;
                case SYN_TIME_NSEC:
                    {
                        mUseAbsTimeStamp = true;
                        mPendingEvent.timestamp = report_time+event->value;
                    }
                    break;
                case SYN_REPORT:
                    {
                        if(mUseAbsTimeStamp != true) {
                            mPendingEvent.timestamp = timevalToNano(event->time);
                        }
                        mPendingEvent.timestamp -= sysclk_sync_offset;
                        if (mEnabled) {
                            *data++ = mPendingEvent;
                            numEventReceived++;
                            count--;
                        }
                    }
                    break;
            }
        } else {
            ALOGE("AccelSensor: unknown event (type=%d, code=%d)",
                    type, event->code);
        }
        mInputReader.next();
    }
#if FETCH_FULL_EVENT_BEFORE_RETURN
    /* if we didn't read a complete event, see if we can fill and
       try again instead of returning with nothing and redoing poll. */
    if (numEventReceived == 0 && mEnabled == 1) {
        n = mInputReader.fill(data_fd);
        if (n)
            goto again;
    }
#endif
    return numEventReceived;
}
posted @ 2021-07-15 13:46  yujixuan  阅读(405)  评论(0编辑  收藏  举报