Sensor框架Framework层解读 - 图文(7)

2019-08-30 22:56

sp SensorManager::createEventQueue() {

sp queue; Mutex::Autolock _l(mLock);

while (assertStateLocked() == NO_ERROR) { //创建连接接口

sp connection =

mSensorServer->createSensorEventConnection(); if (connection == NULL) {

// SensorService just died.

LOGE(\SensorService died.\

continue; }

//创建消息队列

queue = new SensorEventQueue(connection); break; }

return queue; }

View Code

客户端与服务器创建一个SensorEventConnection连接接口,而一个消息队列中包含一个连接接口。

创建连接接口:

sp

SensorService::createSensorEventConnection()

{

sp result(new SensorEventConnection(this));

return result; }

SensorService::SensorEventConnection::SensorEventConnection( const sp& service)

: mService(service), mChannel(new BitTube ()) { }

View Code

关键在于BitTube,在构造函数中创建了管道:

BitTube::BitTube()

: mSendFd(-1), mReceiveFd(-1) {

int sockets[2];

if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) { int size = SOCKET_BUFFER_SIZE;

setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));

setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));

setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));

setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));

fcntl(sockets[0], F_SETFL, O_NONBLOCK); fcntl(sockets[1], F_SETFL, O_NONBLOCK); mReceiveFd = sockets[0]; mSendFd = sockets[1]; } else {

mReceiveFd = -errno;

ALOGE(\strerror(-mReceiveFd));

} }

View Code

其中:fds[0]就是对应的mReceiveFd,是管道的读端,sensor数据的读取端,对应的是客户端进程访问的。

fds[1]就是对应mSendFd,是管道的写端,sensor数据写入端,是sensor的服务进程访问的一端。 通过pipe(fds)创建管道,通过fcntl来设置操作管道的方式,设置通道两端的操作方式为O_NONBLOCK ,非阻塞IO方式,read或write调用返回-1和EAGAIN错误。

总结下消息队列

客户端第一次注册监听器的时候,就需要创建一个消息队列,客户端创了SensorThread线程从消息队列里面读取数据。

SensorEventQueue中有一个SensorEventConnection实例的引用,SensorEventConnection中有一个BitTube实例的引用。

使能Sensor

客户端创建了连接接口SensorEventConnection后,可以调用其方法使能Sensor传感器:

status_t SensorService::SensorEventConnection::enableDisable( int handle, bool enabled) {

status_t err; if (enabled) {

err = mService->enable(this, handle); } else {

err = mService->disable(this, handle); }

return err; }

View Code

handle对应着Sensor传感器的句柄

服务端往管道写数据

bool SensorService::threadLoop() {

…… do {

count = device.poll(buffer, numEventMax);

recordLastValue(buffer, count); ……

// send our events to clients...

const SortedVector< wp > activeConnections(

getActiveConnections());

size_t numConnections = activeConnections.size(); for (size_t i=0 ; i connection( activeConnections[i].promote()); if (connection != 0) {

connection->sendEvents(buffer, count, scratch); } }

} while (count >= 0 || Thread::exitPending()); return false; }

View Code

前面介绍过,在SensorService中,创建了一个线程不断从HAL层读取Sensor数据,就是在threadLoop方法中。

关键在与下面了一个for循环,其实是扫描有多少个客户端连接接口,然后就往没每个连接的管道中写数据。

status_t SensorService::SensorEventConnection::sendEvents( sensors_event_t const* buffer, size_t numEvents, sensors_event_t* scratch) {

// filter out events not for this connection size_t count = 0; if (scratch) { …… } ……

if (count == 0) return 0;

ssize_t size = mChannel->write(scratch, count*sizeof(sensors_event_t));

…… }

View Code

调用该连接接口的BitTube::write():

ssize_t BitTube::write(void const* vaddr, size_t size) {

ssize_t err, len; do {

len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);

err = len < 0 ? errno : 0; } while (err == EINTR);

return err == 0 ? len : -err; } }

View Code

到此,服务端就完成了往管道的写端写入数据。

客户端读管道数据

时序图

ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents)

{

return BitTube::recvObjects(mSensorChannel, events, numEvents); }

View Code

调用到了BitTube::read():

static ssize_t recvObjects(const sp& tube, T* events, size_t count) {

return recvObjects(tube, events, count, sizeof(T)); }

ssize_t BitTube::recvObjects(const sp& tube, void* events, size_t count, size_t objSize) {

ssize_t numObjects = 0;

for (size_t i=0 ; i

char* vaddr = reinterpret_cast(events) + objSize * i; ssize_t size = tube->read(vaddr, objSize); if (size < 0) {

// error occurred return size;

} else if (size == 0) { // no more messages break; }

numObjects++; }

return numObjects; }

ssize_t BitTube::read(void* vaddr, size_t size) {

ssize_t err, len; do {

len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT); err = len < 0 ? errno : 0; } while (err == EINTR);

if (err == EAGAIN || err == EWOULDBLOCK) { return 0; }

return err == 0 ? len : -err; }

View Code


Sensor框架Framework层解读 - 图文(7).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:注册分类1、2、3、5.1类申报资料要求(试行)

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: