Loading api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -9340,6 +9340,7 @@ package android.content { ctor public ContentUris(); method public static android.net.Uri.Builder appendId(android.net.Uri.Builder, long); method public static long parseId(android.net.Uri); method public static android.net.Uri removeId(android.net.Uri); method public static android.net.Uri withAppendedId(android.net.Uri, long); } core/java/android/content/ContentUris.java +28 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package android.content; import android.net.Uri; import java.util.List; /** * Utility methods useful for working with {@link android.net.Uri} objects * that use the "content" (content://) scheme. Loading Loading @@ -109,4 +111,30 @@ public class ContentUris { public static Uri withAppendedId(Uri contentUri, long id) { return appendId(contentUri.buildUpon(), id).build(); } /** * Removes any ID from the end of the path. * * @param contentUri that ends with an ID * @return a new URI with the ID removed from the end of the path * @throws IllegalArgumentException when the given URI has no ID to remove * from the end of the path */ public static Uri removeId(Uri contentUri) { // Verify that we have a valid ID to actually remove final String last = contentUri.getLastPathSegment(); if (last == null) { throw new IllegalArgumentException("No path segments to remove"); } else { Long.parseLong(last); } final List<String> segments = contentUri.getPathSegments(); final Uri.Builder builder = contentUri.buildUpon(); builder.path(null); for (int i = 0; i < segments.size() - 1; i++) { builder.appendPath(segments.get(i)); } return builder.build(); } } core/java/android/os/FileUtils.java +109 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,18 @@ package android.os; import static android.os.ParcelFileDescriptor.MODE_APPEND; import static android.os.ParcelFileDescriptor.MODE_CREATE; import static android.os.ParcelFileDescriptor.MODE_READ_ONLY; import static android.os.ParcelFileDescriptor.MODE_READ_WRITE; import static android.os.ParcelFileDescriptor.MODE_TRUNCATE; import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY; import static android.system.OsConstants.O_APPEND; import static android.system.OsConstants.O_CREAT; import static android.system.OsConstants.O_RDONLY; import static android.system.OsConstants.O_RDWR; import static android.system.OsConstants.O_TRUNC; import static android.system.OsConstants.O_WRONLY; import static android.system.OsConstants.SPLICE_F_MORE; import static android.system.OsConstants.SPLICE_F_MOVE; import static android.system.OsConstants.S_ISFIFO; Loading Loading @@ -1061,8 +1073,13 @@ public class FileUtils { mimeTypeFromExt = ContentResolver.MIME_TYPE_DEFAULT; } final String extFromMimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType( mimeType); final String extFromMimeType; if (ContentResolver.MIME_TYPE_DEFAULT.equals(mimeType)) { extFromMimeType = null; } else { extFromMimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType); } if (Objects.equals(mimeType, mimeTypeFromExt) || Objects.equals(ext, extFromMimeType)) { // Extension maps back to requested MIME type; allow it } else { Loading Loading @@ -1179,6 +1196,96 @@ public class FileUtils { IoUtils.closeQuietly(fd); } /** {@hide} */ public static int translateModeStringToPosix(String mode) { int res = 0; if (mode.startsWith("rw")) { res |= O_RDWR | O_CREAT; } else if (mode.startsWith("w")) { res |= O_WRONLY | O_CREAT; } else if (mode.startsWith("r")) { res |= O_RDONLY; } else { throw new IllegalArgumentException("Bad mode: " + mode); } if (mode.indexOf('t') != -1) { res |= O_TRUNC; } if (mode.indexOf('a') != -1) { res |= O_APPEND; } return res; } /** {@hide} */ public static String translateModePosixToString(int mode) { String res = ""; if ((mode & O_RDWR) == O_RDWR) { res += "rw"; } else if ((mode & O_WRONLY) == O_WRONLY) { res += "w"; } else if ((mode & O_RDONLY) == O_RDONLY) { res += "r"; } else { throw new IllegalArgumentException("Bad mode: " + mode); } if ((mode & O_TRUNC) == O_TRUNC) { res += "t"; } if ((mode & O_APPEND) == O_APPEND) { res += "a"; } return res; } /** {@hide} */ public static int translateModePosixToPfd(int mode) { int res = 0; if ((mode & O_RDWR) == O_RDWR) { res |= MODE_READ_WRITE; } else if ((mode & O_WRONLY) == O_WRONLY) { res |= MODE_WRITE_ONLY; } else if ((mode & O_RDONLY) == O_RDONLY) { res |= MODE_READ_ONLY; } else { throw new IllegalArgumentException("Bad mode: " + mode); } if ((mode & O_CREAT) == O_CREAT) { res |= MODE_CREATE; } if ((mode & O_TRUNC) == O_TRUNC) { res |= MODE_TRUNCATE; } if ((mode & O_APPEND) == O_APPEND) { res |= MODE_APPEND; } return res; } /** {@hide} */ public static int translateModePfdToPosix(int mode) { int res = 0; if ((mode & MODE_READ_WRITE) == MODE_READ_WRITE) { res |= O_RDWR; } else if ((mode & MODE_WRITE_ONLY) == MODE_WRITE_ONLY) { res |= O_WRONLY; } else if ((mode & MODE_READ_ONLY) == MODE_READ_ONLY) { res |= O_RDONLY; } else { throw new IllegalArgumentException("Bad mode: " + mode); } if ((mode & MODE_CREATE) == MODE_CREATE) { res |= O_CREAT; } if ((mode & MODE_TRUNCATE) == MODE_TRUNCATE) { res |= O_TRUNC; } if ((mode & MODE_APPEND) == MODE_APPEND) { res |= O_APPEND; } return res; } /** {@hide} */ @VisibleForTesting public static class MemoryPipe extends Thread implements AutoCloseable { Loading core/java/android/os/ParcelFileDescriptor.java +1 −22 Original line number Diff line number Diff line Loading @@ -559,28 +559,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { * @throws IllegalArgumentException if the given string does not match a known file mode. */ public static int parseMode(String mode) { final int modeBits; if ("r".equals(mode)) { modeBits = ParcelFileDescriptor.MODE_READ_ONLY; } else if ("w".equals(mode) || "wt".equals(mode)) { modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY | ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_TRUNCATE; } else if ("wa".equals(mode)) { modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY | ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_APPEND; } else if ("rw".equals(mode)) { modeBits = ParcelFileDescriptor.MODE_READ_WRITE | ParcelFileDescriptor.MODE_CREATE; } else if ("rwt".equals(mode)) { modeBits = ParcelFileDescriptor.MODE_READ_WRITE | ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_TRUNCATE; } else { throw new IllegalArgumentException("Bad mode '" + mode + "'"); } return modeBits; return FileUtils.translateModePosixToPfd(FileUtils.translateModeStringToPosix(mode)); } /** Loading core/tests/coretests/src/android/os/FileUtilsTest.java +42 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,22 @@ package android.os; import static android.os.FileUtils.roundStorageSize; import static android.os.FileUtils.translateModePfdToPosix; import static android.os.FileUtils.translateModePosixToPfd; import static android.os.FileUtils.translateModePosixToString; import static android.os.FileUtils.translateModeStringToPosix; import static android.os.ParcelFileDescriptor.MODE_APPEND; import static android.os.ParcelFileDescriptor.MODE_CREATE; import static android.os.ParcelFileDescriptor.MODE_READ_ONLY; import static android.os.ParcelFileDescriptor.MODE_READ_WRITE; import static android.os.ParcelFileDescriptor.MODE_TRUNCATE; import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY; import static android.system.OsConstants.O_APPEND; import static android.system.OsConstants.O_CREAT; import static android.system.OsConstants.O_RDONLY; import static android.system.OsConstants.O_RDWR; import static android.system.OsConstants.O_TRUNC; import static android.system.OsConstants.O_WRONLY; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.WEEK_IN_MILLIS; Loading Loading @@ -476,6 +492,32 @@ public class FileUtilsTest { assertEquals(G64, roundStorageSize(G32 + 1)); } @Test public void testTranslateMode() throws Exception { assertTranslate("r", O_RDONLY, MODE_READ_ONLY); assertTranslate("rw", O_RDWR | O_CREAT, MODE_READ_WRITE | MODE_CREATE); assertTranslate("rwt", O_RDWR | O_CREAT | O_TRUNC, MODE_READ_WRITE | MODE_CREATE | MODE_TRUNCATE); assertTranslate("rwa", O_RDWR | O_CREAT | O_APPEND, MODE_READ_WRITE | MODE_CREATE | MODE_APPEND); assertTranslate("w", O_WRONLY | O_CREAT, MODE_WRITE_ONLY | MODE_CREATE | MODE_CREATE); assertTranslate("wt", O_WRONLY | O_CREAT | O_TRUNC, MODE_WRITE_ONLY | MODE_CREATE | MODE_TRUNCATE); assertTranslate("wa", O_WRONLY | O_CREAT | O_APPEND, MODE_WRITE_ONLY | MODE_CREATE | MODE_APPEND); } private static void assertTranslate(String string, int posix, int pfd) { assertEquals(posix, translateModeStringToPosix(string)); assertEquals(string, translateModePosixToString(posix)); assertEquals(pfd, translateModePosixToPfd(posix)); assertEquals(posix, translateModePfdToPosix(pfd)); } private static void assertNameEquals(String expected, File actual) { assertEquals(expected, actual.getName()); } Loading Loading
api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -9340,6 +9340,7 @@ package android.content { ctor public ContentUris(); method public static android.net.Uri.Builder appendId(android.net.Uri.Builder, long); method public static long parseId(android.net.Uri); method public static android.net.Uri removeId(android.net.Uri); method public static android.net.Uri withAppendedId(android.net.Uri, long); }
core/java/android/content/ContentUris.java +28 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package android.content; import android.net.Uri; import java.util.List; /** * Utility methods useful for working with {@link android.net.Uri} objects * that use the "content" (content://) scheme. Loading Loading @@ -109,4 +111,30 @@ public class ContentUris { public static Uri withAppendedId(Uri contentUri, long id) { return appendId(contentUri.buildUpon(), id).build(); } /** * Removes any ID from the end of the path. * * @param contentUri that ends with an ID * @return a new URI with the ID removed from the end of the path * @throws IllegalArgumentException when the given URI has no ID to remove * from the end of the path */ public static Uri removeId(Uri contentUri) { // Verify that we have a valid ID to actually remove final String last = contentUri.getLastPathSegment(); if (last == null) { throw new IllegalArgumentException("No path segments to remove"); } else { Long.parseLong(last); } final List<String> segments = contentUri.getPathSegments(); final Uri.Builder builder = contentUri.buildUpon(); builder.path(null); for (int i = 0; i < segments.size() - 1; i++) { builder.appendPath(segments.get(i)); } return builder.build(); } }
core/java/android/os/FileUtils.java +109 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,18 @@ package android.os; import static android.os.ParcelFileDescriptor.MODE_APPEND; import static android.os.ParcelFileDescriptor.MODE_CREATE; import static android.os.ParcelFileDescriptor.MODE_READ_ONLY; import static android.os.ParcelFileDescriptor.MODE_READ_WRITE; import static android.os.ParcelFileDescriptor.MODE_TRUNCATE; import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY; import static android.system.OsConstants.O_APPEND; import static android.system.OsConstants.O_CREAT; import static android.system.OsConstants.O_RDONLY; import static android.system.OsConstants.O_RDWR; import static android.system.OsConstants.O_TRUNC; import static android.system.OsConstants.O_WRONLY; import static android.system.OsConstants.SPLICE_F_MORE; import static android.system.OsConstants.SPLICE_F_MOVE; import static android.system.OsConstants.S_ISFIFO; Loading Loading @@ -1061,8 +1073,13 @@ public class FileUtils { mimeTypeFromExt = ContentResolver.MIME_TYPE_DEFAULT; } final String extFromMimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType( mimeType); final String extFromMimeType; if (ContentResolver.MIME_TYPE_DEFAULT.equals(mimeType)) { extFromMimeType = null; } else { extFromMimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType); } if (Objects.equals(mimeType, mimeTypeFromExt) || Objects.equals(ext, extFromMimeType)) { // Extension maps back to requested MIME type; allow it } else { Loading Loading @@ -1179,6 +1196,96 @@ public class FileUtils { IoUtils.closeQuietly(fd); } /** {@hide} */ public static int translateModeStringToPosix(String mode) { int res = 0; if (mode.startsWith("rw")) { res |= O_RDWR | O_CREAT; } else if (mode.startsWith("w")) { res |= O_WRONLY | O_CREAT; } else if (mode.startsWith("r")) { res |= O_RDONLY; } else { throw new IllegalArgumentException("Bad mode: " + mode); } if (mode.indexOf('t') != -1) { res |= O_TRUNC; } if (mode.indexOf('a') != -1) { res |= O_APPEND; } return res; } /** {@hide} */ public static String translateModePosixToString(int mode) { String res = ""; if ((mode & O_RDWR) == O_RDWR) { res += "rw"; } else if ((mode & O_WRONLY) == O_WRONLY) { res += "w"; } else if ((mode & O_RDONLY) == O_RDONLY) { res += "r"; } else { throw new IllegalArgumentException("Bad mode: " + mode); } if ((mode & O_TRUNC) == O_TRUNC) { res += "t"; } if ((mode & O_APPEND) == O_APPEND) { res += "a"; } return res; } /** {@hide} */ public static int translateModePosixToPfd(int mode) { int res = 0; if ((mode & O_RDWR) == O_RDWR) { res |= MODE_READ_WRITE; } else if ((mode & O_WRONLY) == O_WRONLY) { res |= MODE_WRITE_ONLY; } else if ((mode & O_RDONLY) == O_RDONLY) { res |= MODE_READ_ONLY; } else { throw new IllegalArgumentException("Bad mode: " + mode); } if ((mode & O_CREAT) == O_CREAT) { res |= MODE_CREATE; } if ((mode & O_TRUNC) == O_TRUNC) { res |= MODE_TRUNCATE; } if ((mode & O_APPEND) == O_APPEND) { res |= MODE_APPEND; } return res; } /** {@hide} */ public static int translateModePfdToPosix(int mode) { int res = 0; if ((mode & MODE_READ_WRITE) == MODE_READ_WRITE) { res |= O_RDWR; } else if ((mode & MODE_WRITE_ONLY) == MODE_WRITE_ONLY) { res |= O_WRONLY; } else if ((mode & MODE_READ_ONLY) == MODE_READ_ONLY) { res |= O_RDONLY; } else { throw new IllegalArgumentException("Bad mode: " + mode); } if ((mode & MODE_CREATE) == MODE_CREATE) { res |= O_CREAT; } if ((mode & MODE_TRUNCATE) == MODE_TRUNCATE) { res |= O_TRUNC; } if ((mode & MODE_APPEND) == MODE_APPEND) { res |= O_APPEND; } return res; } /** {@hide} */ @VisibleForTesting public static class MemoryPipe extends Thread implements AutoCloseable { Loading
core/java/android/os/ParcelFileDescriptor.java +1 −22 Original line number Diff line number Diff line Loading @@ -559,28 +559,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { * @throws IllegalArgumentException if the given string does not match a known file mode. */ public static int parseMode(String mode) { final int modeBits; if ("r".equals(mode)) { modeBits = ParcelFileDescriptor.MODE_READ_ONLY; } else if ("w".equals(mode) || "wt".equals(mode)) { modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY | ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_TRUNCATE; } else if ("wa".equals(mode)) { modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY | ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_APPEND; } else if ("rw".equals(mode)) { modeBits = ParcelFileDescriptor.MODE_READ_WRITE | ParcelFileDescriptor.MODE_CREATE; } else if ("rwt".equals(mode)) { modeBits = ParcelFileDescriptor.MODE_READ_WRITE | ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_TRUNCATE; } else { throw new IllegalArgumentException("Bad mode '" + mode + "'"); } return modeBits; return FileUtils.translateModePosixToPfd(FileUtils.translateModeStringToPosix(mode)); } /** Loading
core/tests/coretests/src/android/os/FileUtilsTest.java +42 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,22 @@ package android.os; import static android.os.FileUtils.roundStorageSize; import static android.os.FileUtils.translateModePfdToPosix; import static android.os.FileUtils.translateModePosixToPfd; import static android.os.FileUtils.translateModePosixToString; import static android.os.FileUtils.translateModeStringToPosix; import static android.os.ParcelFileDescriptor.MODE_APPEND; import static android.os.ParcelFileDescriptor.MODE_CREATE; import static android.os.ParcelFileDescriptor.MODE_READ_ONLY; import static android.os.ParcelFileDescriptor.MODE_READ_WRITE; import static android.os.ParcelFileDescriptor.MODE_TRUNCATE; import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY; import static android.system.OsConstants.O_APPEND; import static android.system.OsConstants.O_CREAT; import static android.system.OsConstants.O_RDONLY; import static android.system.OsConstants.O_RDWR; import static android.system.OsConstants.O_TRUNC; import static android.system.OsConstants.O_WRONLY; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.WEEK_IN_MILLIS; Loading Loading @@ -476,6 +492,32 @@ public class FileUtilsTest { assertEquals(G64, roundStorageSize(G32 + 1)); } @Test public void testTranslateMode() throws Exception { assertTranslate("r", O_RDONLY, MODE_READ_ONLY); assertTranslate("rw", O_RDWR | O_CREAT, MODE_READ_WRITE | MODE_CREATE); assertTranslate("rwt", O_RDWR | O_CREAT | O_TRUNC, MODE_READ_WRITE | MODE_CREATE | MODE_TRUNCATE); assertTranslate("rwa", O_RDWR | O_CREAT | O_APPEND, MODE_READ_WRITE | MODE_CREATE | MODE_APPEND); assertTranslate("w", O_WRONLY | O_CREAT, MODE_WRITE_ONLY | MODE_CREATE | MODE_CREATE); assertTranslate("wt", O_WRONLY | O_CREAT | O_TRUNC, MODE_WRITE_ONLY | MODE_CREATE | MODE_TRUNCATE); assertTranslate("wa", O_WRONLY | O_CREAT | O_APPEND, MODE_WRITE_ONLY | MODE_CREATE | MODE_APPEND); } private static void assertTranslate(String string, int posix, int pfd) { assertEquals(posix, translateModeStringToPosix(string)); assertEquals(string, translateModePosixToString(posix)); assertEquals(pfd, translateModePosixToPfd(posix)); assertEquals(posix, translateModePfdToPosix(pfd)); } private static void assertNameEquals(String expected, File actual) { assertEquals(expected, actual.getName()); } Loading