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

Commit 8911d46b authored by Steven Moreland's avatar Steven Moreland Committed by Gerrit Code Review
Browse files

Merge changes I44a66c3b,Ieb3273f0

* changes:
  Revert^2 "libbinder: binderRpcTest on host"
  Reland libbinder: vsock support for RPC
parents 520cc33d f6ec4632
Loading
Loading
Loading
Loading
+104 −54
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@


#include <binder/Parcel.h>
#include <binder/Parcel.h>
#include <binder/Stability.h>
#include <binder/Stability.h>
#include <utils/String8.h>


#include "RpcState.h"
#include "RpcState.h"
#include "RpcWireFormat.h"
#include "RpcWireFormat.h"
@@ -29,14 +30,20 @@
#include <sys/un.h>
#include <sys/un.h>
#include <unistd.h>
#include <unistd.h>


#if defined(__GLIBC__)
#ifdef __GLIBC__
extern "C" pid_t gettid();
extern "C" pid_t gettid();
#endif
#endif


#ifdef __BIONIC__
#include <linux/vm_sockets.h>
#endif

namespace android {
namespace android {


using base::unique_fd;
using base::unique_fd;


RpcConnection::SocketAddress::~SocketAddress() {}

RpcConnection::RpcConnection() {
RpcConnection::RpcConnection() {
    LOG_RPC_DETAIL("RpcConnection created %p", this);
    LOG_RPC_DETAIL("RpcConnection created %p", this);


@@ -50,65 +57,68 @@ sp<RpcConnection> RpcConnection::make() {
    return new RpcConnection;
    return new RpcConnection;
}
}


bool RpcConnection::setupUnixDomainServer(const char* path) {
class UnixSocketAddress : public RpcConnection::SocketAddress {
    LOG_ALWAYS_FATAL_IF(mServer.get() != -1, "Only supports one server now");
public:

    explicit UnixSocketAddress(const char* path) : mAddr({.sun_family = AF_UNIX}) {
    unique_fd serverFd(TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)));
        unsigned int pathLen = strlen(path) + 1;
    if (serverFd == -1) {
        LOG_ALWAYS_FATAL_IF(pathLen > sizeof(mAddr.sun_path), "%u %s", pathLen, path);
        ALOGE("Could not create socket at %s: %s", path, strerror(errno));
        memcpy(mAddr.sun_path, path, pathLen);
        return false;
    }
    virtual ~UnixSocketAddress() {}
    std::string toString() const override {
        return String8::format("path '%.*s'", static_cast<int>(sizeof(mAddr.sun_path)),
                               mAddr.sun_path)
                .c_str();
    }
    }
    const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); }
    size_t addrSize() const override { return sizeof(mAddr); }


    struct sockaddr_un addr = {
private:
            .sun_family = AF_UNIX,
    sockaddr_un mAddr;
};
};


    unsigned int pathLen = strlen(path) + 1;
bool RpcConnection::setupUnixDomainServer(const char* path) {
    LOG_ALWAYS_FATAL_IF(pathLen > sizeof(addr.sun_path), "%u", pathLen);
    return addServer(UnixSocketAddress(path));
    memcpy(addr.sun_path, path, pathLen);

    if (0 != TEMP_FAILURE_RETRY(bind(serverFd.get(), (struct sockaddr*)&addr, sizeof(addr)))) {
        ALOGE("Could not bind socket at %s: %s", path, strerror(errno));
        return false;
    }

    if (0 != TEMP_FAILURE_RETRY(listen(serverFd.get(), 1 /*backlog*/))) {
        ALOGE("Could not listen socket at %s: %s", path, strerror(errno));
        return false;
}
}


    mServer = std::move(serverFd);
bool RpcConnection::addUnixDomainClient(const char* path) {
    return true;
    return addClient(UnixSocketAddress(path));
}
}


bool RpcConnection::addUnixDomainClient(const char* path) {
#ifdef __BIONIC__
    LOG_RPC_DETAIL("Connecting on path: %s", path);


    unique_fd serverFd(TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)));
