android_os_ParcelFileDescriptor.cpp revision 076357b8567458d4b6dfdcf839ef751634cd2bfb
1/* //device/libs/android_runtime/android_os_ParcelFileDescriptor.cpp 2** 3** Copyright 2008, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#include "JNIHelp.h" 19 20#include <fcntl.h> 21#include <sys/stat.h> 22#include <stdio.h> 23 24#include <utils/Log.h> 25 26#include <android_runtime/AndroidRuntime.h> 27 28namespace android 29{ 30 31static struct file_descriptor_offsets_t 32{ 33 jclass mClass; 34 jmethodID mConstructor; 35 jfieldID mDescriptor; 36} gFileDescriptorOffsets; 37 38static struct socket_offsets_t 39{ 40 jfieldID mSocketImpl; 41} gSocketOffsets; 42 43static struct socket_impl_offsets_t 44{ 45 jfieldID mFileDescriptor; 46} gSocketImplOffsets; 47 48 49static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromSocket(JNIEnv* env, 50 jobject clazz, jobject object) 51{ 52 jobject socketImpl = env->GetObjectField(object, gSocketOffsets.mSocketImpl); 53 jobject fileDescriptor = env->GetObjectField(socketImpl, gSocketImplOffsets.mFileDescriptor); 54 jint fd = env->GetIntField(fileDescriptor, gFileDescriptorOffsets.mDescriptor); 55 jobject fileDescriptorClone = env->NewObject(gFileDescriptorOffsets.mClass, 56 gFileDescriptorOffsets.mConstructor); 57 if (fileDescriptorClone != NULL) { 58 env->SetIntField(fileDescriptorClone, gFileDescriptorOffsets.mDescriptor, dup(fd)); 59 } 60 return fileDescriptorClone; 61} 62 63static const JNINativeMethod gParcelFileDescriptorMethods[] = { 64 {"getFileDescriptorFromSocket", "(Ljava/net/Socket;)Ljava/io/FileDescriptor;", 65 (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromSocket} 66}; 67 68const char* const kParcelFileDescriptorPathName = "android/os/ParcelFileDescriptor"; 69 70int register_android_os_ParcelFileDescriptor(JNIEnv* env) 71{ 72 jclass clazz; 73 74 clazz = env->FindClass("java/net/Socket"); 75 LOG_FATAL_IF(clazz == NULL, "Unable to find class java.net.Socket"); 76 gSocketOffsets.mSocketImpl = env->GetFieldID(clazz, "impl", "Ljava/net/SocketImpl;"); 77 LOG_FATAL_IF(gSocketOffsets.mSocketImpl == NULL, 78 "Unable to find impl field in java.net.Socket"); 79 80 clazz = env->FindClass("java/net/SocketImpl"); 81 LOG_FATAL_IF(clazz == NULL, "Unable to find class java.net.SocketImpl"); 82 gSocketImplOffsets.mFileDescriptor = env->GetFieldID(clazz, "fd", "Ljava/io/FileDescriptor;"); 83 LOG_FATAL_IF(gSocketImplOffsets.mFileDescriptor == NULL, 84 "Unable to find fd field in java.net.SocketImpl"); 85 86 clazz = env->FindClass("java/io/FileDescriptor"); 87 LOG_FATAL_IF(clazz == NULL, "Unable to find class java.io.FileDescriptor"); 88 gFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz); 89 gFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "()V"); 90 gFileDescriptorOffsets.mDescriptor = env->GetFieldID(clazz, "descriptor", "I"); 91 LOG_FATAL_IF(gFileDescriptorOffsets.mDescriptor == NULL, 92 "Unable to find descriptor field in java.io.FileDescriptor"); 93 94 clazz = env->FindClass(kParcelFileDescriptorPathName); 95 LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor"); 96 97 return AndroidRuntime::registerNativeMethods( 98 env, kParcelFileDescriptorPathName, 99 gParcelFileDescriptorMethods, NELEM(gParcelFileDescriptorMethods)); 100} 101 102} 103