summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2011-05-20 10:37:34 -0700
committerDianne Hackborn <hackbod@google.com>2011-05-20 12:48:22 -0700
commitea2117bdc03316a9292e2344c6fd157c85c13167 (patch)
treef1bc6b8428311c333b94d08e58c17ede1b2e54d5
parent69cb87576ba163b61bb0e6477a3b7c57a9b11d40 (diff)
downloadframeworks_base-ea2117bdc03316a9292e2344c6fd157c85c13167.zip
frameworks_base-ea2117bdc03316a9292e2344c6fd157c85c13167.tar.gz
frameworks_base-ea2117bdc03316a9292e2344c6fd157c85c13167.tar.bz2
Add ParcelFileDescriptor.fromFd() and .adoptFd().
Change-Id: I2fe0429188dc80abaa0c8977f2e43a010e0f4da2
-rw-r--r--api/current.xml28
-rw-r--r--core/java/android/os/ParcelFileDescriptor.java56
-rw-r--r--core/jni/android_os_ParcelFileDescriptor.cpp42
3 files changed, 111 insertions, 15 deletions
diff --git a/api/current.xml b/api/current.xml
index a44442a..a7555da 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -150303,6 +150303,19 @@
<parameter name="descriptor" type="android.os.ParcelFileDescriptor">
</parameter>
</constructor>
+<method name="adoptFd"
+ return="android.os.ParcelFileDescriptor"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fd" type="int">
+</parameter>
+</method>
<method name="close"
return="void"
abstract="false"
@@ -150366,6 +150379,21 @@
<exception name="IOException" type="java.io.IOException">
</exception>
</method>
+<method name="fromFd"
+ return="android.os.ParcelFileDescriptor"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fd" type="int">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
<method name="fromSocket"
return="android.os.ParcelFileDescriptor"
abstract="false"
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index aa959b4..0f1354b 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -128,7 +128,46 @@ public class ParcelFileDescriptor implements Parcelable {
}
/**
- * Create a new ParcelFileDescriptor from the specified Socket.
+ * Create a new ParcelFileDescriptor from a raw native fd. The new
+ * ParcelFileDescriptor holds a dup of the original fd passed in here,
+ * so you must still close that fd as well as the new ParcelFileDescriptor.
+ *
+ * @param fd The native fd that the ParcelFileDescriptor should dup.
+ *
+ * @return Returns a new ParcelFileDescriptor holding a FileDescriptor
+ * for a dup of the given fd.
+ */
+ public static ParcelFileDescriptor fromFd(int fd) throws IOException {
+ FileDescriptor fdesc = getFileDescriptorFromFd(fd);
+ return new ParcelFileDescriptor(fdesc);
+ }
+
+ // Extracts the file descriptor from the specified socket and returns it untouched
+ private static native FileDescriptor getFileDescriptorFromFd(int fd) throws IOException;
+
+ /**
+ * Take ownership of a raw native fd in to a new ParcelFileDescriptor.
+ * The returned ParcelFileDescriptor now owns the given fd, and will be
+ * responsible for closing it. You must not close the fd yourself.
+ *
+ * @param fd The native fd that the ParcelFileDescriptor should adopt.
+ *
+ * @return Returns a new ParcelFileDescriptor holding a FileDescriptor
+ * for the given fd.
+ */
+ public static ParcelFileDescriptor adoptFd(int fd) {
+ FileDescriptor fdesc = getFileDescriptorFromFdNoDup(fd);
+ return new ParcelFileDescriptor(fdesc);
+ }
+
+ // Extracts the file descriptor from the specified socket and returns it untouched
+ private static native FileDescriptor getFileDescriptorFromFdNoDup(int fd);
+
+ /**
+ * Create a new ParcelFileDescriptor from the specified Socket. The new
+ * ParcelFileDescriptor holds a dup of the original FileDescriptor in
+ * the Socket, so you must still close the Socket as well as the new
+ * ParcelFileDescriptor.
*
* @param socket The Socket whose FileDescriptor is used to create
* a new ParcelFileDescriptor.
@@ -151,17 +190,14 @@ public class ParcelFileDescriptor implements Parcelable {
*/
public static ParcelFileDescriptor[] createPipe() throws IOException {
FileDescriptor[] fds = new FileDescriptor[2];
- int res = createPipeNative(fds);
- if (res == 0) {
- ParcelFileDescriptor[] pfds = new ParcelFileDescriptor[2];
- pfds[0] = new ParcelFileDescriptor(fds[0]);
- pfds[1] = new ParcelFileDescriptor(fds[1]);
- return pfds;
- }
- throw new IOException("Unable to create pipe: errno=" + -res);
+ createPipeNative(fds);
+ ParcelFileDescriptor[] pfds = new ParcelFileDescriptor[2];
+ pfds[0] = new ParcelFileDescriptor(fds[0]);
+ pfds[1] = new ParcelFileDescriptor(fds[1]);
+ return pfds;
}
- private static native int createPipeNative(FileDescriptor[] outFds);
+ private static native void createPipeNative(FileDescriptor[] outFds) throws IOException;
/**
* @hide Please use createPipe() or ContentProvider.openPipeHelper().
diff --git a/core/jni/android_os_ParcelFileDescriptor.cpp b/core/jni/android_os_ParcelFileDescriptor.cpp
index 1f737f9..e73d30b 100644
--- a/core/jni/android_os_ParcelFileDescriptor.cpp
+++ b/core/jni/android_os_ParcelFileDescriptor.cpp
@@ -52,6 +52,33 @@ static struct parcel_file_descriptor_offsets_t
jfieldID mFileDescriptor;
} gParcelFileDescriptorOffsets;
+static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromFd(JNIEnv* env,
+ jobject clazz, jint origfd)
+{
+ int fd = dup(origfd);
+ if (fd < 0) {
+ jniThrowException(env, "java/io/IOException", strerror(errno));
+ return NULL;
+ }
+ jobject fileDescriptorClone = env->NewObject(gFileDescriptorOffsets.mClass,
+ gFileDescriptorOffsets.mConstructor);
+ if (fileDescriptorClone != NULL) {
+ env->SetIntField(fileDescriptorClone, gFileDescriptorOffsets.mDescriptor, fd);
+ }
+ return fileDescriptorClone;
+}
+
+static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromFdNoDup(JNIEnv* env,
+ jobject clazz, jint fd)
+{
+ jobject fileDescriptorClone = env->NewObject(gFileDescriptorOffsets.mClass,
+ gFileDescriptorOffsets.mConstructor);
+ if (fileDescriptorClone != NULL) {
+ env->SetIntField(fileDescriptorClone, gFileDescriptorOffsets.mDescriptor, fd);
+ }
+ return fileDescriptorClone;
+}
+
static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromSocket(JNIEnv* env,
jobject clazz, jobject object)
{
@@ -61,17 +88,20 @@ static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromSocket(JNIEn
jobject fileDescriptorClone = env->NewObject(gFileDescriptorOffsets.mClass,
gFileDescriptorOffsets.mConstructor);
if (fileDescriptorClone != NULL) {
+ // XXXX need to throw an exception if the dup fails!
env->SetIntField(fileDescriptorClone, gFileDescriptorOffsets.mDescriptor, dup(fd));
}
return fileDescriptorClone;
}
-static int android_os_ParcelFileDescriptor_createPipeNative(JNIEnv* env,
+static void android_os_ParcelFileDescriptor_createPipeNative(JNIEnv* env,
jobject clazz, jobjectArray outFds)
{
int fds[2];
if (pipe(fds) < 0) {
- return -errno;
+ int therr = errno;
+ jniThrowException(env, "java/io/IOException", strerror(therr));
+ return;
}
for (int i=0; i<2; i++) {
@@ -82,8 +112,6 @@ static int android_os_ParcelFileDescriptor_createPipeNative(JNIEnv* env,
}
env->SetObjectArrayElement(outFds, i, fdObj);
}
-
- return 0;
}
static jint getFd(JNIEnv* env, jobject clazz)
@@ -138,9 +166,13 @@ static jlong android_os_ParcelFileDescriptor_getFdNative(JNIEnv* env, jobject cl
}
static const JNINativeMethod gParcelFileDescriptorMethods[] = {
+ {"getFileDescriptorFromFd", "(I)Ljava/io/FileDescriptor;",
+ (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromFd},
+ {"getFileDescriptorFromFdNoDup", "(I)Ljava/io/FileDescriptor;",
+ (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromFdNoDup},
{"getFileDescriptorFromSocket", "(Ljava/net/Socket;)Ljava/io/FileDescriptor;",
(void*)android_os_ParcelFileDescriptor_getFileDescriptorFromSocket},
- {"createPipeNative", "([Ljava/io/FileDescriptor;)I",
+ {"createPipeNative", "([Ljava/io/FileDescriptor;)V",
(void*)android_os_ParcelFileDescriptor_createPipeNative},
{"getStatSize", "()J",
(void*)android_os_ParcelFileDescriptor_getStatSize},