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

Commit 974deb9f authored by Steven Moreland's avatar Steven Moreland Committed by Automerger Merge Worker
Browse files

Merge "libbinder: support calls over sockets" am: 4e83ba78 am: 32d689ec

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1495200

Change-Id: I79e3c4205b29dab216832b155a030f8d0e16eaf5
parents c8b582fc 32d689ec
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -124,6 +124,10 @@ cc_library {
        "ParcelFileDescriptor.cpp",
        "PersistableBundle.cpp",
        "ProcessState.cpp",
        "RpcAddress.cpp",
        "RpcConnection.cpp",
        "RpcServer.cpp",
        "RpcState.cpp",
        "Static.cpp",
        "Stability.cpp",
        "Status.cpp",
+91 −36
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@

#include <binder/IPCThreadState.h>
#include <binder/IResultReceiver.h>
#include <binder/RpcConnection.h>
#include <binder/Stability.h>
#include <cutils/compiler.h>
#include <utils/Log.h>
@@ -133,25 +134,56 @@ BpBinder* BpBinder::create(int32_t handle) {
        }
        sTrackingMap[trackedUid]++;
    }
    return new BpBinder(handle, trackedUid);
    return new BpBinder(BinderHandle{handle}, trackedUid);
}

BpBinder::BpBinder(int32_t handle, int32_t trackedUid)
    : mStability(0)
    , mHandle(handle)
    , mAlive(1)
    , mObitsSent(0)
    , mObituaries(nullptr)
    , mTrackedUid(trackedUid)
{
    ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
BpBinder* BpBinder::create(const sp<RpcConnection>& connection, const RpcAddress& address) {
    LOG_ALWAYS_FATAL_IF(connection == nullptr, "BpBinder::create null connection");

    // These are not currently tracked, since there is no UID or other
    // identifier to track them with. However, if similar functionality is
    // needed, connection objects keep track of all BpBinder objects on a
    // per-connection basis.

    return new BpBinder(SocketHandle{connection, address});
}

BpBinder::BpBinder(Handle&& handle)
      : mStability(0),
        mHandle(handle),
        mAlive(true),
        mObitsSent(false),
        mObituaries(nullptr),
        mTrackedUid(-1) {
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
    IPCThreadState::self()->incWeakHandle(handle, this);
}

int32_t BpBinder::handle() const {
    return mHandle;
BpBinder::BpBinder(BinderHandle&& handle, int32_t trackedUid) : BpBinder(Handle(handle)) {
    mTrackedUid = trackedUid;

    ALOGV("Creating BpBinder %p handle %d\n", this, this->binderHandle());

    IPCThreadState::self()->incWeakHandle(this->binderHandle(), this);
}

BpBinder::BpBinder(SocketHandle&& handle) : BpBinder(Handle(handle)) {
    LOG_ALWAYS_FATAL_IF(rpcConnection() == nullptr, "BpBinder created w/o connection object");
}

bool BpBinder::isRpcBinder() const {
    return std::holds_alternative<SocketHandle>(mHandle);
}

const RpcAddress& BpBinder::rpcAddress() const {
    return std::get<SocketHandle>(mHandle).address;
}

const sp<RpcConnection>& BpBinder::rpcConnection() const {
    return std::get<SocketHandle>(mHandle).connection;
}

int32_t BpBinder::binderHandle() const {
    return std::get<BinderHandle>(mHandle).handle;
}

bool BpBinder::isDescriptorCached() const {
@@ -190,9 +222,10 @@ bool BpBinder::isBinderAlive() const

status_t BpBinder::pingBinder()
{
    Parcel send;
    Parcel data;
    data.markForBinder(this);
    Parcel reply;
    return transact(PING_TRANSACTION, send, &reply);
    return transact(PING_TRANSACTION, data, &reply);
}

status_t BpBinder::dump(int fd, const Vector<String16>& args)
@@ -236,8 +269,13 @@ status_t BpBinder::transact(
            }
        }

        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        status_t status;
        if (CC_UNLIKELY(isRpcBinder())) {
            status = rpcConnection()->transact(rpcAddress(), code, data, reply, flags);
        } else {
            status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags);
        }

        if (status == DEAD_OBJECT) mAlive = 0;

        return status;
@@ -250,6 +288,8 @@ status_t BpBinder::transact(
status_t BpBinder::linkToDeath(
    const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
{
    if (isRpcBinder()) return UNKNOWN_TRANSACTION;

    Obituary ob;
    ob.recipient = recipient;
    ob.cookie = cookie;
@@ -267,10 +307,10 @@ status_t BpBinder::linkToDeath(
                if (!mObituaries) {
                    return NO_MEMORY;
                }
                ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
                ALOGV("Requesting death notification: %p handle %d\n", this, binderHandle());
                getWeakRefs()->incWeak(this);
                IPCThreadState* self = IPCThreadState::self();
                self->requestDeathNotification(mHandle, this);
                self->requestDeathNotification(binderHandle(), this);
                self->flushCommands();
            }
            ssize_t res = mObituaries->add(ob);
@@ -286,6 +326,8 @@ status_t BpBinder::unlinkToDeath(
    const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
    wp<DeathRecipient>* outRecipient)
{
    if (isRpcBinder()) return UNKNOWN_TRANSACTION;

    AutoMutex _l(mLock);

    if (mObitsSent) {
@@ -303,9 +345,9 @@ status_t BpBinder::unlinkToDeath(
            }
            mObituaries->removeAt(i);
            if (mObituaries->size() == 0) {
                ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);
                ALOGV("Clearing death notification: %p handle %d\n", this, binderHandle());
                IPCThreadState* self = IPCThreadState::self();
                self->clearDeathNotification(mHandle, this);
                self->clearDeathNotification(binderHandle(), this);
                self->flushCommands();
                delete mObituaries;
                mObituaries = nullptr;
@@ -319,8 +361,10 @@ status_t BpBinder::unlinkToDeath(

void BpBinder::sendObituary()
{
    ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
        this, mHandle, mObitsSent ? "true" : "false");
    LOG_ALWAYS_FATAL_IF(isRpcBinder(), "Cannot send obituary for remote binder.");

    ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n", this, binderHandle(),
          mObitsSent ? "true" : "false");

    mAlive = 0;
    if (mObitsSent) return;
@@ -328,9 +372,9 @@ void BpBinder::sendObituary()
    mLock.lock();
    Vector<Obituary>* obits = mObituaries;
    if(obits != nullptr) {
        ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
        ALOGV("Clearing sent death notification: %p handle %d\n", this, binderHandle());
        IPCThreadState* self = IPCThreadState::self();
        self->clearDeathNotification(mHandle, this);
        self->clearDeathNotification(binderHandle(), this);
        self->flushCommands();
        mObituaries = nullptr;
    }
@@ -388,7 +432,9 @@ BpBinder* BpBinder::remoteBinder()

BpBinder::~BpBinder()
{
    ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
    ALOGV("Destroying BpBinder %p handle %d\n", this, binderHandle());

    if (CC_UNLIKELY(isRpcBinder())) return;

    IPCThreadState* ipc = IPCThreadState::self();

@@ -396,7 +442,8 @@ BpBinder::~BpBinder()
        AutoMutex _l(sTrackingLock);
        uint32_t trackedValue = sTrackingMap[mTrackedUid];
        if (CC_UNLIKELY((trackedValue & COUNTING_VALUE_MASK) == 0)) {
            ALOGE("Unexpected Binder Proxy tracking decrement in %p handle %d\n", this, mHandle);
            ALOGE("Unexpected Binder Proxy tracking decrement in %p handle %d\n", this,
                  binderHandle());
        } else {
            if (CC_UNLIKELY(
                (trackedValue & LIMIT_REACHED_MASK) &&
@@ -413,26 +460,31 @@ BpBinder::~BpBinder()
    }

    if (ipc) {
        ipc->expungeHandle(mHandle, this);
        ipc->decWeakHandle(mHandle);
        ipc->expungeHandle(binderHandle(), this);
        ipc->decWeakHandle(binderHandle());
    }
}

void BpBinder::onFirstRef()
{
    ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
    ALOGV("onFirstRef BpBinder %p handle %d\n", this, binderHandle());
    if (CC_UNLIKELY(isRpcBinder())) return;
    IPCThreadState* ipc = IPCThreadState::self();
    if (ipc) ipc->incStrongHandle(mHandle, this);
    if (ipc) ipc->incStrongHandle(binderHandle(), this);
}

void BpBinder::onLastStrongRef(const void* /*id*/)
{
    ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
    ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, binderHandle());
    if (CC_UNLIKELY(isRpcBinder())) {
        (void)rpcConnection()->sendDecStrong(rpcAddress());
        return;
    }
    IF_ALOGV() {
        printRefs();
    }
    IPCThreadState* ipc = IPCThreadState::self();
    if (ipc) ipc->decStrongHandle(mHandle);
    if (ipc) ipc->decStrongHandle(binderHandle());

    mLock.lock();
    Vector<Obituary>* obits = mObituaries;
@@ -442,7 +494,7 @@ void BpBinder::onLastStrongRef(const void* /*id*/)
                  mDescriptorCache.size() ? String8(mDescriptorCache).c_str() : "<uncached descriptor>");
        }

        if (ipc) ipc->clearDeathNotification(mHandle, this);
        if (ipc) ipc->clearDeathNotification(binderHandle(), this);
        mObituaries = nullptr;
    }
    mLock.unlock();
@@ -457,9 +509,12 @@ void BpBinder::onLastStrongRef(const void* /*id*/)

bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
{
    ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
    // RPC binder doesn't currently support inc from weak binders
    if (CC_UNLIKELY(isRpcBinder())) return false;

    ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, binderHandle());
    IPCThreadState* ipc = IPCThreadState::self();
    return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
    return ipc ? ipc->attemptIncStrongHandle(binderHandle()) == NO_ERROR : false;
}

uint32_t BpBinder::getBinderProxyCount(uint32_t uid)
+16 −0
Original line number Diff line number Diff line
@@ -26,6 +26,22 @@

namespace android {

std::string hexString(const void* bytes, size_t len) {
    if (bytes == nullptr) return "<null>";

    const uint8_t* bytes8 = static_cast<const uint8_t*>(bytes);
    const char chars[] = "0123456789abcdef";
    std::string result;
    result.resize(len * 2);

    for (size_t i = 0; i < len; i++) {
        result[2 * i] = chars[bytes8[i] >> 4];
        result[2 * i + 1] = chars[bytes8[i] & 0xf];
    }

    return result;
}

// ---------------------------------------------------------------------

static const char indentStr[] =
+2 −4
Original line number Diff line number Diff line
@@ -17,13 +17,13 @@
#pragma once

#include <stdint.h>
#include <sys/cdefs.h>
#include <sys/types.h>
#include <string>

namespace android {
// ---------------------------------------------------------------------------

__BEGIN_DECLS
std::string hexString(const void* data, size_t size);

const char* stringForIndent(int32_t indentLevel);

@@ -40,7 +40,5 @@ void printHexData(int32_t indent, const void *buf, size_t length,

ssize_t getBinderKernelReferences(size_t count, uintptr_t* buf);

__END_DECLS

// ---------------------------------------------------------------------------
} // namespace android
+2 −0
Original line number Diff line number Diff line
@@ -689,6 +689,8 @@ status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
    LOG_ALWAYS_FATAL_IF(data.isForRpc(), "Parcel constructed for RPC, but being used with binder.");

    status_t err;

    flags |= TF_ACCEPT_FDS;
Loading