android sensor

这篇博客深入探讨了Android系统的传感器框架,从驱动层的上报机制,到HAL层的接口定义,再到SensorService的服务端处理和InputEventCircularReader的事件循环缓冲机制,详细阐述了Android设备如何管理和处理传感器数据。
摘要由CSDN通过智能技术生成
驱动层

上报

input_report_abs(...,ABS_X,...);
input_report_rel(..., REL_X, ...);
input_report_key(..., KEY_XXX, 0/1);
HAL

定义XXXSensor, ID_XXX,SENSOR_TYPE_XXX

class XXXSensor : public SensorBase {
public:
    XXXSensor();
    virtual ~XXXSensor();
    virtual int setDelay(int32_t handle, int64_t ns);
    virtual int setEnable(int32_t handle, int enabled);
    virtual int readEvents(sensors_event_t* data, int count);
    void processEvent(int code, int value);

private:
        int mEnabled;
        int mPendingMask;
        InputEventCircularReader mInputReader;
        sensors_event_t mPendingEvent;    //临时存放的event
};
XXXSensor::XXXSensor()
        : SensorBase(NULL, OFN_DATA_NAME),
        mEnabled(0),        
        mInputReader(4),
        mPendingMask(0)
{
        memset(&mPendingEvent, 0, sizeof(mPendingEvent));

        mPendingEvent.sensor  = ID_XXX;
        mPendingEvent.type    = SENSOR_TYPE_XXX;
        mPendingEvent.version = sizeof(sensors_event_t);
}
int XXXSensor::readEvents(sensors_event_t* data, int count)
{
		//读取fd,放入缓冲中
        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_REL) {
						mPendingMask = 1 ;
        				mPendingEvent.xxx =value;

                        mInputReader.next();
                } else if (type == EV_SYN) {
                        int64_t time = timevalToNano(event->time);
                        if (mPendingMask) {
                                mPendingMask = 0;
                                mPendingEvent.timestamp = time;
                                *data++ = mPendingEvent;
                                 count--;
                                 numEventReceived++;
                        }
                        
                        if (!mPendingMask) {
                                mInputReader.next();
                        }
                } else {
                        mInputReader.next();
                }
        }

        return numEventReceived;
}
//sensors_event_t 存放sensor的实际的数据
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;

            /* 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;
    };
    uint32_t reserved1[4];
} sensors_event_t;

SensorBase

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

//根据deviceName找到对应的dev/input/event* ,
/dev/input # ls
event0
event1
event2
event3
event4
mice

int SensorBase::openInput(const char* inputName) {
        int fd = -1;
        int input_id = -1;
        const char *dirname = "/dev/input";
        const char *inputsysfs = "/sys/class/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];
			//通过ioctl命令EVIOCGNAME,能获取dev/input/event*对应的Device Name
                        if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
                                name[0] = '\0';
                        }
                        if (!strcmp(name, inputName)) {

                                break;
                        } else {
                                close(fd);
                                fd = -1;
                        }
                }
        }

        closedir(dir);
        return fd;
}

  • sensor集合在一起sensors
static int sensors__get_sensors_list(struct sensors_module_t* module,
        struct sensor_t const** list)
{
    int a = 0;
    *list = sSensorList;
    a = ARRAY_SIZE(sSensorList);

#ifdef DEBUG_SENSOR
    ALOGD("sNumber:%d, a:%d\n", sNumber, a);
#endif
    return sNumber;
}
// //hal module的method接口
static struct hw_module_methods_t sensors_module_methods = {
open: open_sensors    
};

struct sensors_module_t HAL_MODULE_INFO_SYM = {
common: {
tag: HARDWARE_MODULE_TAG,
     version_major: 1,
     version_minor: 1,
     id: SENSORS_HARDWARE_MODULE_ID,
     name: "Sensor module",
     author: "Freescale Semiconductor Inc.",
     methods: &sensors_module_methods,   // hal module的method接口
     dso : NULL,
     reserved : {},
        },
 //HAL 扩展接口
get_sensors_list: sensors__get_sensors_list,
};

static int open_sensors(const struct hw_module_t* module, const char* id,
                        struct hw_device_t** device)
{
        int status = -EINVAL;

        sensors_poll_context_t *dev = new sensors_poll_context_t();
        memset(&dev->device, 0, sizeof(sensors_poll_device_t));

        dev->device.common.tag = HARDWARE_DEVICE_TAG;
        dev->device.common.version  = 0;
        dev->device.common.module   = const_cast<hw_module_t*>(module);
        dev->device.common.close    = poll__close;
        dev->device.activate        = poll__activate;    //sensor集合的active接口
        dev->device.setDelay        = poll__setDelay;
        dev->device.poll            = poll__poll;        //sensor集合的poll接口

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

        return status;
}

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 pollEvents(sensors_event_t* data, int count);

    private:
    int accel;
    int mag;
    int gyro;
    int light;
    int proximity;
    int orn;
    int temperature ;
    int press;

    static const size_t wake = 10;
    static const char WAKE_MESSAGE = 'W';
    struct pollfd mPollFds[11];
    int mWritePipeFd;
    SensorBase* mSensors[10];
    ...
}
   int first = -1;
    

    if((seStatus[ID_A].isUsed == true) && (seStatus[ID_A].isFound == true)) {
        first = first + 1;
        accel = first;
        mSensors[first] = new AccelSensor();
        //fd 需要加入到mPollFds里面,将来poll , fd就是/dev/input/eventx的句柄
        mPollFds[first].fd = mSensors[accel]->getFd();
        //POLLIN事件
        mPollFds[first].events = POLLIN;
        mPollFds[first].revents = 0;
    }
   if((seStatus[ID_L].isUsed == true) && (seStatus[ID_L].isFound == true)) {
        first = first + 1;
        light = first;
        mSensors[first] = new LightSensor();
        mPollFds[first].fd = mSensors[light]->getFd();
        mPollFds[first].events = POLLIN;
        mPollFds[first].revents = 0;
    }

	...
	//所有sensor之后加一个wake event
	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;
}
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 < sNumber) ; i++) {
            SensorBase* const sensor(mSensors[i]);
            if ((mPollFds[i].revents & POLLIN) || (sensor->hasPendingEvents())) {
				//读取pending events
                int nb = sensor->readEvents(data, count);
                if (nb < count) {
                    // no more data for this sensor
                    mPollFds[i].revents = 0;
                }
                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);
            //阻塞查询pollfd
            do {
                n = poll(mPollFds, sNumber, nbEvents ? 0 : -1);
            } while (n < 0 && errno == EINTR);
						//错误
            			if (n<0) {
                			ALOGE("poll() failed (%s)", strerror(errno));
                			return -errno;
                        }
                       
                       	//wake event
                        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;
}

SensorService

native/services/sensorservice

 CorrectedGyroSensor.cpp  Fusion.h           LinearAccelerationSensor.cpp  mat.h                  quat.h                    SensorDevice.cpp  SensorFusion.h       SensorService.cpp  traits.h
BatteryService.cpp  CorrectedGyroSensor.h    GravitySensor.cpp  LinearAccelerationSensor.h    OrientationSensor.cpp  RotationVectorSensor.cpp  SensorDevice.h    SensorInterface.cpp  SensorService.h    vec.h
BatteryService.h    Fusion.cpp               GravitySensor.h    main_sensorservice.cpp        OrientationSensor.h    RotationVectorSensor.h    SensorFusion.cpp  SensorInterface.h    tests

服务端

int main(int /*argc*/, char** /*argv*/) {
    SensorService::publishAndJoinThreadPool();
    return 0;
}
class SensorService :
        public BinderService<SensorService>,
        public BnSensorServer,
        protected Thread
{
}

