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

Commit 4390758f authored by Elliott Hughes's avatar Elliott Hughes
Browse files

Use an @hide libcore API to get the FileDescriptor from a Socket.

Saves having your own native code...

Change-Id: Ib082a6530bcf743a35031500cee6318bc92d4d35
parent d3a6956a
Loading
Loading
Loading
Loading
+32 −35
Original line number Diff line number Diff line
@@ -137,13 +137,10 @@ public class ParcelFileDescriptor implements Parcelable {
     *         specified Socket.
     */
    public static ParcelFileDescriptor fromSocket(Socket socket) {
        FileDescriptor fd = getFileDescriptorFromSocket(socket);
        FileDescriptor fd = socket.getFileDescriptor$();
        return fd != null ? new ParcelFileDescriptor(fd) : null;
    }

    // Extracts the file descriptor from the specified socket and returns it untouched
    private static native FileDescriptor getFileDescriptorFromSocket(Socket socket);

    /**
     * Create two ParcelFileDescriptors structured as a data pipe.  The first
     * ParcelFileDescriptor in the returned array is the read side; the second
+1 −38
Original line number Diff line number Diff line
@@ -29,31 +29,11 @@
namespace android
{

static struct socket_offsets_t
{
    jfieldID mSocketImpl;
} gSocketOffsets;

static struct socket_impl_offsets_t
{
    jfieldID mFileDescriptor;
} gSocketImplOffsets;

static struct parcel_file_descriptor_offsets_t
{
    jclass mClass;
    jfieldID mFileDescriptor;
} gParcelFileDescriptorOffsets;

static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromSocket(JNIEnv* env,
    jobject clazz, jobject object)
{
    jobject socketImpl = env->GetObjectField(object, gSocketOffsets.mSocketImpl);
    jobject fileDescriptor = env->GetObjectField(socketImpl, gSocketImplOffsets.mFileDescriptor);
    jint fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
    return jniCreateFileDescriptor(env, dup(fd));
}

static int android_os_ParcelFileDescriptor_createPipeNative(JNIEnv* env,
    jobject clazz, jobjectArray outFds)
{
@@ -122,8 +102,6 @@ static jlong android_os_ParcelFileDescriptor_getFdNative(JNIEnv* env, jobject cl
}

static const JNINativeMethod gParcelFileDescriptorMethods[] = {
    {"getFileDescriptorFromSocket", "(Ljava/net/Socket;)Ljava/io/FileDescriptor;",
        (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromSocket},
    {"createPipeNative", "([Ljava/io/FileDescriptor;)I",
        (void*)android_os_ParcelFileDescriptor_createPipeNative},
    {"getStatSize", "()J",
@@ -138,23 +116,8 @@ const char* const kParcelFileDescriptorPathName = "android/os/ParcelFileDescript

int register_android_os_ParcelFileDescriptor(JNIEnv* env)
{
    jclass clazz;

    clazz = env->FindClass("java/net/Socket");
    LOG_FATAL_IF(clazz == NULL, "Unable to find class java.net.Socket");
    gSocketOffsets.mSocketImpl = env->GetFieldID(clazz, "impl", "Ljava/net/SocketImpl;");
    LOG_FATAL_IF(gSocketOffsets.mSocketImpl == NULL,
        "Unable to find impl field in java.net.Socket");

    clazz = env->FindClass("java/net/SocketImpl");
    LOG_FATAL_IF(clazz == NULL, "Unable to find class java.net.SocketImpl");
    gSocketImplOffsets.mFileDescriptor = env->GetFieldID(clazz, "fd", "Ljava/io/FileDescriptor;");
    LOG_FATAL_IF(gSocketImplOffsets.mFileDescriptor == NULL,
                 "Unable to find fd field in java.net.SocketImpl");

    clazz = env->FindClass(kParcelFileDescriptorPathName);
    jclass clazz = env->FindClass(kParcelFileDescriptorPathName);
    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor");
    gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
    gParcelFileDescriptorOffsets.mFileDescriptor = env->GetFieldID(clazz, "mFileDescriptor", "Ljava/io/FileDescriptor;");
    LOG_FATAL_IF(gParcelFileDescriptorOffsets.mFileDescriptor == NULL,
                 "Unable to find mFileDescriptor field in android.os.ParcelFileDescriptor");