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

Commit c21947c2 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "InputTransport: store fd in a unique_fd."

parents 2852a2d6 2ccbe3a0
Loading
Loading
Loading
Loading
+7 −7
Original line number Original line Diff line number Diff line
@@ -42,6 +42,8 @@
#include <utils/Timers.h>
#include <utils/Timers.h>
#include <utils/Vector.h>
#include <utils/Vector.h>


#include <android-base/unique_fd.h>

namespace android {
namespace android {
class Parcel;
class Parcel;


@@ -166,8 +168,7 @@ protected:
    virtual ~InputChannel();
    virtual ~InputChannel();


public:
public:
    InputChannel() = default;
    static sp<InputChannel> create(const std::string& name, android::base::unique_fd fd);
    InputChannel(const std::string& name, int fd);


    /* Creates a pair of input channels.
    /* Creates a pair of input channels.
     *
     *
@@ -177,7 +178,7 @@ public:
            sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel);
            sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel);


    inline std::string getName() const { return mName; }
    inline std::string getName() const { return mName; }
    inline int getFd() const { return mFd; }
    inline int getFd() const { return mFd.get(); }


    /* Sends a message to the other endpoint.
    /* Sends a message to the other endpoint.
     *
     *
@@ -208,16 +209,15 @@ public:
    sp<InputChannel> dup() const;
    sp<InputChannel> dup() const;


    status_t write(Parcel& out) const;
    status_t write(Parcel& out) const;
    status_t read(const Parcel& from);
    static sp<InputChannel> read(const Parcel& from);


    sp<IBinder> getToken() const;
    sp<IBinder> getToken() const;
    void setToken(const sp<IBinder>& token);
    void setToken(const sp<IBinder>& token);


private:
private:
    void setFd(int fd);
    InputChannel(const std::string& name, android::base::unique_fd fd);

    std::string mName;
    std::string mName;
    int mFd = -1;
    android::base::unique_fd mFd;


    sp<IBinder> mToken = nullptr;
    sp<IBinder> mToken = nullptr;
};
};
+2 −4
Original line number Original line Diff line number Diff line
@@ -92,15 +92,13 @@ status_t BnInputFlinger::onTransact(
    }
    }
    case REGISTER_INPUT_CHANNEL_TRANSACTION: {
    case REGISTER_INPUT_CHANNEL_TRANSACTION: {
        CHECK_INTERFACE(IInputFlinger, data, reply);
        CHECK_INTERFACE(IInputFlinger, data, reply);
        sp<InputChannel> channel = new InputChannel();
        sp<InputChannel> channel = InputChannel::read(data);
        channel->read(data);
        registerInputChannel(channel);
        registerInputChannel(channel);
        break;
        break;
    }
    }
    case UNREGISTER_INPUT_CHANNEL_TRANSACTION: {
    case UNREGISTER_INPUT_CHANNEL_TRANSACTION: {
        CHECK_INTERFACE(IInputFlinger, data, reply);
        CHECK_INTERFACE(IInputFlinger, data, reply);
        sp<InputChannel> channel = new InputChannel();
        sp<InputChannel> channel = InputChannel::read(data);
        channel->read(data);
        unregisterInputChannel(channel);
        unregisterInputChannel(channel);
        break;
        break;
    }
    }
+43 −45
Original line number Original line Diff line number Diff line
@@ -227,35 +227,28 @@ void InputMessage::getSanitizedCopy(InputMessage* msg) const {


// --- InputChannel ---
// --- InputChannel ---


InputChannel::InputChannel(const std::string& name, int fd) :
sp<InputChannel> InputChannel::create(const std::string& name, android::base::unique_fd fd) {
        mName(name) {
    const int result = fcntl(fd, F_SETFL, O_NONBLOCK);
    if (result != 0) {
        LOG_ALWAYS_FATAL("channel '%s' ~ Could not make socket non-blocking: %s", name.c_str(),
                         strerror(errno));
        return nullptr;
    }
    return new InputChannel(name, std::move(fd));
}

InputChannel::InputChannel(const std::string& name, android::base::unique_fd fd)
      : mName(name), mFd(std::move(fd)) {
#if DEBUG_CHANNEL_LIFECYCLE
#if DEBUG_CHANNEL_LIFECYCLE
    ALOGD("Input channel constructed: name='%s', fd=%d",
    ALOGD("Input channel constructed: name='%s', fd=%d",
            mName.c_str(), fd);
            mName.c_str(), fd);
#endif
#endif

    setFd(fd);
}
}


InputChannel::~InputChannel() {
InputChannel::~InputChannel() {
#if DEBUG_CHANNEL_LIFECYCLE
#if DEBUG_CHANNEL_LIFECYCLE
    ALOGD("Input channel destroyed: name='%s', fd=%d",
    ALOGD("Input channel destroyed: name='%s', fd=%d", mName.c_str(), mFd.get());
            mName.c_str(), mFd);
#endif
#endif

    ::close(mFd);
}

void InputChannel::setFd(int fd) {
    if (mFd > 0) {
        ::close(mFd);
    }
    mFd = fd;
    if (mFd > 0) {
        int result = fcntl(mFd, F_SETFL, O_NONBLOCK);
        LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket "
            "non-blocking.  errno=%d", mName.c_str(), errno);
    }
}
}


status_t InputChannel::openInputChannelPair(const std::string& name,
status_t InputChannel::openInputChannelPair(const std::string& name,
@@ -276,13 +269,13 @@ status_t InputChannel::openInputChannelPair(const std::string& name,
    setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
    setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
    setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
    setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));


    std::string serverChannelName = name;
    std::string serverChannelName = name + " (server)";
    serverChannelName += " (server)";
    android::base::unique_fd serverFd(sockets[0]);
    outServerChannel = new InputChannel(serverChannelName, sockets[0]);
    outServerChannel = InputChannel::create(serverChannelName, std::move(serverFd));


    std::string clientChannelName = name;
    std::string clientChannelName = name + " (client)";
    clientChannelName += " (client)";
    android::base::unique_fd clientFd(sockets[1]);
    outClientChannel = new InputChannel(clientChannelName, sockets[1]);
    outClientChannel = InputChannel::create(clientChannelName, std::move(clientFd));
    return OK;
    return OK;
}
}


@@ -292,7 +285,7 @@ status_t InputChannel::sendMessage(const InputMessage* msg) {
    msg->getSanitizedCopy(&cleanMsg);
    msg->getSanitizedCopy(&cleanMsg);
    ssize_t nWrite;
    ssize_t nWrite;
    do {
    do {
        nWrite = ::send(mFd, &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
        nWrite = ::send(mFd.get(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
    } while (nWrite == -1 && errno == EINTR);
    } while (nWrite == -1 && errno == EINTR);


    if (nWrite < 0) {
    if (nWrite < 0) {
@@ -327,7 +320,7 @@ status_t InputChannel::sendMessage(const InputMessage* msg) {
status_t InputChannel::receiveMessage(InputMessage* msg) {
status_t InputChannel::receiveMessage(InputMessage* msg) {
    ssize_t nRead;
    ssize_t nRead;
    do {
    do {
        nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);
        nRead = ::recv(mFd.get(), msg, sizeof(InputMessage), MSG_DONTWAIT);
    } while (nRead == -1 && errno == EINTR);
    } while (nRead == -1 && errno == EINTR);


    if (nRead < 0) {
    if (nRead < 0) {
@@ -365,39 +358,44 @@ status_t InputChannel::receiveMessage(InputMessage* msg) {
}
}


sp<InputChannel> InputChannel::dup() const {
sp<InputChannel> InputChannel::dup() const {
    int fd = ::dup(getFd());
    android::base::unique_fd newFd(::dup(getFd()));
    return fd >= 0 ? new InputChannel(getName(), fd) : nullptr;
    if (!newFd.ok()) {
        ALOGE("Could not duplicate fd %i for channel %s: %s", getFd(), mName.c_str(),
              strerror(errno));
        return nullptr;
    }
    return InputChannel::create(mName, std::move(newFd));
}
}



status_t InputChannel::write(Parcel& out) const {
status_t InputChannel::write(Parcel& out) const {
    status_t s = out.writeString8(String8(getName().c_str()));
    status_t s = out.writeCString(getName().c_str());

    if (s != OK) {
    if (s != OK) {
        return s;
        return s;
    }
    }

    s = out.writeStrongBinder(mToken);
    s = out.writeStrongBinder(mToken);
    if (s != OK) {
    if (s != OK) {
        return s;
        return s;
    }
    }


    s = out.writeDupFileDescriptor(getFd());
    s = out.writeUniqueFileDescriptor(mFd);

    return s;
    return s;
}
}


status_t InputChannel::read(const Parcel& from) {
sp<InputChannel> InputChannel::read(const Parcel& from) {
    mName = from.readString8();
    std::string name = from.readCString();
    mToken = from.readStrongBinder();
    sp<IBinder> token = from.readStrongBinder();

    android::base::unique_fd rawFd;
    int rawFd = from.readFileDescriptor();
    status_t fdResult = from.readUniqueFileDescriptor(&rawFd);
    setFd(::dup(rawFd));
    if (fdResult != OK) {

        return nullptr;
    if (mFd < 0) {
        return BAD_VALUE;
    }
    }


    return OK;
    sp<InputChannel> channel = InputChannel::create(name, std::move(rawFd));
    if (channel != nullptr) {
        channel->setToken(token);
    }
    return channel;
}
}


sp<IBinder> InputChannel::getToken() const {
sp<IBinder> InputChannel::getToken() const {
+18 −9
Original line number Original line Diff line number Diff line
@@ -22,11 +22,12 @@
#include <time.h>
#include <time.h>
#include <errno.h>
#include <errno.h>


#include <binder/Binder.h>
#include <gtest/gtest.h>
#include <gtest/gtest.h>
#include <input/InputTransport.h>
#include <input/InputTransport.h>
#include <utils/Timers.h>
#include <utils/StopWatch.h>
#include <utils/StopWatch.h>
#include <utils/StrongPointer.h>
#include <utils/StrongPointer.h>
#include <utils/Timers.h>


namespace android {
namespace android {


@@ -43,20 +44,28 @@ TEST_F(InputChannelTest, ConstructorAndDestructor_TakesOwnershipOfFileDescriptor
    // of a pipe and to check for EPIPE on the other end after the channel is destroyed.
    // of a pipe and to check for EPIPE on the other end after the channel is destroyed.
    Pipe pipe;
    Pipe pipe;


    sp<InputChannel> inputChannel = new InputChannel("channel name", pipe.sendFd);
    android::base::unique_fd sendFd(pipe.sendFd);

    sp<InputChannel> inputChannel = InputChannel::create("channel name", std::move(sendFd));


    EXPECT_NE(inputChannel, nullptr) << "channel should be successfully created";
    EXPECT_STREQ("channel name", inputChannel->getName().c_str())
    EXPECT_STREQ("channel name", inputChannel->getName().c_str())
            << "channel should have provided name";
            << "channel should have provided name";
    EXPECT_EQ(pipe.sendFd, inputChannel->getFd())
    EXPECT_NE(-1, inputChannel->getFd()) << "channel should have valid fd";
            << "channel should have provided fd";


    inputChannel.clear(); // destroys input channel
    // InputChannel should be the owner of the file descriptor now
    ASSERT_FALSE(sendFd.ok());
}


    EXPECT_EQ(-EPIPE, pipe.readSignal())
TEST_F(InputChannelTest, SetAndGetToken) {
            << "channel should have closed fd when destroyed";
    Pipe pipe;
    sp<InputChannel> channel =
            InputChannel::create("test channel", android::base::unique_fd(pipe.sendFd));
    EXPECT_EQ(channel->getToken(), nullptr);


    // clean up fds of Pipe endpoints that were closed so we don't try to close them again
    sp<IBinder> token = new BBinder();
    pipe.sendFd = -1;
    channel->setToken(token);
    EXPECT_EQ(token, channel->getToken());
}
}


TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {
TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {