ParcelFileDescriptor.java revision b3e4ef37021a9e5518fdbc7d0cbb0a1709d5301b
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.os;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File;
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileOutputStream;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.Socket;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The FileDescriptor returned by {@link Parcel#readFileDescriptor}, allowing
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you to close it when done with it.
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ParcelFileDescriptor implements Parcelable {
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final FileDescriptor mFileDescriptor;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mClosed;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //this field is to create wrapper for ParcelFileDescriptor using another
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //PartialFileDescriptor but avoid invoking close twice
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //consider ParcelFileDescriptor A(fileDescriptor fd),  ParcelFileDescriptor B(A)
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //in this particular case fd.close might be invoked twice.
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final ParcelFileDescriptor mParcelDescriptor;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and this file doesn't already exist, then create the file with
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * permissions such that any application can read it.
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int MODE_WORLD_READABLE = 0x00000001;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and this file doesn't already exist, then create the file with
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * permissions such that any application can write it.
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int MODE_WORLD_WRITEABLE = 0x00000002;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For use with {@link #open}: open the file with read-only access.
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int MODE_READ_ONLY = 0x10000000;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For use with {@link #open}: open the file with write-only access.
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int MODE_WRITE_ONLY = 0x20000000;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For use with {@link #open}: open the file with read and write access.
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int MODE_READ_WRITE = 0x30000000;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For use with {@link #open}: create the file if it doesn't already exist.
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int MODE_CREATE = 0x08000000;
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For use with {@link #open}: erase contents of file when opening.
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int MODE_TRUNCATE = 0x04000000;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For use with {@link #open}: append to end of file while writing.
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int MODE_APPEND = 0x02000000;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a new ParcelFileDescriptor accessing a given file.
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param file The file to be opened.
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mode The desired access mode, must be one of
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #MODE_READ_ONLY}, {@link #MODE_WRITE_ONLY}, or
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #MODE_READ_WRITE}; may also be any combination of
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #MODE_CREATE}, {@link #MODE_TRUNCATE},
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #MODE_WORLD_READABLE}, and {@link #MODE_WORLD_WRITEABLE}.
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a new ParcelFileDescriptor pointing to the given
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * file.
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws FileNotFoundException Throws FileNotFoundException if the given
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * file does not exist or can not be opened with the requested mode.
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static ParcelFileDescriptor open(File file, int mode)
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws FileNotFoundException {
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String path = file.getPath();
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SecurityManager security = System.getSecurityManager();
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (security != null) {
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            security.checkRead(path);
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((mode&MODE_WRITE_ONLY) != 0) {
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                security.checkWrite(path);
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((mode&MODE_READ_WRITE) == 0) {
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException(
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "Must specify MODE_READ_ONLY, MODE_WRITE_ONLY, or MODE_READ_WRITE");
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        FileDescriptor fd = Parcel.openFileDescriptor(path, mode);
116186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn        return fd != null ? new ParcelFileDescriptor(fd) : null;
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create a new ParcelFileDescriptor from the specified Socket.
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param socket The Socket whose FileDescriptor is used to create
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *               a new ParcelFileDescriptor.
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return A new ParcelFileDescriptor with the FileDescriptor of the
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         specified Socket.
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static ParcelFileDescriptor fromSocket(Socket socket) {
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        FileDescriptor fd = getFileDescriptorFromSocket(socket);
130186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn        return fd != null ? new ParcelFileDescriptor(fd) : null;
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Extracts the file descriptor from the specified socket and returns it untouched
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static native FileDescriptor getFileDescriptorFromSocket(Socket socket);
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Retrieve the actual FileDescriptor associated with this object.
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns the FileDescriptor associated with this object.
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public FileDescriptor getFileDescriptor() {
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mFileDescriptor;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the total size of the file representing this fd, as determined
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * by stat().  Returns -1 if the fd is not a file.
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native long getStatSize();
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is needed for implementing AssetFileDescriptor.AutoCloseOutputStream,
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and I really don't think we want it to be public.
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public native long seekTo(long pos);
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Close the ParcelFileDescriptor. This implementation closes the underlying
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * OS resources allocated to represent this stream.
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @throws IOException
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *             If an error occurs attempting to close this ParcelFileDescriptor.
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void close() throws IOException {
166186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn        synchronized (this) {
167186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn            if (mClosed) return;
168186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn            mClosed = true;
169186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn        }
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mParcelDescriptor != null) {
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If this is a proxy to another file descriptor, just call through to its
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // close method.
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mParcelDescriptor.close();
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Parcel.closeFileDescriptor(mFileDescriptor);
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * An InputStream you can create on a ParcelFileDescriptor, which will
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * take care of calling {@link ParcelFileDescriptor#close
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ParcelFileDescritor.close()} for you when the stream is closed.
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class AutoCloseInputStream extends FileInputStream {
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final ParcelFileDescriptor mFd;
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public AutoCloseInputStream(ParcelFileDescriptor fd) {
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(fd.getFileDescriptor());
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFd = fd;
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void close() throws IOException {
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFd.close();
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * An OutputStream you can create on a ParcelFileDescriptor, which will
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * take care of calling {@link ParcelFileDescriptor#close
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * ParcelFileDescritor.close()} for you when the stream is closed.
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class AutoCloseOutputStream extends FileOutputStream {
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final ParcelFileDescriptor mFd;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public AutoCloseOutputStream(ParcelFileDescriptor fd) {
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(fd.getFileDescriptor());
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFd = fd;
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void close() throws IOException {
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFd.close();
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String toString() {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return "{ParcelFileDescriptor: " + mFileDescriptor + "}";
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void finalize() throws Throwable {
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mClosed) {
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                close();
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super.finalize();
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ParcelFileDescriptor(ParcelFileDescriptor descriptor) {
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super();
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mParcelDescriptor = descriptor;
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFileDescriptor = mParcelDescriptor.mFileDescriptor;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package */ParcelFileDescriptor(FileDescriptor descriptor) {
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super();
241186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn        if (descriptor == null) {
242186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn            throw new NullPointerException("descriptor must not be null");
243186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn        }
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFileDescriptor = descriptor;
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mParcelDescriptor = null;
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Parcelable interface */
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int describeContents() {
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return Parcelable.CONTENTS_FILE_DESCRIPTOR;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
253b3e4ef37021a9e5518fdbc7d0cbb0a1709d5301bDan Egnor    /**
254b3e4ef37021a9e5518fdbc7d0cbb0a1709d5301bDan Egnor     * {@inheritDoc}
255b3e4ef37021a9e5518fdbc7d0cbb0a1709d5301bDan Egnor     * If {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set in flags,
256b3e4ef37021a9e5518fdbc7d0cbb0a1709d5301bDan Egnor     * the file descriptor will be closed after a copy is written to the Parcel.
257b3e4ef37021a9e5518fdbc7d0cbb0a1709d5301bDan Egnor     */
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void writeToParcel(Parcel out, int flags) {
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        out.writeFileDescriptor(mFileDescriptor);
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((flags&PARCELABLE_WRITE_RETURN_VALUE) != 0 && !mClosed) {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                close();
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (IOException e) {
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Empty
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final Parcelable.Creator<ParcelFileDescriptor> CREATOR
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            = new Parcelable.Creator<ParcelFileDescriptor>() {
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ParcelFileDescriptor createFromParcel(Parcel in) {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return in.readFileDescriptor();
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ParcelFileDescriptor[] newArray(int size) {
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new ParcelFileDescriptor[size];
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
280