class VsockSocketAddress : public RpcConnection::SocketAddress {
    if (serverFd == -1) {
public:
        ALOGE("Could not create socket at %s: %s", path, strerror(errno));
    VsockSocketAddress(unsigned int cid, unsigned int port)
        return false;
          : mAddr({
                    .svm_family = AF_VSOCK,
                    .svm_port = port,
                    .svm_cid = cid,
            }) {}
    virtual ~VsockSocketAddress() {}
    std::string toString() const override {
        return String8::format("cid %du port %du", mAddr.svm_cid, mAddr.svm_port).c_str();
    }
    }
    const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); }
    size_t addrSize() const override { return sizeof(mAddr); }


    struct sockaddr_un addr = {
private:
            .sun_family = AF_UNIX,
    sockaddr_vm mAddr;
};
};


    unsigned int pathLen = strlen(path) + 1;
bool RpcConnection::setupVsockServer(unsigned int port) {
    LOG_ALWAYS_FATAL_IF(pathLen > sizeof(addr.sun_path), "%u", pathLen);
    // realizing value w/ this type at compile time to avoid ubsan abort
    memcpy(addr.sun_path, path, pathLen);
    constexpr unsigned int kAnyCid = VMADDR_CID_ANY;


    if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), (struct sockaddr*)&addr, sizeof(addr)))) {
    return addServer(VsockSocketAddress(kAnyCid, port));
        ALOGE("Could not connect socket at %s: %s", path, strerror(errno));
        return false;
}
}


    LOG_RPC_DETAIL("Unix domain client with fd %d", serverFd.get());
bool RpcConnection::addVsockClient(unsigned int cid, unsigned int port) {

    return addClient(VsockSocketAddress(cid, port));
    addClient(std::move(serverFd));
    return true;
}
}


#endif // __BIONIC__

