am 5c8caba2: am 1b144e62: Merge "Add ParcelFileDescriptor.fromFd() and .adoptFd()." into honeycomb-mr2

* commit '5c8caba2e590792531ffb2c9f4ea924993662abd':
  Add ParcelFileDescriptor.fromFd() and .adoptFd().
This commit is contained in:
Dianne Hackborn
2011-05-20 16:13:54 -07:00
committed by Android Git Automerger
3 changed files with 111 additions and 15 deletions

View File

@ -150314,6 +150314,19 @@
<parameter name="descriptor" type="android.os.ParcelFileDescriptor"> <parameter name="descriptor" type="android.os.ParcelFileDescriptor">
</parameter> </parameter>
</constructor> </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" <method name="close"
return="void" return="void"
abstract="false" abstract="false"
@ -150377,6 +150390,21 @@
<exception name="IOException" type="java.io.IOException"> <exception name="IOException" type="java.io.IOException">
</exception> </exception>
</method> </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" <method name="fromSocket"
return="android.os.ParcelFileDescriptor" return="android.os.ParcelFileDescriptor"
abstract="false" abstract="false"

View File

@ -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 * @param socket The Socket whose FileDescriptor is used to create
* a new ParcelFileDescriptor. * a new ParcelFileDescriptor.
@ -151,17 +190,14 @@ public class ParcelFileDescriptor implements Parcelable {
*/ */
public static ParcelFileDescriptor[] createPipe() throws IOException { public static ParcelFileDescriptor[] createPipe() throws IOException {
FileDescriptor[] fds = new FileDescriptor[2]; FileDescriptor[] fds = new FileDescriptor[2];
int res = createPipeNative(fds); createPipeNative(fds);
if (res == 0) {
ParcelFileDescriptor[] pfds = new ParcelFileDescriptor[2]; ParcelFileDescriptor[] pfds = new ParcelFileDescriptor[2];
pfds[0] = new ParcelFileDescriptor(fds[0]); pfds[0] = new ParcelFileDescriptor(fds[0]);
pfds[1] = new ParcelFileDescriptor(fds[1]); pfds[1] = new ParcelFileDescriptor(fds[1]);
return pfds; return pfds;
} }
throw new IOException("Unable to create pipe: errno=" + -res);
}
private static native int createPipeNative(FileDescriptor[] outFds); private static native void createPipeNative(FileDescriptor[] outFds) throws IOException;
/** /**
* @hide Please use createPipe() or ContentProvider.openPipeHelper(). * @hide Please use createPipe() or ContentProvider.openPipeHelper().

View File

@ -52,6 +52,33 @@ static struct parcel_file_descriptor_offsets_t
jfieldID mFileDescriptor; jfieldID mFileDescriptor;
} gParcelFileDescriptorOffsets; } 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, static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromSocket(JNIEnv* env,
jobject clazz, jobject object) jobject clazz, jobject object)
{ {
@ -61,17 +88,20 @@ static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromSocket(JNIEn
jobject fileDescriptorClone = env->NewObject(gFileDescriptorOffsets.mClass, jobject fileDescriptorClone = env->NewObject(gFileDescriptorOffsets.mClass,
gFileDescriptorOffsets.mConstructor); gFileDescriptorOffsets.mConstructor);
if (fileDescriptorClone != NULL) { if (fileDescriptorClone != NULL) {
// XXXX need to throw an exception if the dup fails!
env->SetIntField(fileDescriptorClone, gFileDescriptorOffsets.mDescriptor, dup(fd)); env->SetIntField(fileDescriptorClone, gFileDescriptorOffsets.mDescriptor, dup(fd));
} }
return fileDescriptorClone; return fileDescriptorClone;
} }
static int android_os_ParcelFileDescriptor_createPipeNative(JNIEnv* env, static void android_os_ParcelFileDescriptor_createPipeNative(JNIEnv* env,
jobject clazz, jobjectArray outFds) jobject clazz, jobjectArray outFds)
{ {
int fds[2]; int fds[2];
if (pipe(fds) < 0) { if (pipe(fds) < 0) {
return -errno; int therr = errno;
jniThrowException(env, "java/io/IOException", strerror(therr));
return;
} }
for (int i=0; i<2; i++) { for (int i=0; i<2; i++) {
@ -82,8 +112,6 @@ static int android_os_ParcelFileDescriptor_createPipeNative(JNIEnv* env,
} }
env->SetObjectArrayElement(outFds, i, fdObj); env->SetObjectArrayElement(outFds, i, fdObj);
} }
return 0;
} }
static jint getFd(JNIEnv* env, jobject clazz) 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[] = { 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;", {"getFileDescriptorFromSocket", "(Ljava/net/Socket;)Ljava/io/FileDescriptor;",
(void*)android_os_ParcelFileDescriptor_getFileDescriptorFromSocket}, (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromSocket},
{"createPipeNative", "([Ljava/io/FileDescriptor;)I", {"createPipeNative", "([Ljava/io/FileDescriptor;)V",
(void*)android_os_ParcelFileDescriptor_createPipeNative}, (void*)android_os_ParcelFileDescriptor_createPipeNative},
{"getStatSize", "()J", {"getStatSize", "()J",
(void*)android_os_ParcelFileDescriptor_getStatSize}, (void*)android_os_ParcelFileDescriptor_getStatSize},