resolved conflicts for merge of 070a19e0 to master

Change-Id: I855ab02a4e8dd465af67fd23b66c0dace76bd411
diff --git a/api/current.txt b/api/current.txt
index dd619cf..3339497 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -13924,12 +13924,14 @@
 
   public class ParcelFileDescriptor implements android.os.Parcelable {
     ctor public ParcelFileDescriptor(android.os.ParcelFileDescriptor);
+    method public static android.os.ParcelFileDescriptor adoptFd(int);
     method public void close() throws java.io.IOException;
     method public static android.os.ParcelFileDescriptor[] createPipe() throws java.io.IOException;
     method public int describeContents();
     method public int detachFd();
     method public static android.os.ParcelFileDescriptor dup(java.io.FileDescriptor) throws java.io.IOException;
     method public static android.os.ParcelFileDescriptor fromDatagramSocket(java.net.DatagramSocket);
+    method public static android.os.ParcelFileDescriptor fromFd(int) throws java.io.IOException;
     method public static android.os.ParcelFileDescriptor fromSocket(java.net.Socket);
     method public int getFd();
     method public java.io.FileDescriptor getFileDescriptor();
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 727fcca..3ea3f56 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -129,7 +129,46 @@
     }
 
     /**
-     * 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.
@@ -163,17 +202,14 @@
      */
     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 4ec131c..99a2d04 100644
--- a/core/jni/android_os_ParcelFileDescriptor.cpp
+++ b/core/jni/android_os_ParcelFileDescriptor.cpp
@@ -34,20 +34,37 @@
     jfieldID mFileDescriptor;
 } gParcelFileDescriptorOffsets;
 
-static int android_os_ParcelFileDescriptor_createPipeNative(JNIEnv* env,
+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;
+    }
+    return jniCreateFileDescriptor(env, fd);
+}
+
+static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromFdNoDup(JNIEnv* env,
+    jobject clazz, jint fd)
+{
+    return jniCreateFileDescriptor(env, fd);
+}
+
+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++) {
         jobject fdObj = jniCreateFileDescriptor(env, fds[i]);
         env->SetObjectArrayElement(outFds, i, fdObj);
     }
-
-    return 0;
 }
 
 static jint getFd(JNIEnv* env, jobject clazz)
@@ -102,7 +119,11 @@
 }
 
 static const JNINativeMethod gParcelFileDescriptorMethods[] = {
-    {"createPipeNative", "([Ljava/io/FileDescriptor;)I",
+    {"getFileDescriptorFromFd", "(I)Ljava/io/FileDescriptor;",
+        (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromFd},
+    {"getFileDescriptorFromFdNoDup", "(I)Ljava/io/FileDescriptor;",
+        (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromFdNoDup},
+    {"createPipeNative", "([Ljava/io/FileDescriptor;)V",
         (void*)android_os_ParcelFileDescriptor_createPipeNative},
     {"getStatSize", "()J",
         (void*)android_os_ParcelFileDescriptor_getStatSize},