diff options
| author | Jeff Sharkey <jsharkey@android.com> | 2021-04-21 08:21:35 -0600 |
|---|---|---|
| committer | Jeff Sharkey <jsharkey@android.com> | 2021-04-28 14:25:46 -0600 |
| commit | fe738fbd0dd953ddffd12d2479cc27801e9aecc2 (patch) | |
| tree | 964dda36877deb80aa4475da3ab6fd52eafc02cb /core/java/android/content/ContentProvider.java | |
| parent | ddcd076c781455053b50fd69cca68d3479de3f9d (diff) | |
Restore file truncation where expected.
Several years ago ParcelFileDescriptor.parseMode() was fixed to match
the behavior of fopen(), since developers expect consistent behavior
between managed and native code. FileUtilsTest.testTranslateMode()
verifies that all these modes are correctly translated.
However, this unintentionally changed the behavior of
ContentResolver.openOutputStream(), which only sends the 'w' mode
to the remote process. Developers expect this API to behave like
the FileOutputStream constructor, which always truncates the file
unless opened with the append mode.
Since some remote providers may not be prepared to handle the 't'
mode, this change carefully uses Os.ftruncate() to restore this
expected behavior in all cases.
For other APIs that return opened files, this strategy is applied
to restore the original behavior, but only when the target SDK of
the app is expecting this truncation to take place. The reason for
this is that moving forward our goal should always enable
ContentInterface APIs to be a transparent conversation between apps
without attempting to alter the behavior. Apps talking with older
providers can apply the Os.ftruncate() logic themselves, if
desired, once they target Android Q or higher.
Bug: 157888856, 180680924
Test: atest CtsContentTestCases:ContentResolverTest
Change-Id: Iacec49164c4ce3891db0270635e9f458dea7becd
Diffstat (limited to 'core/java/android/content/ContentProvider.java')
| -rw-r--r-- | core/java/android/content/ContentProvider.java | 37 |
1 files changed, 15 insertions, 22 deletions
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 7e1df1b0e59c..114ad874d0c4 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -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. @@ -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 @@ -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. @@ -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 @@ -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. |
