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

Commit f8efb476 authored by Yifan Hong's avatar Yifan Hong Committed by Automerger Merge Worker
Browse files

Merge changes Ic46ac54b,Id787e70f am: dfb9cd9d

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

Change-Id: I4e77ef33751d5d0d3463e59fd0a3cdcd7d46bf73
parents a7e2f1b5 dfb9cd9d
Loading
Loading
Loading
Loading
+73 −16
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
#include <binder/Binder.h>
#include <binder/Binder.h>


#include <atomic>
#include <atomic>
#include <set>


#include <android-base/unique_fd.h>
#include <android-base/unique_fd.h>
#include <binder/BpBinder.h>
#include <binder/BpBinder.h>
@@ -150,7 +151,8 @@ status_t IBinder::getDebugPid(pid_t* out) {
    return OK;
    return OK;
}
}


status_t IBinder::setRpcClientDebug(android::base::unique_fd socketFd) {
status_t IBinder::setRpcClientDebug(android::base::unique_fd socketFd,
                                    const sp<IBinder>& keepAliveBinder) {
    if constexpr (!kEnableRpcDevServers) {
    if constexpr (!kEnableRpcDevServers) {
        ALOGW("setRpcClientDebug disallowed because RPC is not enabled");
        ALOGW("setRpcClientDebug disallowed because RPC is not enabled");
        return INVALID_OPERATION;
        return INVALID_OPERATION;
@@ -158,7 +160,7 @@ status_t IBinder::setRpcClientDebug(android::base::unique_fd socketFd) {


    BBinder* local = this->localBinder();
    BBinder* local = this->localBinder();
    if (local != nullptr) {
    if (local != nullptr) {
        return local->BBinder::setRpcClientDebug(std::move(socketFd));
        return local->BBinder::setRpcClientDebug(std::move(socketFd), keepAliveBinder);
    }
    }


    BpBinder* proxy = this->remoteBinder();
    BpBinder* proxy = this->remoteBinder();
@@ -173,11 +175,44 @@ status_t IBinder::setRpcClientDebug(android::base::unique_fd socketFd) {
        status = data.writeFileDescriptor(socketFd.release(), true /* own */);
        status = data.writeFileDescriptor(socketFd.release(), true /* own */);
        if (status != OK) return status;
        if (status != OK) return status;
    }
    }
    if (status = data.writeStrongBinder(keepAliveBinder); status != OK) return status;
    return transact(SET_RPC_CLIENT_TRANSACTION, data, &reply);
    return transact(SET_RPC_CLIENT_TRANSACTION, data, &reply);
}
}


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


class BBinder::RpcServerLink : public IBinder::DeathRecipient {
public:
    // On binder died, calls RpcServer::shutdown on @a rpcServer, and removes itself from @a binder.
    RpcServerLink(const sp<RpcServer>& rpcServer, const sp<IBinder>& keepAliveBinder,
                  const wp<BBinder>& binder)
          : mRpcServer(rpcServer), mKeepAliveBinder(keepAliveBinder), mBinder(binder) {}
    void binderDied(const wp<IBinder>&) override {
        LOG_RPC_DETAIL("RpcServerLink: binder died, shutting down RpcServer");
        if (mRpcServer == nullptr) {
            ALOGW("RpcServerLink: Unable to shut down RpcServer because it does not exist.");
        } else {
            ALOGW_IF(!mRpcServer->shutdown(),
                     "RpcServerLink: RpcServer did not shut down properly. Not started?");
        }
        mRpcServer.clear();

        auto promoted = mBinder.promote();
        if (promoted == nullptr) {
            ALOGW("RpcServerLink: Unable to remove link from parent binder object because parent "
                  "binder object is gone.");
        } else {
            promoted->removeRpcServerLink(sp<RpcServerLink>::fromExisting(this));
        }
        mBinder.clear();
    }

private:
    sp<RpcServer> mRpcServer;
    sp<IBinder> mKeepAliveBinder; // hold to avoid automatically unlinking
    wp<BBinder> mBinder;
};

class BBinder::Extras
class BBinder::Extras
{
{
public:
public:
@@ -190,7 +225,7 @@ public:


    // for below objects
    // for below objects
    Mutex mLock;
    Mutex mLock;
    sp<RpcServer> mRpcServer;
    std::set<sp<RpcServerLink>> mRpcServerLinks;
    BpBinder::ObjectManager mObjects;
    BpBinder::ObjectManager mObjects;
};
};


@@ -453,11 +488,14 @@ status_t BBinder::setRpcClientDebug(const Parcel& data) {
    if (hasSocketFd) {
    if (hasSocketFd) {
        if (status = data.readUniqueFileDescriptor(&clientFd); status != OK) return status;
        if (status = data.readUniqueFileDescriptor(&clientFd); status != OK) return status;
    }
    }
    sp<IBinder> keepAliveBinder;
    if (status = data.readNullableStrongBinder(&keepAliveBinder); status != OK) return status;


    return setRpcClientDebug(std::move(clientFd));
    return setRpcClientDebug(std::move(clientFd), keepAliveBinder);
}
}


status_t BBinder::setRpcClientDebug(android::base::unique_fd socketFd) {
status_t BBinder::setRpcClientDebug(android::base::unique_fd socketFd,
                                    const sp<IBinder>& keepAliveBinder) {
    if constexpr (!kEnableRpcDevServers) {
    if constexpr (!kEnableRpcDevServers) {
        ALOGW("%s: disallowed because RPC is not enabled", __PRETTY_FUNCTION__);
        ALOGW("%s: disallowed because RPC is not enabled", __PRETTY_FUNCTION__);
        return INVALID_OPERATION;
        return INVALID_OPERATION;
@@ -471,6 +509,11 @@ status_t BBinder::setRpcClientDebug(android::base::unique_fd socketFd) {
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }


    if (keepAliveBinder == nullptr) {
        ALOGE("%s: No keepAliveBinder provided.", __PRETTY_FUNCTION__);
        return UNEXPECTED_NULL;
    }

    size_t binderThreadPoolMaxCount = ProcessState::self()->getThreadPoolMaxThreadCount();
    size_t binderThreadPoolMaxCount = ProcessState::self()->getThreadPoolMaxThreadCount();
    if (binderThreadPoolMaxCount <= 1) {
    if (binderThreadPoolMaxCount <= 1) {
        ALOGE("%s: ProcessState thread pool max count is %zu. RPC is disabled for this service "
        ALOGE("%s: ProcessState thread pool max count is %zu. RPC is disabled for this service "
@@ -479,24 +522,38 @@ status_t BBinder::setRpcClientDebug(android::base::unique_fd socketFd) {
        return INVALID_OPERATION;
        return INVALID_OPERATION;
    }
    }


    // Weak ref to avoid circular dependency:
    // BBinder -> RpcServerLink ----> RpcServer -X-> BBinder
    //                          `-X-> BBinder
    auto weakThis = wp<BBinder>::fromExisting(this);

    Extras* e = getOrCreateExtras();
    Extras* e = getOrCreateExtras();
    AutoMutex _l(e->mLock);
    AutoMutex _l(e->mLock);
    if (e->mRpcServer != nullptr) {
    auto rpcServer = RpcServer::make();
        ALOGE("%s: Already have RPC client", __PRETTY_FUNCTION__);
    LOG_ALWAYS_FATAL_IF(rpcServer == nullptr, "RpcServer::make returns null");
        return ALREADY_EXISTS;
    rpcServer->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
    }
    auto link = sp<RpcServerLink>::make(rpcServer, keepAliveBinder, weakThis);
    e->mRpcServer = RpcServer::make();
    if (auto status = keepAliveBinder->linkToDeath(link, nullptr, 0); status != OK) {
    LOG_ALWAYS_FATAL_IF(e->mRpcServer == nullptr, "RpcServer::make returns null");
        ALOGE("%s: keepAliveBinder->linkToDeath returns %s", __PRETTY_FUNCTION__,
    e->mRpcServer->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
              statusToString(status).c_str());
    // Weak ref to avoid circular dependency: BBinder -> RpcServer -X-> BBinder
        return status;
    e->mRpcServer->setRootObjectWeak(wp<BBinder>::fromExisting(this));
    }
    e->mRpcServer->setupExternalServer(std::move(socketFd));
    rpcServer->setRootObjectWeak(weakThis);
    e->mRpcServer->setMaxThreads(binderThreadPoolMaxCount);
    rpcServer->setupExternalServer(std::move(socketFd));
    e->mRpcServer->start();
    rpcServer->setMaxThreads(binderThreadPoolMaxCount);
    rpcServer->start();
    e->mRpcServerLinks.emplace(link);
    LOG_RPC_DETAIL("%s(fd=%d) successful", __PRETTY_FUNCTION__, socketFdForPrint);
    LOG_RPC_DETAIL("%s(fd=%d) successful", __PRETTY_FUNCTION__, socketFdForPrint);
    return OK;
    return OK;
}
}


void BBinder::removeRpcServerLink(const sp<RpcServerLink>& link) {
    Extras* e = mExtras.load(std::memory_order_acquire);
    if (!e) return;
    AutoMutex _l(e->mLock);
    (void)e->mRpcServerLinks.erase(link);
}

BBinder::~BBinder()
BBinder::~BBinder()
{
{
    Extras* e = mExtras.load(std::memory_order_relaxed);
    Extras* e = mExtras.load(std::memory_order_relaxed);
+4 −1
Original line number Original line Diff line number Diff line
@@ -101,7 +101,8 @@ public:
    // to another process.
    // to another process.
    void setParceled();
    void setParceled();


    [[nodiscard]] status_t setRpcClientDebug(android::base::unique_fd clientFd);
    [[nodiscard]] status_t setRpcClientDebug(android::base::unique_fd clientFd,
                                             const sp<IBinder>& keepAliveBinder);


protected:
protected:
    virtual             ~BBinder();
    virtual             ~BBinder();
@@ -116,11 +117,13 @@ private:
                        BBinder(const BBinder& o);
                        BBinder(const BBinder& o);
            BBinder&    operator=(const BBinder& o);
            BBinder&    operator=(const BBinder& o);


    class RpcServerLink;
    class Extras;
    class Extras;


    Extras*             getOrCreateExtras();
    Extras*             getOrCreateExtras();


    [[nodiscard]] status_t setRpcClientDebug(const Parcel& data);
    [[nodiscard]] status_t setRpcClientDebug(const Parcel& data);
    void removeRpcServerLink(const sp<RpcServerLink>& link);


    std::atomic<Extras*> mExtras;
    std::atomic<Extras*> mExtras;


+6 −3
Original line number Original line Diff line number Diff line
@@ -162,14 +162,17 @@ public:
     * 2. spawns 1 new thread that calls RpcServer::join()
     * 2. spawns 1 new thread that calls RpcServer::join()
     *    - join() spawns some number of threads that accept() connections; see RpcServer
     *    - join() spawns some number of threads that accept() connections; see RpcServer
     *
     *
     * setRpcClientDebug() may only be called once.
     * setRpcClientDebug() may be called multiple times. Each call will add a new RpcServer
     * TODO(b/182914638): If allow to shut down the client, addRpcClient can be called repeatedly.
     * and opens up a TCP port.
     *
     *
     * Note: A thread is spawned for each accept()'ed fd, which may call into functions of the
     * Note: A thread is spawned for each accept()'ed fd, which may call into functions of the
     * interface freely. See RpcServer::join(). To avoid such race conditions, implement the service
     * interface freely. See RpcServer::join(). To avoid such race conditions, implement the service
     * functions with multithreading support.
     * functions with multithreading support.
     *
     * On death of @a keepAliveBinder, the RpcServer shuts down.
     */
     */
    [[nodiscard]] status_t setRpcClientDebug(android::base::unique_fd socketFd);
    [[nodiscard]] status_t setRpcClientDebug(android::base::unique_fd socketFd,
                                             const sp<IBinder>& keepAliveBinder);


    // NOLINTNEXTLINE(google-default-arguments)
    // NOLINTNEXTLINE(google-default-arguments)
    virtual status_t        transact(   uint32_t code,
    virtual status_t        transact(   uint32_t code,
+4 −1
Original line number Original line Diff line number Diff line
@@ -26,9 +26,11 @@
#include <binder/IServiceManager.h>
#include <binder/IServiceManager.h>
#include <binder/RpcServer.h>
#include <binder/RpcServer.h>


using android::BBinder;
using android::defaultServiceManager;
using android::defaultServiceManager;
using android::OK;
using android::OK;
using android::RpcServer;
using android::RpcServer;
using android::sp;
using android::statusToString;
using android::statusToString;
using android::String16;
using android::String16;
using android::base::Basename;
using android::base::Basename;
@@ -74,7 +76,8 @@ int Dispatch(const char* name) {
        return EX_SOFTWARE;
        return EX_SOFTWARE;
    }
    }
    auto socket = rpcServer->releaseServer();
    auto socket = rpcServer->releaseServer();
    auto status = binder->setRpcClientDebug(std::move(socket));
    auto keepAliveBinder = sp<BBinder>::make();
    auto status = binder->setRpcClientDebug(std::move(socket), keepAliveBinder);
    if (status != OK) {
    if (status != OK) {
        LOG(ERROR) << "setRpcClientDebug failed with " << statusToString(status);
        LOG(ERROR) << "setRpcClientDebug failed with " << statusToString(status);
        return EX_SOFTWARE;
        return EX_SOFTWARE;
+2 −0
Original line number Original line Diff line number Diff line
@@ -62,6 +62,7 @@ cc_test {
    shared_libs: [
    shared_libs: [
        "libbase",
        "libbase",
        "libbinder",
        "libbinder",
        "liblog",
        "libutils",
        "libutils",
    ],
    ],
    static_libs: [
    static_libs: [
@@ -104,6 +105,7 @@ cc_test {
    shared_libs: [
    shared_libs: [
        "libbase",
        "libbase",
        "libbinder",
        "libbinder",
        "liblog",
        "libutils",
        "libutils",
    ],
    ],
    static_libs: [
    static_libs: [
Loading