diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-02-28 18:03:26 -0800 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2011-02-28 18:03:26 -0800 |
commit | c9119f5034d36f548bbddd8f60291e24ab4e270b (patch) | |
tree | 040920e1f2474bcc7c8aa460377c976baa684488 | |
parent | 6c2193a7e26c0794f45dfb60d2a0cf6ae776f390 (diff) | |
download | frameworks_base-c9119f5034d36f548bbddd8f60291e24ab4e270b.zip frameworks_base-c9119f5034d36f548bbddd8f60291e24ab4e270b.tar.gz frameworks_base-c9119f5034d36f548bbddd8f60291e24ab4e270b.tar.bz2 |
Add ParcelFileDescriptor APIs to get raw fd.
Change-Id: I66ba72ffffd27237e60c9411453eef950ae62705
-rw-r--r-- | api/current.xml | 22 | ||||
-rw-r--r-- | core/java/android/os/Parcel.java | 1 | ||||
-rw-r--r-- | core/java/android/os/ParcelFileDescriptor.java | 34 | ||||
-rw-r--r-- | core/jni/android_os_ParcelFileDescriptor.cpp | 15 | ||||
-rw-r--r-- | core/jni/android_util_Binder.cpp | 9 |
5 files changed, 80 insertions, 1 deletions
diff --git a/api/current.xml b/api/current.xml index 2c97892..c007659 100644 --- a/api/current.xml +++ b/api/current.xml @@ -149691,6 +149691,17 @@ visibility="public" > </method> +<method name="detachFd" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="fromSocket" return="android.os.ParcelFileDescriptor" abstract="false" @@ -149704,6 +149715,17 @@ <parameter name="socket" type="java.net.Socket"> </parameter> </method> +<method name="getFd" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getFileDescriptor" return="java.io.FileDescriptor" abstract="false" diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 8944f12..eca3484 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -1385,6 +1385,7 @@ public final class Parcel { int mode) throws FileNotFoundException; /*package*/ static native void closeFileDescriptor(FileDescriptor desc) throws IOException; + /*package*/ static native void clearFileDescriptor(FileDescriptor desc); /** * Read a byte value from the parcel at the current dataPosition(). diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java index 3a5d26b..5bd129f 100644 --- a/core/java/android/os/ParcelFileDescriptor.java +++ b/core/java/android/os/ParcelFileDescriptor.java @@ -197,6 +197,40 @@ public class ParcelFileDescriptor implements Parcelable { public native long seekTo(long pos); /** + * Return the native fd int for this ParcelFileDescriptor. The + * ParcelFileDescriptor still owns the fd, and it still must be closed + * through this API. + */ + public int getFd() { + if (mClosed) { + throw new IllegalStateException("Already closed"); + } + return getFdNative(); + } + + private native int getFdNative(); + + /** + * Return the native fd int for this ParcelFileDescriptor and detach it + * from the object here. You are now responsible for closing the fd in + * native code. + */ + public int detachFd() { + if (mClosed) { + throw new IllegalStateException("Already closed"); + } + if (mParcelDescriptor != null) { + int fd = mParcelDescriptor.detachFd(); + mClosed = true; + return fd; + } + int fd = getFd(); + mClosed = true; + Parcel.clearFileDescriptor(mFileDescriptor); + return fd; + } + + /** * Close the ParcelFileDescriptor. This implementation closes the underlying * OS resources allocated to represent this stream. * diff --git a/core/jni/android_os_ParcelFileDescriptor.cpp b/core/jni/android_os_ParcelFileDescriptor.cpp index eceef1c..1f737f9 100644 --- a/core/jni/android_os_ParcelFileDescriptor.cpp +++ b/core/jni/android_os_ParcelFileDescriptor.cpp @@ -126,6 +126,17 @@ static jlong android_os_ParcelFileDescriptor_seekTo(JNIEnv* env, return lseek(fd, pos, SEEK_SET); } +static jlong android_os_ParcelFileDescriptor_getFdNative(JNIEnv* env, jobject clazz) +{ + jint fd = getFd(env, clazz); + if (fd < 0) { + jniThrowException(env, "java/lang/IllegalArgumentException", "bad file descriptor"); + return -1; + } + + return fd; +} + static const JNINativeMethod gParcelFileDescriptorMethods[] = { {"getFileDescriptorFromSocket", "(Ljava/net/Socket;)Ljava/io/FileDescriptor;", (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromSocket}, @@ -134,7 +145,9 @@ static const JNINativeMethod gParcelFileDescriptorMethods[] = { {"getStatSize", "()J", (void*)android_os_ParcelFileDescriptor_getStatSize}, {"seekTo", "(J)J", - (void*)android_os_ParcelFileDescriptor_seekTo} + (void*)android_os_ParcelFileDescriptor_seekTo}, + {"getFdNative", "()I", + (void*)android_os_ParcelFileDescriptor_getFdNative} }; const char* const kParcelFileDescriptorPathName = "android/os/ParcelFileDescriptor"; diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 7226e31..15362eb 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -1520,6 +1520,14 @@ static void android_os_Parcel_closeFileDescriptor(JNIEnv* env, jobject clazz, jo } } +static void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jobject clazz, jobject object) +{ + int fd = env->GetIntField(object, gFileDescriptorOffsets.mDescriptor); + if (fd >= 0) { + env->SetIntField(object, gFileDescriptorOffsets.mDescriptor, -1); + } +} + static void android_os_Parcel_freeBuffer(JNIEnv* env, jobject clazz) { int32_t own = env->GetIntField(clazz, gParcelOffsets.mOwnObject); @@ -1719,6 +1727,7 @@ static const JNINativeMethod gParcelMethods[] = { {"internalReadFileDescriptor", "()Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor}, {"openFileDescriptor", "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor}, {"closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor}, + {"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor}, {"freeBuffer", "()V", (void*)android_os_Parcel_freeBuffer}, {"init", "(I)V", (void*)android_os_Parcel_init}, {"destroy", "()V", (void*)android_os_Parcel_destroy}, |