Loading core/java/android/content/ContentProvider.java +15 −22 Original line number Diff line number Diff line Loading @@ -1885,9 +1885,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * in {@link android.provider.MediaStore.MediaColumns}.</p> * * @param uri The URI whose file is to be opened. * @param mode Access mode for the file. May be "r" for read-only access, * "rw" for read and write access, or "rwt" for read and write access * that truncates any existing file. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * * @return Returns a new ParcelFileDescriptor which you can use to access * the file. Loading Loading @@ -1948,10 +1948,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * in {@link android.provider.MediaStore.MediaColumns}.</p> * * @param uri The URI whose file is to be opened. * @param mode Access mode for the file. May be "r" for read-only access, * "w" for write-only access, "rw" for read and write access, or * "rwt" for read and write access that truncates any existing * file. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * @param signal A signal to cancel the operation in progress, or * {@code null} if none. For example, if you are downloading a * file from the network to service a "rw" mode request, you Loading Loading @@ -2011,11 +2010,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * containing at least the columns specified by {@link android.provider.OpenableColumns}.</p> * * @param uri The URI whose file is to be opened. * @param mode Access mode for the file. May be "r" for read-only access, * "w" for write-only access (erasing whatever data is currently in * the file), "wa" for write-only access to append to any existing data, * "rw" for read and write access on any existing data, and "rwt" for read * and write access that truncates any existing file. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * * @return Returns a new AssetFileDescriptor which you can use to access * the file. Loading Loading @@ -2068,11 +2065,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * containing at least the columns specified by {@link android.provider.OpenableColumns}.</p> * * @param uri The URI whose file is to be opened. * @param mode Access mode for the file. May be "r" for read-only access, * "w" for write-only access (erasing whatever data is currently in * the file), "wa" for write-only access to append to any existing data, * "rw" for read and write access on any existing data, and "rwt" for read * and write access that truncates any existing file. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * @param signal A signal to cancel the operation in progress, or * {@code null} if none. For example, if you are downloading a * file from the network to service a "rw" mode request, you Loading Loading @@ -2103,11 +2098,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * by looking up a column named "_data" at the given URI. * * @param uri The URI to be opened. * @param mode The file mode. May be "r" for read-only access, * "w" for write-only access (erasing whatever data is currently in * the file), "wa" for write-only access to append to any existing data, * "rw" for read and write access on any existing data, and "rwt" for read * and write access that truncates any existing file. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * * @return Returns a new ParcelFileDescriptor that can be used by the * client to access the file. Loading core/java/android/content/ContentResolver.java +73 −13 Original line number Diff line number Diff line Loading @@ -63,7 +63,9 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.system.ErrnoException; import android.system.Int64Ref; import android.system.Os; import android.text.TextUtils; import android.util.EventLog; import android.util.Log; Loading @@ -76,8 +78,10 @@ import com.android.internal.util.MimeIconUtils; import dalvik.system.CloseGuard; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; Loading Loading @@ -864,6 +868,20 @@ public abstract class ContentResolver implements ContentInterface { return wrap((ContentInterface) wrapped); } /** * Offer to locally truncate the given file when opened using the write-only * mode. This is typically used to preserve legacy compatibility behavior. */ private static void maybeTruncate(FileDescriptor fd, String mode) throws FileNotFoundException { if ("w".equals(mode)) { try { Os.ftruncate(fd, 0); } catch (ErrnoException e) { throw new FileNotFoundException("Failed to truncate: " + e.getMessage()); } } } /** @hide */ @SuppressWarnings("HiddenAbstractMethod") @UnsupportedAppUsage Loading Loading @@ -1525,8 +1543,20 @@ public abstract class ContentResolver implements ContentInterface { } /** * Synonym for {@link #openOutputStream(Uri, String) * openOutputStream(uri, "w")}. * Open a stream on to the content associated with a content URI. If there * is no data associated with the URI, FileNotFoundException is thrown. * * <h5>Accepts the following URI schemes:</h5> * <ul> * <li>content ({@link #SCHEME_CONTENT})</li> * <li>file ({@link #SCHEME_FILE})</li> * </ul> * * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information * on these schemes. * * <p>This method behaves like {@link FileOutputStream} and automatically * truncates any existing contents. * * @param uri The desired URI. * @return an OutputStream or {@code null} if the provider recently crashed. Loading @@ -1534,7 +1564,16 @@ public abstract class ContentResolver implements ContentInterface { */ public final @Nullable OutputStream openOutputStream(@NonNull Uri uri) throws FileNotFoundException { return openOutputStream(uri, "w"); AssetFileDescriptor fd = openAssetFileDescriptor(uri, "w", null); if (fd == null) return null; try { final FileOutputStream res = fd.createOutputStream(); // Unconditionally truncate to mirror FileOutputStream behavior maybeTruncate(res.getFD(), "w"); return res; } catch (IOException e) { throw new FileNotFoundException("Unable to create stream"); } } /** Loading @@ -1551,7 +1590,9 @@ public abstract class ContentResolver implements ContentInterface { * on these schemes. * * @param uri The desired URI. * @param mode May be "w", "wa", "rw", or "rwt". * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * @return an OutputStream or {@code null} if the provider recently crashed. * @throws FileNotFoundException if the provided URI could not be opened. * @see #openAssetFileDescriptor(Uri, String) Loading @@ -1559,8 +1600,14 @@ public abstract class ContentResolver implements ContentInterface { public final @Nullable OutputStream openOutputStream(@NonNull Uri uri, @NonNull String mode) throws FileNotFoundException { AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode, null); if (fd == null) return null; try { return fd != null ? fd.createOutputStream() : null; final FileOutputStream res = fd.createOutputStream(); // Preserve legacy behavior by offering to truncate if (mTargetSdkVersion < Build.VERSION_CODES.Q) { maybeTruncate(res.getFD(), mode); } return res; } catch (IOException e) { throw new FileNotFoundException("Unable to create stream"); } Loading Loading @@ -1607,8 +1654,9 @@ public abstract class ContentResolver implements ContentInterface { * provider, use {@link ParcelFileDescriptor#closeWithError(String)}. * * @param uri The desired URI to open. * @param mode The file mode to use, as per {@link ContentProvider#openFile * ContentProvider.openFile}. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * @return Returns a new ParcelFileDescriptor pointing to the file or {@code null} if the * provider recently crashed. You own this descriptor and are responsible for closing it * when done. Loading Loading @@ -1650,8 +1698,9 @@ public abstract class ContentResolver implements ContentInterface { * provider, use {@link ParcelFileDescriptor#closeWithError(String)}. * * @param uri The desired URI to open. * @param mode The file mode to use, as per {@link ContentProvider#openFile * ContentProvider.openFile}. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * @param cancellationSignal A signal to cancel the operation in progress, * or null if none. If the operation is canceled, then * {@link OperationCanceledException} will be thrown. Loading Loading @@ -1744,8 +1793,9 @@ public abstract class ContentResolver implements ContentInterface { * from any built-in data conversion that a provider implements. * * @param uri The desired URI to open. * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile * ContentProvider.openAssetFile}. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * @return Returns a new ParcelFileDescriptor pointing to the file or {@code null} if the * provider recently crashed. You own this descriptor and are responsible for closing it * when done. Loading Loading @@ -1798,8 +1848,9 @@ public abstract class ContentResolver implements ContentInterface { * from any built-in data conversion that a provider implements. * * @param uri The desired URI to open. * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile * ContentProvider.openAssetFile}. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * @param cancellationSignal A signal to cancel the operation in progress, or null if * none. If the operation is canceled, then * {@link OperationCanceledException} will be thrown. Loading Loading @@ -1835,6 +1886,10 @@ public abstract class ContentResolver implements ContentInterface { } else if (SCHEME_FILE.equals(scheme)) { ParcelFileDescriptor pfd = ParcelFileDescriptor.open( new File(uri.getPath()), ParcelFileDescriptor.parseMode(mode)); // Preserve legacy behavior by offering to truncate if (mTargetSdkVersion < Build.VERSION_CODES.Q) { maybeTruncate(pfd.getFileDescriptor(), mode); } return new AssetFileDescriptor(pfd, 0, -1); } else { if ("r".equals(mode)) { Loading Loading @@ -1892,6 +1947,11 @@ public abstract class ContentResolver implements ContentInterface { // ParcelFileDescriptorInner do that when it is closed. stableProvider = null; // Preserve legacy behavior by offering to truncate if (mTargetSdkVersion < Build.VERSION_CODES.Q) { maybeTruncate(pfd.getFileDescriptor(), mode); } return new AssetFileDescriptor(pfd, fd.getStartOffset(), fd.getDeclaredLength()); Loading core/java/android/os/ParcelFileDescriptor.java +49 −9 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import static android.system.OsConstants.S_ISLNK; import static android.system.OsConstants.S_ISREG; import static android.system.OsConstants.S_IWOTH; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SuppressLint; import android.annotation.SystemApi; Loading Loading @@ -63,6 +64,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InterruptedIOException; import java.io.UncheckedIOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.DatagramSocket; import java.net.Socket; import java.nio.ByteOrder; Loading Loading @@ -110,6 +113,20 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { private final CloseGuard mGuard = CloseGuard.get(); /** @hide */ @IntDef(prefix = {"MODE_"}, value = { MODE_WORLD_READABLE, MODE_WORLD_WRITEABLE, MODE_READ_ONLY, MODE_WRITE_ONLY, MODE_READ_WRITE, MODE_CREATE, MODE_TRUNCATE, MODE_APPEND, }) @Retention(RetentionPolicy.SOURCE) public @interface Mode { } /** * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied and * this file doesn't already exist, then create the file with permissions Loading Loading @@ -227,7 +244,8 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { * be opened with the requested mode. * @see #parseMode(String) */ public static ParcelFileDescriptor open(File file, int mode) throws FileNotFoundException { public static ParcelFileDescriptor open(File file, @Mode int mode) throws FileNotFoundException { final FileDescriptor fd = openInternal(file, mode); if (fd == null) return null; Loading Loading @@ -259,7 +277,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { // We can't accept a generic Executor here, since we need to use // MessageQueue.addOnFileDescriptorEventListener() @SuppressLint("ExecutorRegistration") public static ParcelFileDescriptor open(File file, int mode, Handler handler, public static ParcelFileDescriptor open(File file, @Mode int mode, Handler handler, final OnCloseListener listener) throws IOException { if (handler == null) { throw new IllegalArgumentException("Handler must not be null"); Loading Loading @@ -330,7 +348,8 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { return pfd; } private static FileDescriptor openInternal(File file, int mode) throws FileNotFoundException { private static FileDescriptor openInternal(File file, @Mode int mode) throws FileNotFoundException { final int flags = FileUtils.translateModePfdToPosix(mode) | ifAtLeastQ(O_CLOEXEC); int realMode = S_IRWXU | S_IRWXG; Loading Loading @@ -623,15 +642,36 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { } /** * Converts a string representing a file mode, such as "rw", into a bitmask suitable for use * with {@link #open}. * Converts a string representing a file mode, such as "rw", into a bitmask * suitable for use with {@link #open}. * <p> * @param mode The string representation of the file mode. Can be "r", "w", "wt", "wa", "rw" * or "rwt". * The argument must define at least one of the following base access modes: * <ul> * <li>"r" indicates the file should be opened in read-only mode, equivalent * to {@link OsConstants#O_RDONLY}. * <li>"w" indicates the file should be opened in write-only mode, * equivalent to {@link OsConstants#O_WRONLY}. * <li>"rw" indicates the file should be opened in read-write mode, * equivalent to {@link OsConstants#O_RDWR}. * </ul> * In addition to a base access mode, the following additional modes may * requested: * <ul> * <li>"a" indicates the file should be opened in append mode, equivalent to * {@link OsConstants#O_APPEND}. Before each write, the file offset is * positioned at the end of the file. * <li>"t" indicates the file should be opened in truncate mode, equivalent * to {@link OsConstants#O_TRUNC}. If the file already exists and is a * regular file and is opened for writing, it will be truncated to length 0. * </ul> * * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". * @return A bitmask representing the given file mode. * @throws IllegalArgumentException if the given string does not match a known file mode. * @throws IllegalArgumentException if the given string does not match a * known file mode. */ public static int parseMode(String mode) { public static @Mode int parseMode(String mode) { return FileUtils.translateModePosixToPfd(FileUtils.translateModeStringToPosix(mode)); } Loading Loading
core/java/android/content/ContentProvider.java +15 −22 Original line number Diff line number Diff line Loading @@ -1885,9 +1885,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * in {@link android.provider.MediaStore.MediaColumns}.</p> * * @param uri The URI whose file is to be opened. * @param mode Access mode for the file. May be "r" for read-only access, * "rw" for read and write access, or "rwt" for read and write access * that truncates any existing file. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * * @return Returns a new ParcelFileDescriptor which you can use to access * the file. Loading Loading @@ -1948,10 +1948,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * in {@link android.provider.MediaStore.MediaColumns}.</p> * * @param uri The URI whose file is to be opened. * @param mode Access mode for the file. May be "r" for read-only access, * "w" for write-only access, "rw" for read and write access, or * "rwt" for read and write access that truncates any existing * file. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * @param signal A signal to cancel the operation in progress, or * {@code null} if none. For example, if you are downloading a * file from the network to service a "rw" mode request, you Loading Loading @@ -2011,11 +2010,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * containing at least the columns specified by {@link android.provider.OpenableColumns}.</p> * * @param uri The URI whose file is to be opened. * @param mode Access mode for the file. May be "r" for read-only access, * "w" for write-only access (erasing whatever data is currently in * the file), "wa" for write-only access to append to any existing data, * "rw" for read and write access on any existing data, and "rwt" for read * and write access that truncates any existing file. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * * @return Returns a new AssetFileDescriptor which you can use to access * the file. Loading Loading @@ -2068,11 +2065,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * containing at least the columns specified by {@link android.provider.OpenableColumns}.</p> * * @param uri The URI whose file is to be opened. * @param mode Access mode for the file. May be "r" for read-only access, * "w" for write-only access (erasing whatever data is currently in * the file), "wa" for write-only access to append to any existing data, * "rw" for read and write access on any existing data, and "rwt" for read * and write access that truncates any existing file. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * @param signal A signal to cancel the operation in progress, or * {@code null} if none. For example, if you are downloading a * file from the network to service a "rw" mode request, you Loading Loading @@ -2103,11 +2098,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall * by looking up a column named "_data" at the given URI. * * @param uri The URI to be opened. * @param mode The file mode. May be "r" for read-only access, * "w" for write-only access (erasing whatever data is currently in * the file), "wa" for write-only access to append to any existing data, * "rw" for read and write access on any existing data, and "rwt" for read * and write access that truncates any existing file. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * * @return Returns a new ParcelFileDescriptor that can be used by the * client to access the file. Loading
core/java/android/content/ContentResolver.java +73 −13 Original line number Diff line number Diff line Loading @@ -63,7 +63,9 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.system.ErrnoException; import android.system.Int64Ref; import android.system.Os; import android.text.TextUtils; import android.util.EventLog; import android.util.Log; Loading @@ -76,8 +78,10 @@ import com.android.internal.util.MimeIconUtils; import dalvik.system.CloseGuard; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; Loading Loading @@ -864,6 +868,20 @@ public abstract class ContentResolver implements ContentInterface { return wrap((ContentInterface) wrapped); } /** * Offer to locally truncate the given file when opened using the write-only * mode. This is typically used to preserve legacy compatibility behavior. */ private static void maybeTruncate(FileDescriptor fd, String mode) throws FileNotFoundException { if ("w".equals(mode)) { try { Os.ftruncate(fd, 0); } catch (ErrnoException e) { throw new FileNotFoundException("Failed to truncate: " + e.getMessage()); } } } /** @hide */ @SuppressWarnings("HiddenAbstractMethod") @UnsupportedAppUsage Loading Loading @@ -1525,8 +1543,20 @@ public abstract class ContentResolver implements ContentInterface { } /** * Synonym for {@link #openOutputStream(Uri, String) * openOutputStream(uri, "w")}. * Open a stream on to the content associated with a content URI. If there * is no data associated with the URI, FileNotFoundException is thrown. * * <h5>Accepts the following URI schemes:</h5> * <ul> * <li>content ({@link #SCHEME_CONTENT})</li> * <li>file ({@link #SCHEME_FILE})</li> * </ul> * * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information * on these schemes. * * <p>This method behaves like {@link FileOutputStream} and automatically * truncates any existing contents. * * @param uri The desired URI. * @return an OutputStream or {@code null} if the provider recently crashed. Loading @@ -1534,7 +1564,16 @@ public abstract class ContentResolver implements ContentInterface { */ public final @Nullable OutputStream openOutputStream(@NonNull Uri uri) throws FileNotFoundException { return openOutputStream(uri, "w"); AssetFileDescriptor fd = openAssetFileDescriptor(uri, "w", null); if (fd == null) return null; try { final FileOutputStream res = fd.createOutputStream(); // Unconditionally truncate to mirror FileOutputStream behavior maybeTruncate(res.getFD(), "w"); return res; } catch (IOException e) { throw new FileNotFoundException("Unable to create stream"); } } /** Loading @@ -1551,7 +1590,9 @@ public abstract class ContentResolver implements ContentInterface { * on these schemes. * * @param uri The desired URI. * @param mode May be "w", "wa", "rw", or "rwt". * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * @return an OutputStream or {@code null} if the provider recently crashed. * @throws FileNotFoundException if the provided URI could not be opened. * @see #openAssetFileDescriptor(Uri, String) Loading @@ -1559,8 +1600,14 @@ public abstract class ContentResolver implements ContentInterface { public final @Nullable OutputStream openOutputStream(@NonNull Uri uri, @NonNull String mode) throws FileNotFoundException { AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode, null); if (fd == null) return null; try { return fd != null ? fd.createOutputStream() : null; final FileOutputStream res = fd.createOutputStream(); // Preserve legacy behavior by offering to truncate if (mTargetSdkVersion < Build.VERSION_CODES.Q) { maybeTruncate(res.getFD(), mode); } return res; } catch (IOException e) { throw new FileNotFoundException("Unable to create stream"); } Loading Loading @@ -1607,8 +1654,9 @@ public abstract class ContentResolver implements ContentInterface { * provider, use {@link ParcelFileDescriptor#closeWithError(String)}. * * @param uri The desired URI to open. * @param mode The file mode to use, as per {@link ContentProvider#openFile * ContentProvider.openFile}. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * @return Returns a new ParcelFileDescriptor pointing to the file or {@code null} if the * provider recently crashed. You own this descriptor and are responsible for closing it * when done. Loading Loading @@ -1650,8 +1698,9 @@ public abstract class ContentResolver implements ContentInterface { * provider, use {@link ParcelFileDescriptor#closeWithError(String)}. * * @param uri The desired URI to open. * @param mode The file mode to use, as per {@link ContentProvider#openFile * ContentProvider.openFile}. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * @param cancellationSignal A signal to cancel the operation in progress, * or null if none. If the operation is canceled, then * {@link OperationCanceledException} will be thrown. Loading Loading @@ -1744,8 +1793,9 @@ public abstract class ContentResolver implements ContentInterface { * from any built-in data conversion that a provider implements. * * @param uri The desired URI to open. * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile * ContentProvider.openAssetFile}. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * @return Returns a new ParcelFileDescriptor pointing to the file or {@code null} if the * provider recently crashed. You own this descriptor and are responsible for closing it * when done. Loading Loading @@ -1798,8 +1848,9 @@ public abstract class ContentResolver implements ContentInterface { * from any built-in data conversion that a provider implements. * * @param uri The desired URI to open. * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile * ContentProvider.openAssetFile}. * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". See * {@link ParcelFileDescriptor#parseMode} for more details. * @param cancellationSignal A signal to cancel the operation in progress, or null if * none. If the operation is canceled, then * {@link OperationCanceledException} will be thrown. Loading Loading @@ -1835,6 +1886,10 @@ public abstract class ContentResolver implements ContentInterface { } else if (SCHEME_FILE.equals(scheme)) { ParcelFileDescriptor pfd = ParcelFileDescriptor.open( new File(uri.getPath()), ParcelFileDescriptor.parseMode(mode)); // Preserve legacy behavior by offering to truncate if (mTargetSdkVersion < Build.VERSION_CODES.Q) { maybeTruncate(pfd.getFileDescriptor(), mode); } return new AssetFileDescriptor(pfd, 0, -1); } else { if ("r".equals(mode)) { Loading Loading @@ -1892,6 +1947,11 @@ public abstract class ContentResolver implements ContentInterface { // ParcelFileDescriptorInner do that when it is closed. stableProvider = null; // Preserve legacy behavior by offering to truncate if (mTargetSdkVersion < Build.VERSION_CODES.Q) { maybeTruncate(pfd.getFileDescriptor(), mode); } return new AssetFileDescriptor(pfd, fd.getStartOffset(), fd.getDeclaredLength()); Loading
core/java/android/os/ParcelFileDescriptor.java +49 −9 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import static android.system.OsConstants.S_ISLNK; import static android.system.OsConstants.S_ISREG; import static android.system.OsConstants.S_IWOTH; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SuppressLint; import android.annotation.SystemApi; Loading Loading @@ -63,6 +64,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InterruptedIOException; import java.io.UncheckedIOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.DatagramSocket; import java.net.Socket; import java.nio.ByteOrder; Loading Loading @@ -110,6 +113,20 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { private final CloseGuard mGuard = CloseGuard.get(); /** @hide */ @IntDef(prefix = {"MODE_"}, value = { MODE_WORLD_READABLE, MODE_WORLD_WRITEABLE, MODE_READ_ONLY, MODE_WRITE_ONLY, MODE_READ_WRITE, MODE_CREATE, MODE_TRUNCATE, MODE_APPEND, }) @Retention(RetentionPolicy.SOURCE) public @interface Mode { } /** * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied and * this file doesn't already exist, then create the file with permissions Loading Loading @@ -227,7 +244,8 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { * be opened with the requested mode. * @see #parseMode(String) */ public static ParcelFileDescriptor open(File file, int mode) throws FileNotFoundException { public static ParcelFileDescriptor open(File file, @Mode int mode) throws FileNotFoundException { final FileDescriptor fd = openInternal(file, mode); if (fd == null) return null; Loading Loading @@ -259,7 +277,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { // We can't accept a generic Executor here, since we need to use // MessageQueue.addOnFileDescriptorEventListener() @SuppressLint("ExecutorRegistration") public static ParcelFileDescriptor open(File file, int mode, Handler handler, public static ParcelFileDescriptor open(File file, @Mode int mode, Handler handler, final OnCloseListener listener) throws IOException { if (handler == null) { throw new IllegalArgumentException("Handler must not be null"); Loading Loading @@ -330,7 +348,8 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { return pfd; } private static FileDescriptor openInternal(File file, int mode) throws FileNotFoundException { private static FileDescriptor openInternal(File file, @Mode int mode) throws FileNotFoundException { final int flags = FileUtils.translateModePfdToPosix(mode) | ifAtLeastQ(O_CLOEXEC); int realMode = S_IRWXU | S_IRWXG; Loading Loading @@ -623,15 +642,36 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { } /** * Converts a string representing a file mode, such as "rw", into a bitmask suitable for use * with {@link #open}. * Converts a string representing a file mode, such as "rw", into a bitmask * suitable for use with {@link #open}. * <p> * @param mode The string representation of the file mode. Can be "r", "w", "wt", "wa", "rw" * or "rwt". * The argument must define at least one of the following base access modes: * <ul> * <li>"r" indicates the file should be opened in read-only mode, equivalent * to {@link OsConstants#O_RDONLY}. * <li>"w" indicates the file should be opened in write-only mode, * equivalent to {@link OsConstants#O_WRONLY}. * <li>"rw" indicates the file should be opened in read-write mode, * equivalent to {@link OsConstants#O_RDWR}. * </ul> * In addition to a base access mode, the following additional modes may * requested: * <ul> * <li>"a" indicates the file should be opened in append mode, equivalent to * {@link OsConstants#O_APPEND}. Before each write, the file offset is * positioned at the end of the file. * <li>"t" indicates the file should be opened in truncate mode, equivalent * to {@link OsConstants#O_TRUNC}. If the file already exists and is a * regular file and is opened for writing, it will be truncated to length 0. * </ul> * * @param mode The string representation of the file mode. Can be "r", "w", * "wt", "wa", "rw" or "rwt". * @return A bitmask representing the given file mode. * @throws IllegalArgumentException if the given string does not match a known file mode. * @throws IllegalArgumentException if the given string does not match a * known file mode. */ public static int parseMode(String mode) { public static @Mode int parseMode(String mode) { return FileUtils.translateModePosixToPfd(FileUtils.translateModeStringToPosix(mode)); } Loading