SensorDevice

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

    if (mSensorModule) {
        err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
  ...
            sensor_t const* list;
            ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
            mActivationCount.setCapacity(count);
            Info model;
            //loop所有的sensor enable
            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);
            }
	}
}
//封装poll接口
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;
}

SensorService

status_t SensorService::enable(const sp& connection,

        int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,

        const String16& opPackageName) {

     connection->addSensor(handle));


            mActiveConnections.add(connection);
       ......

    return err;

}
public boolean addSensor(

            Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {
            addSensorEvent(sensor);
          enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0);

    }
private int enableSensor(

        Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
  
    return nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs,

            maxBatchReportLatencyUs);

}
status_t SensorService::SensorEventConnection::enableDisable(

        int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,

        int reservedFlags)

{
 

    if (enabled) {
        //打开
        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
                               reservedFlags, mOpPackageName);
        }
    } else {
        err = mService->disable(this, handle);
    }

    return err;

}

bool SensorService::threadLoop() {

     do {
		//mSensorEventBuffer就是 sensors_event_t结构
        ssize_t count = device.poll(mSensorEventBuffer, numEventMax);

        ........

        size_t numConnections = activeConnections.size();

        for (size_t i=0 ; i < numConnections; ++i) {

            if (activeConnections[i] != 0) {

                // 遍历所有的mActiveConnections, 调用sendEvents发送数据
                activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
                        mMapFlushEventsToConnections);

    } while (!Thread::exitPending());

}
status_t SensorService::SensorEventConnection::sendEvents(
        sensors_event_t const* buffer, size_t numEvents,
        sensors_event_t* scratch,
        SensorEventConnection const * const * mapFlushEventsToConnections) {
        ...
    ssize_t size = SensorEventQueue::write(mChannel,
                                    reinterpret_cast<ASensorEvent const*>(scratch), count);
      
}
sp SensorService::createSensorEventConnection(const String8& packageName,

        int requestedMode, const String16& opPackageName) {

    sp result(new SensorEventConnection(this, uid, connPackageName,
            requestedMode == DATA_INJECTION, connOpPackageName, hasSensorAccess));

            mActiveConnections.add(result);
    }

    return result;

}

