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

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

Merge "Revert "RpcSession attaches/detaches JVM for Java thread"" am: a474aaf3 am: 60aa427c

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

Change-Id: I1ac303c5d8820f9328c642d3cb0cf18805b3d309
parents 83a5bb6e 60aa427c
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -189,7 +189,6 @@ cc_library {

    header_libs: [
        "libbinder_headers",
        "libandroid_runtime_threads_headers",
    ],

    export_header_lib_headers: [
+0 −46
Original line number Diff line number Diff line
@@ -18,16 +18,13 @@

#include <binder/RpcSession.h>

#include <dlfcn.h>
#include <inttypes.h>
#include <poll.h>
#include <pthread.h>
#include <unistd.h>

#include <string_view>

#include <android-base/macros.h>
#include <android_runtime/threads.h>
#include <binder/Parcel.h>
#include <binder/RpcServer.h>
#include <binder/Stability.h>
@@ -277,53 +274,10 @@ RpcSession::PreJoinSetupResult RpcSession::preJoinSetup(base::unique_fd fd) {
    };
}

namespace {
// RAII object for attaching / detaching current thread to JVM if Android Runtime exists. If
// Android Runtime doesn't exist, no-op.
class JavaThreadAttacher {
public:
    JavaThreadAttacher() {
        // Use dlsym to find androidJavaAttachThread because libandroid_runtime is loaded after
        // libbinder.
        static auto attachFn = reinterpret_cast<decltype(&androidJavaAttachThread)>(
                dlsym(RTLD_DEFAULT, "androidJavaAttachThread"));
        if (attachFn == nullptr) return;

        char buf[16];
        const char* threadName = "UnknownRpcSessionThread"; // default thread name
        if (0 == pthread_getname_np(pthread_self(), buf, sizeof(buf))) {
            threadName = buf;
        }
        LOG_RPC_DETAIL("Attaching current thread %s to JVM", threadName);
        LOG_ALWAYS_FATAL_IF(!attachFn(threadName), "Cannot attach thread %s to JVM", threadName);
        mAttached = true;
    }
    ~JavaThreadAttacher() {
        if (!mAttached) return;
        static auto detachFn = reinterpret_cast<decltype(&androidJavaDetachThread)>(
                dlsym(RTLD_DEFAULT, "androidJavaDetachThread"));
        LOG_ALWAYS_FATAL_IF(detachFn == nullptr,
                            "androidJavaAttachThread exists but androidJavaDetachThread doesn't");

        LOG_RPC_DETAIL("Detaching current thread from JVM");
        if (detachFn()) {
            mAttached = false;
        } else {
            ALOGW("Unable to detach current thread from JVM");
        }
    }

private:
    DISALLOW_COPY_AND_ASSIGN(JavaThreadAttacher);
    bool mAttached = false;
};
} // namespace

void RpcSession::join(sp<RpcSession>&& session, PreJoinSetupResult&& setupResult) {
    sp<RpcConnection>& connection = setupResult.connection;

    if (setupResult.status == OK) {
        JavaThreadAttacher javaThreadAttacher;
        while (true) {
            status_t status = session->state()->getAndExecuteCommand(connection, session,
                                                                     RpcState::CommandType::ANY);
+0 −37
Original line number Diff line number Diff line
@@ -1208,43 +1208,6 @@ TEST(BinderRpc, Shutdown) {
            << "After server->shutdown() returns true, join() did not stop after 2s";
}

TEST(BinderRpc, Java) {
#if !defined(__ANDROID__)
    GTEST_SKIP() << "This test is only run on Android. Though it can technically run on host on"
                    "createRpcDelegateServiceManager() with a device attached, such test belongs "
                    "to binderHostDeviceTest. Hence, just disable this test on host.";
#endif // !__ANDROID__
    sp<IServiceManager> sm = defaultServiceManager();
    ASSERT_NE(nullptr, sm);
    // Any Java service with non-empty getInterfaceDescriptor() would do.
    // Let's pick batteryproperties.
    auto binder = sm->checkService(String16("batteryproperties"));
    ASSERT_NE(nullptr, binder);
    auto descriptor = binder->getInterfaceDescriptor();
    ASSERT_GE(descriptor.size(), 0);
    ASSERT_EQ(OK, binder->pingBinder());

    auto rpcServer = RpcServer::make();
    rpcServer->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
    unsigned int port;
    ASSERT_TRUE(rpcServer->setupInetServer(0, &port));
    auto socket = rpcServer->releaseServer();

    auto keepAlive = sp<BBinder>::make();
    ASSERT_EQ(OK, binder->setRpcClientDebug(std::move(socket), keepAlive));

    auto rpcSession = RpcSession::make();
    ASSERT_TRUE(rpcSession->setupInetClient("127.0.0.1", port));
    auto rpcBinder = rpcSession->getRootObject();
    ASSERT_NE(nullptr, rpcBinder);

    ASSERT_EQ(OK, rpcBinder->pingBinder());

    ASSERT_EQ(descriptor, rpcBinder->getInterfaceDescriptor())
            << "getInterfaceDescriptor should not crash system_server";
    ASSERT_EQ(OK, rpcBinder->pingBinder());
}

} // namespace android

int main(int argc, char** argv) {