Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7d290174 authored by Dan Stoza's avatar Dan Stoza
Browse files

libgui: Make BitTube Parcelable and use unique_fd

This change completes the Parcelable interface for BitTube (it was
semi-Parcelable before as it implemented writeToParcel, but this adds
the complementary readFromParcel).

It also changes the send and receive file descriptors from ints to
android::base::unique_fds, which simplifies some of their lifecycle
management.

Finally, it changes the default constructor to leave the class
uninitialized, adding a BitTube(BitTube::DefaultSize) constructor to
replace that functionality (and paving the way for the ability to
default-construct a BitTube prior to readFromParcel'ing into it).

Test: m -j + manual testing
Change-Id: Ib0cba4c7c443b449a9a1837f07f7334395d4f10d
parent 27c81155
Loading
Loading
Loading
Loading
+20 −22
Original line number Diff line number Diff line
@@ -34,26 +34,14 @@ namespace gui {
// need. So we make it smaller.
static const size_t DEFAULT_SOCKET_BUFFER_SIZE = 4 * 1024;

BitTube::BitTube() : mSendFd(-1), mReceiveFd(-1) {
    init(DEFAULT_SOCKET_BUFFER_SIZE, DEFAULT_SOCKET_BUFFER_SIZE);
}

BitTube::BitTube(size_t bufsize) : mSendFd(-1), mReceiveFd(-1) {
BitTube::BitTube(size_t bufsize) {
    init(bufsize, bufsize);
}

BitTube::BitTube(const Parcel& data) : mSendFd(-1), mReceiveFd(-1) {
    mReceiveFd = dup(data.readFileDescriptor());
    if (mReceiveFd < 0) {
        mReceiveFd = -errno;
        ALOGE("BitTube(Parcel): can't dup filedescriptor (%s)", strerror(-mReceiveFd));
    }
}

BitTube::~BitTube() {
    if (mSendFd >= 0) close(mSendFd);
BitTube::BitTube(DefaultSizeType) : BitTube(DEFAULT_SOCKET_BUFFER_SIZE) {}

    if (mReceiveFd >= 0) close(mReceiveFd);
BitTube::BitTube(const Parcel& data) {
    readFromParcel(&data);
}

void BitTube::init(size_t rcvbuf, size_t sndbuf) {
@@ -67,11 +55,11 @@ void BitTube::init(size_t rcvbuf, size_t sndbuf) {
        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];
        mReceiveFd.reset(sockets[0]);
        mSendFd.reset(sockets[1]);
    } else {
        mReceiveFd = -errno;
        ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));
        mReceiveFd.reset();
        ALOGE("BitTube: pipe creation failed (%s)", strerror(errno));
    }
}

@@ -118,11 +106,21 @@ status_t BitTube::writeToParcel(Parcel* reply) const {
    if (mReceiveFd < 0) return -EINVAL;

    status_t result = reply->writeDupFileDescriptor(mReceiveFd);
    close(mReceiveFd);
    mReceiveFd = -1;
    mReceiveFd.reset();
    return result;
}

status_t BitTube::readFromParcel(const Parcel* parcel) {
    mReceiveFd.reset(dup(parcel->readFileDescriptor()));
    if (mReceiveFd < 0) {
        mReceiveFd.reset();
        int error = errno;
        ALOGE("BitTube::readFromParcel: can't dup file descriptor (%s)", strerror(error));
        return -error;
    }
    return NO_ERROR;
}

ssize_t BitTube::sendObjects(const sp<BitTube>& tube, void const* events, size_t count,
                             size_t objSize) {
    const char* vaddr = reinterpret_cast<const char*>(events);
+16 −7
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@
#include <sys/types.h>

#include <android/log.h>
#include <android-base/unique_fd.h>
#include <binder/Parcelable.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>

@@ -29,16 +31,22 @@ class Parcel;

namespace gui {

class BitTube : public RefBase {
class BitTube : public RefBase, public Parcelable {
public:
    // creates a BitTube with a default (4KB) send buffer
    BitTube();
    // creates an uninitialized BitTube (to unparcel into)
    BitTube() = default;

    // creates a BitTube with a a specified send and receive buffer size
    explicit BitTube(size_t bufsize);

    // creates a BitTube with a default (4KB) send buffer
    struct DefaultSizeType {};
    static constexpr DefaultSizeType DefaultSize{};
    explicit BitTube(DefaultSizeType);

    explicit BitTube(const Parcel& data);
    virtual ~BitTube();

    virtual ~BitTube() = default;

    // check state after construction
    status_t initCheck() const;
@@ -62,8 +70,9 @@ public:
        return recvObjects(tube, events, count, sizeof(T));
    }

    // parcels this BitTube
    // implement the Parcelable protocol. Only parcels the receive file descriptor
    status_t writeToParcel(Parcel* reply) const;
    status_t readFromParcel(const Parcel* parcel);

private:
    void init(size_t rcvbuf, size_t sndbuf);
@@ -75,8 +84,8 @@ private:
    // the message, excess data is silently discarded.
    ssize_t read(void* vaddr, size_t size);

    int mSendFd;
    mutable int mReceiveFd;
    base::unique_fd mSendFd;
    mutable base::unique_fd mReceiveFd;

    static ssize_t sendObjects(const sp<BitTube>& tube, void const* events, size_t count,
                               size_t objSize);
+1 −1
Original line number Diff line number Diff line
@@ -389,7 +389,7 @@ void EventThread::dump(String8& result) const {

EventThread::Connection::Connection(
        const sp<EventThread>& eventThread)
    : count(-1), mEventThread(eventThread), mChannel(new gui::BitTube())
    : count(-1), mEventThread(eventThread), mChannel(new gui::BitTube(gui::BitTube::DefaultSize))
{
}