SensorEventQueue : ALooper

struct ASensorEventQueue {
    ALooper* looper;
};
class SensorEventQueue : public ASensorEventQueue, public RefBase{
...
}

ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
        ASensorEvent const* events, size_t numEvents) {
    return BitTube::sendObjects(tube, events, numEvents);
}


**客户端**
1 .registerListener
```c

Sensor orientationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);// NO.1 获取sensor

sensorManager.registerListener(sensorEventListener, orientationSensor, SensorManager.SENSOR_DELAY_NORMAL);
  1. registerListenerImpl
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,

           int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {


       synchronized (mSensorListeners) {

                 // 新建一个SensorEventQueue

               queue = new SensorEventQueue(listener, looper, this, fullClassName);

               //  添加sennsor

               queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);

               // 将listener放入缓存

               mSensorListeners.put(listener, queue);
       }

   }
static final class SensorEventQueue extends BaseEventQueue {

        private final SensorEventListener mListener;

        private final SparseArray mSensorsEvents = new SparseArray();

        public SensorEventQueue(SensorEventListener listener, Looper looper,

                SystemSensorManager manager, String packageName) {

        }

        @Override

        public void addSensorEvent(Sensor sensor) {

            SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor,

                    mManager.mTargetSdkLevel));

            synchronized (mSensorsEvents) {

                mSensorsEvents.put(sensor.getHandle(), t);

            }

        }
        ......

  
        @Override
        protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
                long timestamp) {
            final Sensor sensor = mManager.mHandleToSensor.get(handle);
            if (sensor == null) {
                // sensor disconnected
                return;
            }

             SensorEvent t = null;
            synchronized (mSensorsEvents) {
                t = mSensorsEvents.get(handle);
            }

             mListener.onAccuracyChanged(t.sensor, t.accuracy);
            mListener.onSensorChanged(t);

        }
        ......
    }

BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) {

             mNativeSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance,
                    new WeakReference<>(this), looper.getQueue(),
                    packageName, mode, manager.mContext.getOpPackageName());


        }
static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
        jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) {
    SensorManager* mgr = reinterpret_cast(sensorManager);
    sp queue(mgr->createEventQueue(clientName, mode));

    //取得java层的messageQueue
    sp messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);

    //eventQWeak回调java层的dispatchSensorEvent
    sp receiver = new Receiver(queue, messageQueue, eventQWeak);
    return jlong(receiver.get());
}
sp SensorManager::createEventQueue(String8 packageName, int mode) {

    sp queue;
        sp connection = mSensorServer->createSensorEventConnection(packageName, mode, mOpPackageName);
        queue = new SensorEventQueue(connection);

    return queue;
}
class Receiver : public LooperCallback {

    sp mSensorQueue;
    sp mMessageQueue;

public:
    Receiver(const sp& sensorQueue,
            const sp& messageQueue,
            jobject receiverWeak) {
    }
    ......

    virtual int handleEvent(int fd, int events, void* data) {
         ASensorEvent buffer[16];
        while ((n = q->read(buffer, 16)) > 0) {
                      if (receiverObj.get()) {
                        // 回调dispatchSensorEvent
                        env->CallVoidMethod(receiverObj.get(),                                            gBaseEventQueueClassInfo.dispatchSensorEvent,
                                            buffer[i].sensor,
                                            mFloatScratch,
                                            status,
                                            buffer[i].timestamp);
                    }

                }

};
InputEventCircularReader

Event循环缓冲
kernel的接口

struct input_event {
 struct timeval time;
 __u16 type;
 __u16 code;
 __s32 value;
};

struct input_event;

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

InputEventCircularReader::~InputEventCircularReader()
{
        delete [] mBuffer;
}
//读取fd,存储到循环缓冲中
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;
        }
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值