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

Commit ee4e817a authored by Yifan Hong's avatar Yifan Hong Committed by Gerrit Code Review
Browse files

Merge changes I71b563ca,Ib51fa419,I15686bae

* changes:
  Compile the utility `service` on host as `aservice`
  binder: host service manager limits max outgoing threads
  binder: RpcSession limit outgoing threads
parents 2c62f367 86cf053e
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -52,3 +52,21 @@ cc_binary {
        "-Werror",
    ],
}

cc_binary_host {
    name: "aservice",

    srcs: ["service.cpp"],

    shared_libs: [
        "libcutils",
        "libutils",
        "libbinder",
    ],

    cflags: [
        "-DXP_UNIX",
        "-Wall",
        "-Werror",
    ],
}
+6 −1
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ static String16 get_interface_name(sp<IBinder> service)
{
    if (service != nullptr) {
        Parcel data, reply;
        data.markForBinder(service);
        status_t err = service->transact(IBinder::INTERFACE_TRANSACTION, data, &reply);
        if (err == NO_ERROR) {
            return reply.readString16();
@@ -95,6 +96,9 @@ int main(int argc, char* const argv[])
    }
#ifdef VENDORSERVICES
    ProcessState::initWithDriver("/dev/vndbinder");
#endif
#ifndef __ANDROID__
    setDefaultServiceManager(createRpcDelegateServiceManager({.maxOutgoingThreads = 1}));
#endif
    sp<IServiceManager> sm = defaultServiceManager();
    fflush(stdout);
@@ -138,6 +142,7 @@ int main(int argc, char* const argv[])
                int32_t code = atoi(argv[optind++]);
                if (service != nullptr && ifName.size() > 0) {
                    Parcel data, reply;
                    data.markForBinder(service);

                    // the interface name is first
                    data.writeInterfaceToken(ifName);
@@ -229,7 +234,7 @@ int main(int argc, char* const argv[])
                            int afd = ashmem_create_region("test", statbuf.st_size);
                            void* ptr = mmap(NULL, statbuf.st_size,
                                   PROT_READ | PROT_WRITE, MAP_SHARED, afd, 0);
                            read(fd, ptr, statbuf.st_size);
                            (void)read(fd, ptr, statbuf.st_size);
                            close(fd);
                            data.writeFileDescriptor(afd, true /* take ownership */);
                        } else if (strcmp(argv[optind], "nfd") == 0) {
+12 −6
Original line number Diff line number Diff line
@@ -448,21 +448,27 @@ std::optional<IServiceManager::ConnectionInfo> ServiceManagerShim::getConnection
// on-device service manager.
class ServiceManagerHostShim : public ServiceManagerShim {
public:
    using ServiceManagerShim::ServiceManagerShim;
    ServiceManagerHostShim(const sp<AidlServiceManager>& impl,
                           const RpcDelegateServiceManagerOptions& options)
          : ServiceManagerShim(impl), mOptions(options) {}
    // ServiceManagerShim::getService is based on checkService, so no need to override it.
    sp<IBinder> checkService(const String16& name) const override {
        return getDeviceService({String8(name).c_str()});
        return getDeviceService({String8(name).c_str()}, mOptions);
    }

protected:
    // Override realGetService for ServiceManagerShim::waitForService.
    Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) {
        *_aidl_return = getDeviceService({"-g", name});
        *_aidl_return = getDeviceService({"-g", name}, mOptions);
        return Status::ok();
    }

private:
    RpcDelegateServiceManagerOptions mOptions;
};
sp<IServiceManager> createRpcDelegateServiceManager() {
    auto binder = getDeviceService({"manager"});
sp<IServiceManager> createRpcDelegateServiceManager(
        const RpcDelegateServiceManagerOptions& options) {
    auto binder = getDeviceService({"manager"}, options);
    if (binder == nullptr) {
        ALOGE("getDeviceService(\"manager\") returns null");
        return nullptr;
@@ -472,7 +478,7 @@ sp<IServiceManager> createRpcDelegateServiceManager() {
        ALOGE("getDeviceService(\"manager\") returns non service manager");
        return nullptr;
    }
    return sp<ServiceManagerHostShim>::make(interface);
    return sp<ServiceManagerHostShim>::make(interface, options);
}
#endif

+24 −1
Original line number Diff line number Diff line
@@ -90,6 +90,20 @@ size_t RpcSession::getMaxIncomingThreads() {
    return mMaxIncomingThreads;
}

void RpcSession::setMaxOutgoingThreads(size_t threads) {
    std::lock_guard<std::mutex> _l(mMutex);
    LOG_ALWAYS_FATAL_IF(!mConnections.mOutgoing.empty() || !mConnections.mIncoming.empty(),
                        "Must set max outgoing threads before setting up connections, but has %zu "
                        "client(s) and %zu server(s)",
                        mConnections.mOutgoing.size(), mConnections.mIncoming.size());
    mMaxOutgoingThreads = threads;
}

size_t RpcSession::getMaxOutgoingThreads() {
    std::lock_guard<std::mutex> _l(mMutex);
    return mMaxOutgoingThreads;
}

bool RpcSession::setProtocolVersion(uint32_t version) {
    if (version >= RPC_WIRE_PROTOCOL_VERSION_NEXT &&
        version != RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL) {
@@ -473,6 +487,12 @@ status_t RpcSession::setupClient(const std::function<status_t(const std::vector<
        return status;
    }

    size_t outgoingThreads = std::min(numThreadsAvailable, mMaxOutgoingThreads);
    ALOGI_IF(outgoingThreads != numThreadsAvailable,
             "Server hints client to start %zu outgoing threads, but client will only start %zu "
             "because it is preconfigured to start at most %zu outgoing threads.",
             numThreadsAvailable, outgoingThreads, mMaxOutgoingThreads);

    // TODO(b/189955605): we should add additional sessions dynamically
    // instead of all at once - the other side should be responsible for setting
    // up additional connections. We need to create at least one (unless 0 are
@@ -480,7 +500,10 @@ status_t RpcSession::setupClient(const std::function<status_t(const std::vector<
    // any requests at all.

    // we've already setup one client
    for (size_t i = 0; i + 1 < numThreadsAvailable; i++) {
    LOG_RPC_DETAIL("RpcSession::setupClient() instantiating %zu outgoing (server max: %zu) and %zu "
                   "incoming threads",
                   outgoingThreads, numThreadsAvailable, mMaxIncomingThreads);
    for (size_t i = 0; i + 1 < outgoingThreads; i++) {
        if (status_t status = connectAndInit(mId, false /*incoming*/); status != OK) return status;
    }

+6 −1
Original line number Diff line number Diff line
@@ -124,7 +124,8 @@ void cleanupCommandResult(const void* id, void* obj, void* /* cookie */) {

} // namespace

sp<IBinder> getDeviceService(std::vector<std::string>&& serviceDispatcherArgs) {
sp<IBinder> getDeviceService(std::vector<std::string>&& serviceDispatcherArgs,
                             const RpcDelegateServiceManagerOptions& options) {
    std::vector<std::string> prefix{"adb", "shell", "servicedispatcher"};
    serviceDispatcherArgs.insert(serviceDispatcherArgs.begin(), prefix.begin(), prefix.end());

@@ -158,6 +159,10 @@ sp<IBinder> getDeviceService(std::vector<std::string>&& serviceDispatcherArgs) {
    LOG_ALWAYS_FATAL_IF(!forwardResult->hostPort().has_value());

    auto rpcSession = RpcSession::make();
    if (options.maxOutgoingThreads.has_value()) {
        rpcSession->setMaxOutgoingThreads(*options.maxOutgoingThreads);
    }

    if (status_t status = rpcSession->setupInetClient("127.0.0.1", *forwardResult->hostPort());
        status != OK) {
        ALOGE("Unable to set up inet client on host port %u: %s", *forwardResult->hostPort(),
Loading