Loading include/gui/BitTube.h +19 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <utils/Errors.h> #include <utils/RefBase.h> #include <cutils/log.h> namespace android { Loading @@ -43,9 +44,27 @@ public: status_t writeToParcel(Parcel* reply) const; template <typename T> static ssize_t sendObjects(const sp<BitTube>& tube, T const* events, size_t count) { return sendObjects(tube, events, count, sizeof(T)); } template <typename T> static ssize_t recvObjects(const sp<BitTube>& tube, T* events, size_t count) { return recvObjects(tube, events, count, sizeof(T)); } private: int mSendFd; mutable int mReceiveFd; static ssize_t sendObjects(const sp<BitTube>& tube, void const* events, size_t count, size_t objSize); static ssize_t recvObjects(const sp<BitTube>& tube, void* events, size_t count, size_t objSize); }; // ---------------------------------------------------------------------------- Loading include/gui/DisplayEventReceiver.h +8 −1 Original line number Diff line number Diff line Loading @@ -89,7 +89,7 @@ public: int getFd() const; /* * getEvents reads event from the queue and returns how many events were * getEvents reads events from the queue and returns how many events were * read. Returns 0 if there are no more events or a negative error code. * If NOT_ENOUGH_DATA is returned, the object has become invalid forever, it * should be destroyed and getEvents() shouldn't be called again. Loading @@ -98,6 +98,13 @@ public: static ssize_t getEvents(const sp<BitTube>& dataChannel, Event* events, size_t count); /* * sendEvents write events to the queue and returns how many events were * written. */ static ssize_t sendEvents(const sp<BitTube>& dataChannel, Event const* events, size_t count); /* * setVsyncRate() sets the Event::VSync delivery rate. A value of * 1 returns every Event::VSync. A value of 2 returns every other event, Loading include/gui/SensorEventQueue.h +4 −1 Original line number Diff line number Diff line Loading @@ -54,7 +54,10 @@ public: virtual void onFirstRef(); int getFd() const; ssize_t write(ASensorEvent const* events, size_t numEvents); static ssize_t write(const sp<BitTube>& tube, ASensorEvent const* events, size_t numEvents); ssize_t read(ASensorEvent* events, size_t numEvents); status_t waitForEvent() const; Loading libs/gui/BitTube.cpp +63 −11 Original line number Diff line number Diff line Loading @@ -16,9 +16,9 @@ #include <stdint.h> #include <sys/types.h> #include <sys/socket.h> #include <fcntl.h> #include <signal.h> #include <unistd.h> #include <utils/Errors.h> Loading @@ -30,17 +30,25 @@ namespace android { // ---------------------------------------------------------------------------- // Socket buffer size. The default is typically about 128KB, which is much larger than // we really need. So we make it smaller. static const size_t SOCKET_BUFFER_SIZE = 4 * 1024; BitTube::BitTube() : mSendFd(-1), mReceiveFd(-1) { int fds[2]; if (pipe(fds) == 0) { mReceiveFd = fds[0]; mSendFd = fds[1]; fcntl(mReceiveFd, F_SETFL, O_NONBLOCK); fcntl(mSendFd, F_SETFL, O_NONBLOCK); // ignore SIGPIPE, we handle write errors through EPIPE instead signal(SIGPIPE, SIG_IGN); 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("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd)); Loading @@ -52,6 +60,9 @@ BitTube::BitTube(const Parcel& data) { mReceiveFd = dup(data.readFileDescriptor()); if (mReceiveFd >= 0) { int size = SOCKET_BUFFER_SIZE; setsockopt(mReceiveFd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); setsockopt(mReceiveFd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); fcntl(mReceiveFd, F_SETFL, O_NONBLOCK); } else { mReceiveFd = -errno; Loading Loading @@ -86,7 +97,7 @@ ssize_t BitTube::write(void const* vaddr, size_t size) { ssize_t err, len; do { len = ::write(mSendFd, vaddr, size); len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL); err = len < 0 ? errno : 0; } while (err == EINTR); return err == 0 ? len : -err; Loading @@ -97,7 +108,7 @@ ssize_t BitTube::read(void* vaddr, size_t size) { ssize_t err, len; do { len = ::read(mReceiveFd, vaddr, size); len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT); err = len < 0 ? errno : 0; } while (err == EINTR); if (err == EAGAIN || err == EWOULDBLOCK) { Loading @@ -119,5 +130,46 @@ status_t BitTube::writeToParcel(Parcel* reply) const return result; } ssize_t BitTube::sendObjects(const sp<BitTube>& tube, void const* events, size_t count, size_t objSize) { ssize_t numObjects = 0; for (size_t i=0 ; i<count ; i++) { const char* vaddr = reinterpret_cast<const char*>(events) + objSize * i; ssize_t size = tube->write(vaddr, objSize); if (size < 0) { // error occurred numObjects = -size; break; } else if (size == 0) { // no more space break; } numObjects++; } return numObjects; } ssize_t BitTube::recvObjects(const sp<BitTube>& tube, void* events, size_t count, size_t objSize) { ssize_t numObjects = 0; for (size_t i=0 ; i<count ; i++) { char* vaddr = reinterpret_cast<char*>(events) + objSize * i; ssize_t size = tube->read(vaddr, objSize); if (size < 0) { // error occurred numObjects = -size; break; } else if (size == 0) { // no more messages break; } numObjects++; } return numObjects; } // ---------------------------------------------------------------------------- }; // namespace android libs/gui/DisplayEventReceiver.cpp +7 −16 Original line number Diff line number Diff line Loading @@ -85,22 +85,13 @@ ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events, ssize_t DisplayEventReceiver::getEvents(const sp<BitTube>& dataChannel, Event* events, size_t count) { ssize_t size = dataChannel->read(events, sizeof(events[0])*count); ALOGE_IF(size<0, "DisplayEventReceiver::getEvents error (%s)", strerror(-size)); if (size >= 0) { // Note: if (size % sizeof(events[0])) != 0, we've got a // partial read. This can happen if the queue filed up (ie: if we // didn't pull from it fast enough). // We discard the partial event and rely on the sender to // re-send the event if appropriate (some events, like VSYNC // can be lost forever). // returns number of events read size /= sizeof(events[0]); return BitTube::recvObjects(dataChannel, events, count); } return size; ssize_t DisplayEventReceiver::sendEvents(const sp<BitTube>& dataChannel, Event const* events, size_t count) { return BitTube::sendObjects(dataChannel, events, count); } // --------------------------------------------------------------------------- Loading Loading
include/gui/BitTube.h +19 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <utils/Errors.h> #include <utils/RefBase.h> #include <cutils/log.h> namespace android { Loading @@ -43,9 +44,27 @@ public: status_t writeToParcel(Parcel* reply) const; template <typename T> static ssize_t sendObjects(const sp<BitTube>& tube, T const* events, size_t count) { return sendObjects(tube, events, count, sizeof(T)); } template <typename T> static ssize_t recvObjects(const sp<BitTube>& tube, T* events, size_t count) { return recvObjects(tube, events, count, sizeof(T)); } private: int mSendFd; mutable int mReceiveFd; static ssize_t sendObjects(const sp<BitTube>& tube, void const* events, size_t count, size_t objSize); static ssize_t recvObjects(const sp<BitTube>& tube, void* events, size_t count, size_t objSize); }; // ---------------------------------------------------------------------------- Loading
include/gui/DisplayEventReceiver.h +8 −1 Original line number Diff line number Diff line Loading @@ -89,7 +89,7 @@ public: int getFd() const; /* * getEvents reads event from the queue and returns how many events were * getEvents reads events from the queue and returns how many events were * read. Returns 0 if there are no more events or a negative error code. * If NOT_ENOUGH_DATA is returned, the object has become invalid forever, it * should be destroyed and getEvents() shouldn't be called again. Loading @@ -98,6 +98,13 @@ public: static ssize_t getEvents(const sp<BitTube>& dataChannel, Event* events, size_t count); /* * sendEvents write events to the queue and returns how many events were * written. */ static ssize_t sendEvents(const sp<BitTube>& dataChannel, Event const* events, size_t count); /* * setVsyncRate() sets the Event::VSync delivery rate. A value of * 1 returns every Event::VSync. A value of 2 returns every other event, Loading
include/gui/SensorEventQueue.h +4 −1 Original line number Diff line number Diff line Loading @@ -54,7 +54,10 @@ public: virtual void onFirstRef(); int getFd() const; ssize_t write(ASensorEvent const* events, size_t numEvents); static ssize_t write(const sp<BitTube>& tube, ASensorEvent const* events, size_t numEvents); ssize_t read(ASensorEvent* events, size_t numEvents); status_t waitForEvent() const; Loading
libs/gui/BitTube.cpp +63 −11 Original line number Diff line number Diff line Loading @@ -16,9 +16,9 @@ #include <stdint.h> #include <sys/types.h> #include <sys/socket.h> #include <fcntl.h> #include <signal.h> #include <unistd.h> #include <utils/Errors.h> Loading @@ -30,17 +30,25 @@ namespace android { // ---------------------------------------------------------------------------- // Socket buffer size. The default is typically about 128KB, which is much larger than // we really need. So we make it smaller. static const size_t SOCKET_BUFFER_SIZE = 4 * 1024; BitTube::BitTube() : mSendFd(-1), mReceiveFd(-1) { int fds[2]; if (pipe(fds) == 0) { mReceiveFd = fds[0]; mSendFd = fds[1]; fcntl(mReceiveFd, F_SETFL, O_NONBLOCK); fcntl(mSendFd, F_SETFL, O_NONBLOCK); // ignore SIGPIPE, we handle write errors through EPIPE instead signal(SIGPIPE, SIG_IGN); 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("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd)); Loading @@ -52,6 +60,9 @@ BitTube::BitTube(const Parcel& data) { mReceiveFd = dup(data.readFileDescriptor()); if (mReceiveFd >= 0) { int size = SOCKET_BUFFER_SIZE; setsockopt(mReceiveFd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); setsockopt(mReceiveFd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); fcntl(mReceiveFd, F_SETFL, O_NONBLOCK); } else { mReceiveFd = -errno; Loading Loading @@ -86,7 +97,7 @@ ssize_t BitTube::write(void const* vaddr, size_t size) { ssize_t err, len; do { len = ::write(mSendFd, vaddr, size); len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL); err = len < 0 ? errno : 0; } while (err == EINTR); return err == 0 ? len : -err; Loading @@ -97,7 +108,7 @@ ssize_t BitTube::read(void* vaddr, size_t size) { ssize_t err, len; do { len = ::read(mReceiveFd, vaddr, size); len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT); err = len < 0 ? errno : 0; } while (err == EINTR); if (err == EAGAIN || err == EWOULDBLOCK) { Loading @@ -119,5 +130,46 @@ status_t BitTube::writeToParcel(Parcel* reply) const return result; } ssize_t BitTube::sendObjects(const sp<BitTube>& tube, void const* events, size_t count, size_t objSize) { ssize_t numObjects = 0; for (size_t i=0 ; i<count ; i++) { const char* vaddr = reinterpret_cast<const char*>(events) + objSize * i; ssize_t size = tube->write(vaddr, objSize); if (size < 0) { // error occurred numObjects = -size; break; } else if (size == 0) { // no more space break; } numObjects++; } return numObjects; } ssize_t BitTube::recvObjects(const sp<BitTube>& tube, void* events, size_t count, size_t objSize) { ssize_t numObjects = 0; for (size_t i=0 ; i<count ; i++) { char* vaddr = reinterpret_cast<char*>(events) + objSize * i; ssize_t size = tube->read(vaddr, objSize); if (size < 0) { // error occurred numObjects = -size; break; } else if (size == 0) { // no more messages break; } numObjects++; } return numObjects; } // ---------------------------------------------------------------------------- }; // namespace android
libs/gui/DisplayEventReceiver.cpp +7 −16 Original line number Diff line number Diff line Loading @@ -85,22 +85,13 @@ ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events, ssize_t DisplayEventReceiver::getEvents(const sp<BitTube>& dataChannel, Event* events, size_t count) { ssize_t size = dataChannel->read(events, sizeof(events[0])*count); ALOGE_IF(size<0, "DisplayEventReceiver::getEvents error (%s)", strerror(-size)); if (size >= 0) { // Note: if (size % sizeof(events[0])) != 0, we've got a // partial read. This can happen if the queue filed up (ie: if we // didn't pull from it fast enough). // We discard the partial event and rely on the sender to // re-send the event if appropriate (some events, like VSYNC // can be lost forever). // returns number of events read size /= sizeof(events[0]); return BitTube::recvObjects(dataChannel, events, count); } return size; ssize_t DisplayEventReceiver::sendEvents(const sp<BitTube>& dataChannel, Event const* events, size_t count) { return BitTube::sendObjects(dataChannel, events, count); } // --------------------------------------------------------------------------- Loading