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 /** 137389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton * Create two ParcelFileDescriptors structured as a data pipe. The first 138389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton * ParcelFileDescriptor in the returned array is the read side; the second 139389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton * is the write side. 140389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton */ 141389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton public static ParcelFileDescriptor[] createPipe() throws IOException { 142389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton FileDescriptor[] fds = new FileDescriptor[2]; 143389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton int res = createPipeNative(fds); 144389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton if (res == 0) { 145389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton ParcelFileDescriptor[] pfds = new ParcelFileDescriptor[2]; 146389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton pfds[0] = new ParcelFileDescriptor(fds[0]); 147389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton pfds[1] = new ParcelFileDescriptor(fds[1]); 148389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton return pfds; 149389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton } 150389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton throw new IOException("Unable to create pipe: errno=" + -res); 151389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton } 152389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton 153389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton private static native int createPipeNative(FileDescriptor[] outFds); 154389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton 155389a440ad13f7b16e8f7c7f1670bdd55f1e2112aJeff Hamilton /** 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Retrieve the actual FileDescriptor associated with this object. 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns the FileDescriptor associated with this object. 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public FileDescriptor getFileDescriptor() { 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFileDescriptor; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the total size of the file representing this fd, as determined 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by stat(). Returns -1 if the fd is not a file. 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native long getStatSize(); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is needed for implementing AssetFileDescriptor.AutoCloseOutputStream, 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and I really don't think we want it to be public. 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public native long seekTo(long pos); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Close the ParcelFileDescriptor. This implementation closes the underlying 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * OS resources allocated to represent this stream. 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If an error occurs attempting to close this ParcelFileDescriptor. 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() throws IOException { 185186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn synchronized (this) { 186186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn if (mClosed) return; 187186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn mClosed = true; 188186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mParcelDescriptor != null) { 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If this is a proxy to another file descriptor, just call through to its 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // close method. 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParcelDescriptor.close(); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Parcel.closeFileDescriptor(mFileDescriptor); 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 InputStream you can create on a ParcelFileDescriptor, which will 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * take care of calling {@link ParcelFileDescriptor#close 201fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * ParcelFileDescriptor.close()} for you when the stream is closed. 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static class AutoCloseInputStream extends FileInputStream { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ParcelFileDescriptor mFd; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AutoCloseInputStream(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 /** 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * An OutputStream you can create on a ParcelFileDescriptor, which will 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * take care of calling {@link ParcelFileDescriptor#close 220fa9e7c05c7be6891a6cf85a11dc635a6e6853078Christopher Tate * ParcelFileDescriptor.close()} for you when the stream is closed. 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static class AutoCloseOutputStream extends FileOutputStream { 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ParcelFileDescriptor mFd; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AutoCloseOutputStream(ParcelFileDescriptor fd) { 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(fd.getFileDescriptor()); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFd = fd; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() throws IOException { 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFd.close(); 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "{ParcelFileDescriptor: " + mFileDescriptor + "}"; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mClosed) { 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ParcelFileDescriptor(ParcelFileDescriptor descriptor) { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(); 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParcelDescriptor = descriptor; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileDescriptor = mParcelDescriptor.mFileDescriptor; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*package */ParcelFileDescriptor(FileDescriptor descriptor) { 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(); 260186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn if (descriptor == null) { 261186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn throw new NullPointerException("descriptor must not be null"); 262186683923ce8d6a2d5c6fd4768b26b90308661e9Dianne Hackborn } 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileDescriptor = descriptor; 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParcelDescriptor = null; 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Parcelable interface */ 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int describeContents() { 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Parcelable.CONTENTS_FILE_DESCRIPTOR; 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 272b3e4ef37021a9e5518fdbc7d0cbb0a1709d5301bDan Egnor /** 273b3e4ef37021a9e5518fdbc7d0cbb0a1709d5301bDan Egnor * {@inheritDoc} 274b3e4ef37021a9e5518fdbc7d0cbb0a1709d5301bDan Egnor * If {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE} is set in flags, 275b3e4ef37021a9e5518fdbc7d0cbb0a1709d5301bDan Egnor * the file descriptor will be closed after a copy is written to the Parcel. 276b3e4ef37021a9e5518fdbc7d0cbb0a1709d5301bDan Egnor */ 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void writeToParcel(Parcel out, int flags) { 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.writeFileDescriptor(mFileDescriptor); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags&PARCELABLE_WRITE_RETURN_VALUE) != 0 && !mClosed) { 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Empty 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Parcelable.Creator<ParcelFileDescriptor> CREATOR 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new Parcelable.Creator<ParcelFileDescriptor>() { 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ParcelFileDescriptor createFromParcel(Parcel in) { 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return in.readFileDescriptor(); 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ParcelFileDescriptor[] newArray(int size) { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new ParcelFileDescriptor[size]; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 299