sp<IBinder> RpcConnection::getRootObject() {
sp<IBinder> RpcConnection::getRootObject() {
    ExclusiveSocket socket(this, SocketUse::CLIENT);
    ExclusiveSocket socket(this, SocketUse::CLIENT);
    return state()->getRootObject(socket.fd(), this);
    return state()->getRootObject(socket.fd(), this);
@@ -130,11 +140,8 @@ status_t RpcConnection::sendDecStrong(const RpcAddress& address) {
void RpcConnection::join() {
void RpcConnection::join() {
    // establish a connection
    // establish a connection
    {
    {
        struct sockaddr_un clientSa;
        unique_fd clientFd(
        socklen_t clientSaLen = sizeof(clientSa);
                TEMP_FAILURE_RETRY(accept4(mServer.get(), nullptr, 0 /*length*/, SOCK_CLOEXEC)));

        unique_fd clientFd(TEMP_FAILURE_RETRY(
                accept4(mServer.get(), (struct sockaddr*)&clientSa, &clientSaLen, SOCK_CLOEXEC)));
        if (clientFd < 0) {
        if (clientFd < 0) {
            // If this log becomes confusing, should save more state from setupUnixDomainServer
            // If this log becomes confusing, should save more state from setupUnixDomainServer
            // in order to output here.
            // in order to output here.
@@ -144,7 +151,7 @@ void RpcConnection::join() {


        LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());
        LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());


        addServer(std::move(clientFd));
        assignServerToThisThread(std::move(clientFd));
    }
    }


    // We may not use the connection we just established (two threads might
    // We may not use the connection we just established (two threads might
@@ -170,14 +177,57 @@ wp<RpcServer> RpcConnection::server() {
    return mForServer;
    return mForServer;
}
}


void RpcConnection::addClient(base::unique_fd&& fd) {
bool RpcConnection::addServer(const SocketAddress& addr) {
    LOG_ALWAYS_FATAL_IF(mServer.get() != -1, "Each RpcConnection can only have one server.");

    unique_fd serverFd(
            TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
    if (serverFd == -1) {
        ALOGE("Could not create socket: %s", strerror(errno));
        return false;
    }

    if (0 != TEMP_FAILURE_RETRY(bind(serverFd.get(), addr.addr(), addr.addrSize()))) {
        int savedErrno = errno;
        ALOGE("Could not bind socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
        return false;
    }

    if (0 != TEMP_FAILURE_RETRY(listen(serverFd.get(), 1 /*backlog*/))) {
        int savedErrno = errno;
        ALOGE("Could not listen socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
        return false;
    }

    mServer = std::move(serverFd);
    return true;
}

bool RpcConnection::addClient(const SocketAddress& addr) {
    unique_fd serverFd(
            TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
    if (serverFd == -1) {
        int savedErrno = errno;
        ALOGE("Could not create socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
        return false;
    }

    if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), addr.addr(), addr.addrSize()))) {
        int savedErrno = errno;
        ALOGE("Could not connect socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
        return false;
    }

    LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get());

    std::lock_guard<std::mutex> _l(mSocketMutex);
    std::lock_guard<std::mutex> _l(mSocketMutex);
    sp<ConnectionSocket> connection = new ConnectionSocket();
    sp<ConnectionSocket> connection = new ConnectionSocket();
    connection->fd = std::move(fd);
    connection->fd = std::move(serverFd);
    mClients.push_back(connection);
    mClients.push_back(connection);
    return true;
}
}


void RpcConnection::addServer(base::unique_fd&& fd) {
void RpcConnection::assignServerToThisThread(base::unique_fd&& fd) {
    std::lock_guard<std::mutex> _l(mSocketMutex);
    std::lock_guard<std::mutex> _l(mSocketMutex);
    sp<ConnectionSocket> connection = new ConnectionSocket();
    sp<ConnectionSocket> connection = new ConnectionSocket();
    connection->fd = std::move(fd);
    connection->fd = std::move(fd);
+23 −2
Original line number Original line Diff line number Diff line
@@ -61,6 +61,18 @@ public:
     */
     */
    [[nodiscard]] bool addUnixDomainClient(const char* path);
    [[nodiscard]] bool addUnixDomainClient(const char* path);


#ifdef __BIONIC__
    /**
     * Creates an RPC server at the current port.
     */
    [[nodiscard]] bool setupVsockServer(unsigned int port);

    /**
     * Connects to an RPC server at the CVD & port.
     */
    [[nodiscard]] bool addVsockClient(unsigned int cvd, unsigned int port);
#endif // __BIONIC__

    /**
    /**
     * Query the other side of the connection for the root object hosted by that
     * Query the other side of the connection for the root object hosted by that
     * process's RpcServer (if one exists)
     * process's RpcServer (if one exists)
@@ -85,11 +97,20 @@ public:
    // internal only
    // internal only
    const std::unique_ptr<RpcState>& state() { return mState; }
    const std::unique_ptr<RpcState>& state() { return mState; }


    class SocketAddress {
    public:
        virtual ~SocketAddress();
        virtual std::string toString() const = 0;
        virtual const sockaddr* addr() const = 0;
        virtual size_t addrSize() const = 0;
    };

private:
private:
    RpcConnection();
    RpcConnection();


    void addServer(base::unique_fd&& fd);
    bool addServer(const SocketAddress& address);
    void addClient(base::unique_fd&& fd);
    bool addClient(const SocketAddress& address);
    void assignServerToThisThread(base::unique_fd&& fd);


    struct ConnectionSocket : public RefBase {
    struct ConnectionSocket : public RefBase {
        base::unique_fd fd;
        base::unique_fd fd;
+6 −0
Original line number Original line Diff line number Diff line
@@ -106,6 +106,12 @@ cc_test {


cc_test {
cc_test {
    name: "binderRpcTest",
    name: "binderRpcTest",
    host_supported: true,
    target: {
        darwin: {
            enabled: false,
        },
    },
    defaults: ["binder_test_defaults"],
    defaults: ["binder_test_defaults"],


    srcs: [
    srcs: [
+171 −109
Original line number Original line Diff line number Diff line
@@ -14,14 +14,6 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#include <sys/prctl.h>
#include <unistd.h>

#include <chrono>
#include <cstdlib>
#include <iostream>
#include <thread>

#include <BnBinderRpcSession.h>
#include <BnBinderRpcSession.h>
#include <BnBinderRpcTest.h>
#include <BnBinderRpcTest.h>
#include <android-base/logging.h>
#include <android-base/logging.h>
@@ -33,6 +25,18 @@
#include <binder/RpcServer.h>
#include <binder/RpcServer.h>
#include <gtest/gtest.h>
#include <gtest/gtest.h>


#include <chrono>
#include <cstdlib>
#include <iostream>
#include <thread>

#ifdef __BIONIC__
#include <linux/vm_sockets.h>
#endif //__BIONIC__

#include <sys/prctl.h>
#include <unistd.h>

#include "../RpcState.h" // for debugging
#include "../RpcState.h" // for debugging


namespace android {
namespace android {
@@ -185,8 +189,13 @@ private:


static std::string allocateSocketAddress() {
static std::string allocateSocketAddress() {
    static size_t id = 0;
    static size_t id = 0;
    static bool gUseTmp = access("/tmp/", F_OK) != -1;


    if (gUseTmp) {
        return "/tmp/binderRpcTest_" + std::to_string(id++);
    } else {
        return "/dev/binderRpcTest_" + std::to_string(id++);
        return "/dev/binderRpcTest_" + std::to_string(id++);
    }
};
};


struct ProcessConnection {
struct ProcessConnection {
@@ -214,6 +223,51 @@ struct ProcessConnection {
    }
    }
};
};


// Process connection where the process hosts IBinderRpcTest, the server used
// for most testing here
struct BinderRpcTestProcessConnection {
    ProcessConnection proc;

    // pre-fetched root object
    sp<IBinder> rootBinder;

    // pre-casted root object
    sp<IBinderRpcTest> rootIface;

    ~BinderRpcTestProcessConnection() {
        if (!proc.expectInvalid) {
            int32_t remoteBinders = 0;
            EXPECT_OK(rootIface->countBinders(&remoteBinders));
            // should only be the root binder object, iface
            EXPECT_EQ(remoteBinders, 1);
        }

        rootIface = nullptr;
        rootBinder = nullptr;
    }
};

enum class SocketType {
    UNIX,
#ifdef __BIONIC__
    VSOCK,
#endif // __BIONIC__
};
static inline std::string PrintSocketType(const testing::TestParamInfo<SocketType>& info) {
    switch (info.param) {
        case SocketType::UNIX:
            return "unix_domain_socket";
#ifdef __BIONIC__
        case SocketType::VSOCK:
            return "vm_socket";
#endif // __BIONIC__
        default:
            LOG_ALWAYS_FATAL("Unknown socket type");
            return "";
    }
}
class BinderRpc : public ::testing::TestWithParam<SocketType> {
public:
    // This creates a new process serving an interface on a certain number of
    // This creates a new process serving an interface on a certain number of
    // threads.
    // threads.
    ProcessConnection createRpcTestSocketServerProcess(
    ProcessConnection createRpcTestSocketServerProcess(
@@ -221,8 +275,12 @@ ProcessConnection createRpcTestSocketServerProcess(
            const std::function<void(const sp<RpcServer>&, const sp<RpcConnection>&)>& configure) {
            const std::function<void(const sp<RpcServer>&, const sp<RpcConnection>&)>& configure) {
        CHECK_GT(numThreads, 0);
        CHECK_GT(numThreads, 0);


        SocketType socketType = GetParam();

        std::string addr = allocateSocketAddress();
        std::string addr = allocateSocketAddress();
        unlink(addr.c_str());
        unlink(addr.c_str());
        static unsigned int port = 3456;
        port++;


        auto ret = ProcessConnection{
        auto ret = ProcessConnection{
                .host = Process([&] {
                .host = Process([&] {
@@ -232,7 +290,19 @@ ProcessConnection createRpcTestSocketServerProcess(


                    // server supporting one client on one socket
                    // server supporting one client on one socket
                    sp<RpcConnection> connection = server->addClientConnection();
                    sp<RpcConnection> connection = server->addClientConnection();

                    switch (socketType) {
                        case SocketType::UNIX:
                            CHECK(connection->setupUnixDomainServer(addr.c_str())) << addr;
                            CHECK(connection->setupUnixDomainServer(addr.c_str())) << addr;
                            break;
#ifdef __BIONIC__
                        case SocketType::VSOCK:
                            CHECK(connection->setupVsockServer(port));
                            break;
#endif // __BIONIC__
                        default:
                            LOG_ALWAYS_FATAL("Unknown socket type");
                    }


                    configure(server, connection);
                    configure(server, connection);


@@ -247,48 +317,30 @@ ProcessConnection createRpcTestSocketServerProcess(
                .connection = RpcConnection::make(),
                .connection = RpcConnection::make(),
        };
        };


    // wait up to 1s for sockets to be created
    constexpr useconds_t kMaxWaitUs = 1000000;
    constexpr useconds_t kWaitDivision = 100;
    for (size_t i = 0; i < kWaitDivision && 0 != access(addr.c_str(), F_OK); i++) {
        usleep(kMaxWaitUs / kWaitDivision);
    }

        // create remainder of connections
        // create remainder of connections
        for (size_t i = 0; i < numThreads; i++) {
        for (size_t i = 0; i < numThreads; i++) {
        // Connection refused sometimes after file created but before listening.
            for (size_t tries = 0; tries < 5; tries++) {
        CHECK(ret.connection->addUnixDomainClient(addr.c_str()) ||
                usleep(10000);
              (usleep(10000), ret.connection->addUnixDomainClient(addr.c_str())))
                switch (socketType) {
                << i;
                    case SocketType::UNIX:
                        if (ret.connection->addUnixDomainClient(addr.c_str())) goto success;
                        break;
#ifdef __BIONIC__
                    case SocketType::VSOCK:
                        if (ret.connection->addVsockClient(VMADDR_CID_LOCAL, port)) goto success;
                        break;
#endif // __BIONIC__
                    default:
                        LOG_ALWAYS_FATAL("Unknown socket type");
                }
                }

    ret.rootBinder = ret.connection->getRootObject();
    return ret;
            }
            }

            LOG_ALWAYS_FATAL("Could not connect");
// Process connection where the process hosts IBinderRpcTest, the server used
        success:;
// for most testing here
struct BinderRpcTestProcessConnection {
    ProcessConnection proc;

    // pre-fetched root object
    sp<IBinder> rootBinder;

    // pre-casted root object
    sp<IBinderRpcTest> rootIface;

    ~BinderRpcTestProcessConnection() {
        if (!proc.expectInvalid) {
            int32_t remoteBinders = 0;
            EXPECT_OK(rootIface->countBinders(&remoteBinders));
            // should only be the root binder object, iface
            EXPECT_EQ(remoteBinders, 1);
        }
        }


        rootIface = nullptr;
        ret.rootBinder = ret.connection->getRootObject();
        rootBinder = nullptr;
        return ret;
    }
    }
};


    BinderRpcTestProcessConnection createRpcTestSocketServerProcess(size_t numThreads) {
    BinderRpcTestProcessConnection createRpcTestSocketServerProcess(size_t numThreads) {
        BinderRpcTestProcessConnection ret{
        BinderRpcTestProcessConnection ret{
@@ -308,8 +360,9 @@ BinderRpcTestProcessConnection createRpcTestSocketServerProcess(size_t numThread


        return ret;
        return ret;
    }
    }
};


TEST(BinderRpc, RootObjectIsNull) {
TEST_P(BinderRpc, RootObjectIsNull) {
    auto proc = createRpcTestSocketServerProcess(1,
    auto proc = createRpcTestSocketServerProcess(1,
                                                 [](const sp<RpcServer>& server,
                                                 [](const sp<RpcServer>& server,
                                                    const sp<RpcConnection>&) {
                                                    const sp<RpcConnection>&) {
@@ -324,20 +377,20 @@ TEST(BinderRpc, RootObjectIsNull) {
    EXPECT_EQ(nullptr, proc.connection->getRootObject());
    EXPECT_EQ(nullptr, proc.connection->getRootObject());
}
}


TEST(BinderRpc, Ping) {
TEST_P(BinderRpc, Ping) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);
    ASSERT_NE(proc.rootBinder, nullptr);
    ASSERT_NE(proc.rootBinder, nullptr);
    EXPECT_EQ(OK, proc.rootBinder->pingBinder());
    EXPECT_EQ(OK, proc.rootBinder->pingBinder());
}
}


TEST(BinderRpc, TransactionsMustBeMarkedRpc) {
TEST_P(BinderRpc, TransactionsMustBeMarkedRpc) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);
    Parcel data;
    Parcel data;
    Parcel reply;
    Parcel reply;
    EXPECT_EQ(BAD_TYPE, proc.rootBinder->transact(IBinder::PING_TRANSACTION, data, &reply, 0));
    EXPECT_EQ(BAD_TYPE, proc.rootBinder->transact(IBinder::PING_TRANSACTION, data, &reply, 0));
}
}


TEST(BinderRpc, UnknownTransaction) {
TEST_P(BinderRpc, UnknownTransaction) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);
    Parcel data;
    Parcel data;
    data.markForBinder(proc.rootBinder);
    data.markForBinder(proc.rootBinder);
@@ -345,19 +398,19 @@ TEST(BinderRpc, UnknownTransaction) {
    EXPECT_EQ(UNKNOWN_TRANSACTION, proc.rootBinder->transact(1337, data, &reply, 0));
    EXPECT_EQ(UNKNOWN_TRANSACTION, proc.rootBinder->transact(1337, data, &reply, 0));
}
}


TEST(BinderRpc, SendSomethingOneway) {
TEST_P(BinderRpc, SendSomethingOneway) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);
    EXPECT_OK(proc.rootIface->sendString("asdf"));
    EXPECT_OK(proc.rootIface->sendString("asdf"));
}
}


TEST(BinderRpc, SendAndGetResultBack) {
TEST_P(BinderRpc, SendAndGetResultBack) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);
    std::string doubled;
    std::string doubled;
    EXPECT_OK(proc.rootIface->doubleString("cool ", &doubled));
    EXPECT_OK(proc.rootIface->doubleString("cool ", &doubled));
    EXPECT_EQ("cool cool ", doubled);
    EXPECT_EQ("cool cool ", doubled);
}
}


TEST(BinderRpc, SendAndGetResultBackBig) {
TEST_P(BinderRpc, SendAndGetResultBackBig) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);
    std::string single = std::string(1024, 'a');
    std::string single = std::string(1024, 'a');
    std::string doubled;
    std::string doubled;
@@ -365,7 +418,7 @@ TEST(BinderRpc, SendAndGetResultBackBig) {
    EXPECT_EQ(single + single, doubled);
    EXPECT_EQ(single + single, doubled);
}
}


TEST(BinderRpc, CallMeBack) {
TEST_P(BinderRpc, CallMeBack) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);


    int32_t pingResult;
    int32_t pingResult;
@@ -375,7 +428,7 @@ TEST(BinderRpc, CallMeBack) {
    EXPECT_EQ(0, MyBinderRpcSession::gNum);
    EXPECT_EQ(0, MyBinderRpcSession::gNum);
}
}


TEST(BinderRpc, RepeatBinder) {
TEST_P(BinderRpc, RepeatBinder) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);


    sp<IBinder> inBinder = new MyBinderRpcSession("foo");
    sp<IBinder> inBinder = new MyBinderRpcSession("foo");
@@ -397,7 +450,7 @@ TEST(BinderRpc, RepeatBinder) {
    EXPECT_EQ(0, MyBinderRpcSession::gNum);
    EXPECT_EQ(0, MyBinderRpcSession::gNum);
}
}


TEST(BinderRpc, RepeatTheirBinder) {
TEST_P(BinderRpc, RepeatTheirBinder) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);


    sp<IBinderRpcSession> session;
    sp<IBinderRpcSession> session;
@@ -421,7 +474,7 @@ TEST(BinderRpc, RepeatTheirBinder) {
    EXPECT_EQ(nullptr, weak.promote());
    EXPECT_EQ(nullptr, weak.promote());
}
}


TEST(BinderRpc, RepeatBinderNull) {
TEST_P(BinderRpc, RepeatBinderNull) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);


    sp<IBinder> outBinder;
    sp<IBinder> outBinder;
@@ -429,7 +482,7 @@ TEST(BinderRpc, RepeatBinderNull) {
    EXPECT_EQ(nullptr, outBinder);
    EXPECT_EQ(nullptr, outBinder);
}
}


TEST(BinderRpc, HoldBinder) {
TEST_P(BinderRpc, HoldBinder) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);


    IBinder* ptr = nullptr;
    IBinder* ptr = nullptr;
@@ -455,7 +508,7 @@ TEST(BinderRpc, HoldBinder) {
// These are behavioral differences form regular binder, where certain usecases
// These are behavioral differences form regular binder, where certain usecases
// aren't supported.
// aren't supported.


TEST(BinderRpc, CannotMixBindersBetweenUnrelatedSocketConnections) {
TEST_P(BinderRpc, CannotMixBindersBetweenUnrelatedSocketConnections) {
    auto proc1 = createRpcTestSocketServerProcess(1);
    auto proc1 = createRpcTestSocketServerProcess(1);
    auto proc2 = createRpcTestSocketServerProcess(1);
    auto proc2 = createRpcTestSocketServerProcess(1);


@@ -464,7 +517,7 @@ TEST(BinderRpc, CannotMixBindersBetweenUnrelatedSocketConnections) {
              proc1.rootIface->repeatBinder(proc2.rootBinder, &outBinder).transactionError());
              proc1.rootIface->repeatBinder(proc2.rootBinder, &outBinder).transactionError());
}
}


TEST(BinderRpc, CannotSendRegularBinderOverSocketBinder) {
TEST_P(BinderRpc, CannotSendRegularBinderOverSocketBinder) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);


    sp<IBinder> someRealBinder = IInterface::asBinder(defaultServiceManager());
    sp<IBinder> someRealBinder = IInterface::asBinder(defaultServiceManager());
@@ -473,7 +526,7 @@ TEST(BinderRpc, CannotSendRegularBinderOverSocketBinder) {
              proc.rootIface->repeatBinder(someRealBinder, &outBinder).transactionError());
              proc.rootIface->repeatBinder(someRealBinder, &outBinder).transactionError());
}
}


TEST(BinderRpc, CannotSendSocketBinderOverRegularBinder) {
TEST_P(BinderRpc, CannotSendSocketBinderOverRegularBinder) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);


    // for historical reasons, IServiceManager interface only returns the
    // for historical reasons, IServiceManager interface only returns the
@@ -484,7 +537,7 @@ TEST(BinderRpc, CannotSendSocketBinderOverRegularBinder) {


// END TESTS FOR LIMITATIONS OF SOCKET BINDER
// END TESTS FOR LIMITATIONS OF SOCKET BINDER


TEST(BinderRpc, RepeatRootObject) {
TEST_P(BinderRpc, RepeatRootObject) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);


    sp<IBinder> outBinder;
    sp<IBinder> outBinder;
@@ -492,7 +545,7 @@ TEST(BinderRpc, RepeatRootObject) {
    EXPECT_EQ(proc.rootBinder, outBinder);
    EXPECT_EQ(proc.rootBinder, outBinder);
}
}


TEST(BinderRpc, NestedTransactions) {
TEST_P(BinderRpc, NestedTransactions) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);


    auto nastyNester = sp<MyBinderRpcTest>::make();
    auto nastyNester = sp<MyBinderRpcTest>::make();
@@ -503,7 +556,7 @@ TEST(BinderRpc, NestedTransactions) {
    EXPECT_EQ(nullptr, weak.promote());
    EXPECT_EQ(nullptr, weak.promote());
}
}


TEST(BinderRpc, SameBinderEquality) {
TEST_P(BinderRpc, SameBinderEquality) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);


    sp<IBinder> a;
    sp<IBinder> a;
@@ -515,7 +568,7 @@ TEST(BinderRpc, SameBinderEquality) {
    EXPECT_EQ(a, b);
    EXPECT_EQ(a, b);
}
}


TEST(BinderRpc, SameBinderEqualityWeak) {
TEST_P(BinderRpc, SameBinderEqualityWeak) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);


    sp<IBinder> a;
    sp<IBinder> a;
@@ -547,7 +600,7 @@ TEST(BinderRpc, SameBinderEqualityWeak) {
        EXPECT_EQ(expected, session);                     \
        EXPECT_EQ(expected, session);                     \
    } while (false)
    } while (false)


TEST(BinderRpc, SingleSession) {
TEST_P(BinderRpc, SingleSession) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);


    sp<IBinderRpcSession> session;
    sp<IBinderRpcSession> session;
@@ -561,7 +614,7 @@ TEST(BinderRpc, SingleSession) {
    expectSessions(0, proc.rootIface);
    expectSessions(0, proc.rootIface);
}
}


TEST(BinderRpc, ManySessions) {
TEST_P(BinderRpc, ManySessions) {
    auto proc = createRpcTestSocketServerProcess(1);
    auto proc = createRpcTestSocketServerProcess(1);


    std::vector<sp<IBinderRpcSession>> sessions;
    std::vector<sp<IBinderRpcSession>> sessions;
@@ -595,7 +648,7 @@ size_t epochMillis() {
    return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
    return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
}
}


TEST(BinderRpc, ThreadPoolGreaterThanEqualRequested) {
TEST_P(BinderRpc, ThreadPoolGreaterThanEqualRequested) {
    constexpr size_t kNumThreads = 10;
    constexpr size_t kNumThreads = 10;


    auto proc = createRpcTestSocketServerProcess(kNumThreads);
    auto proc = createRpcTestSocketServerProcess(kNumThreads);
@@ -627,7 +680,7 @@ TEST(BinderRpc, ThreadPoolGreaterThanEqualRequested) {
    for (auto& t : ts) t.join();
    for (auto& t : ts) t.join();
}
}


TEST(BinderRpc, ThreadPoolOverSaturated) {
TEST_P(BinderRpc, ThreadPoolOverSaturated) {
    constexpr size_t kNumThreads = 10;
    constexpr size_t kNumThreads = 10;
    constexpr size_t kNumCalls = kNumThreads + 3;
    constexpr size_t kNumCalls = kNumThreads + 3;
    constexpr size_t kSleepMs = 500;
    constexpr size_t kSleepMs = 500;
@@ -651,7 +704,7 @@ TEST(BinderRpc, ThreadPoolOverSaturated) {
    EXPECT_LE(epochMsAfter, epochMsBefore + 3 * kSleepMs);
    EXPECT_LE(epochMsAfter, epochMsBefore + 3 * kSleepMs);
}
}


TEST(BinderRpc, ThreadingStressTest) {
TEST_P(BinderRpc, ThreadingStressTest) {
    constexpr size_t kNumClientThreads = 10;
    constexpr size_t kNumClientThreads = 10;
    constexpr size_t kNumServerThreads = 10;
    constexpr size_t kNumServerThreads = 10;
    constexpr size_t kNumCalls = 100;
    constexpr size_t kNumCalls = 100;
@@ -672,7 +725,7 @@ TEST(BinderRpc, ThreadingStressTest) {
    for (auto& t : threads) t.join();
    for (auto& t : threads) t.join();
}
}


TEST(BinderRpc, OnewayCallDoesNotWait) {
TEST_P(BinderRpc, OnewayCallDoesNotWait) {
    constexpr size_t kReallyLongTimeMs = 100;
    constexpr size_t kReallyLongTimeMs = 100;
    constexpr size_t kSleepMs = kReallyLongTimeMs * 5;
    constexpr size_t kSleepMs = kReallyLongTimeMs * 5;


@@ -687,7 +740,7 @@ TEST(BinderRpc, OnewayCallDoesNotWait) {
    EXPECT_LT(epochMsAfter, epochMsBefore + kReallyLongTimeMs);
    EXPECT_LT(epochMsAfter, epochMsBefore + kReallyLongTimeMs);
}
}


TEST(BinderRpc, OnewayCallQueueing) {
TEST_P(BinderRpc, OnewayCallQueueing) {
    constexpr size_t kNumSleeps = 10;
    constexpr size_t kNumSleeps = 10;
    constexpr size_t kNumExtraServerThreads = 4;
    constexpr size_t kNumExtraServerThreads = 4;
    constexpr size_t kSleepMs = 50;
    constexpr size_t kSleepMs = 50;
@@ -711,7 +764,7 @@ TEST(BinderRpc, OnewayCallQueueing) {
    EXPECT_GT(epochMsAfter, epochMsBefore + kSleepMs * kNumSleeps);
    EXPECT_GT(epochMsAfter, epochMsBefore + kSleepMs * kNumSleeps);
}
}


TEST(BinderRpc, Die) {
TEST_P(BinderRpc, Die) {
    // TODO(b/183141167): handle this in library
    // TODO(b/183141167): handle this in library
    signal(SIGPIPE, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);


@@ -743,7 +796,7 @@ ssize_t countFds() {
    return ret;
    return ret;
}
}


TEST(BinderRpc, Fds) {
TEST_P(BinderRpc, Fds) {
    ssize_t beforeFds = countFds();
    ssize_t beforeFds = countFds();
    ASSERT_GE(beforeFds, 0);
    ASSERT_GE(beforeFds, 0);
    {
    {
@@ -753,10 +806,19 @@ TEST(BinderRpc, Fds) {
    ASSERT_EQ(beforeFds, countFds()) << (system("ls -l /proc/self/fd/"), "fd leak?");
    ASSERT_EQ(beforeFds, countFds()) << (system("ls -l /proc/self/fd/"), "fd leak?");
}
}


extern "C" int main(int argc, char** argv) {
INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc,
                        ::testing::Values(SocketType::UNIX
#ifdef __BIONIC__
                                          ,
                                          SocketType::VSOCK
#endif // __BIONIC__
                                          ),
                        PrintSocketType);

} // namespace android

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);
    ::testing::InitGoogleTest(&argc, argv);
    android::base::InitLogging(argv, android::base::StderrLogger, android::base::DefaultAborter);
    android::base::InitLogging(argv, android::base::StderrLogger, android::base::DefaultAborter);
    return RUN_ALL_TESTS();
    return RUN_ALL_TESTS();
}
}

} // namespace android