summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt24
-rw-r--r--core/java/android/content/ContentProviderClient.java17
-rw-r--r--core/java/android/os/FileUtils.java256
-rw-r--r--core/java/android/print/PrintFileDocumentAdapter.java2
-rw-r--r--core/java/android/provider/DocumentsContract.java3
-rw-r--r--core/tests/benchmarks/src/android/os/FileUtilsBenchmark.java12
-rw-r--r--core/tests/coretests/src/android/os/FileUtilsTest.java2
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java4
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java15
-rw-r--r--services/print/java/com/android/server/print/UserState.java2
10 files changed, 244 insertions, 93 deletions
diff --git a/api/current.txt b/api/current.txt
index dcc19e62d187..f4c6a8f29d23 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9137,6 +9137,7 @@ package android.content {
method public android.os.Bundle call(java.lang.String, java.lang.String, android.os.Bundle) throws android.os.RemoteException;
method public final android.net.Uri canonicalize(android.net.Uri) throws android.os.RemoteException;
method public void close();
+ method public static void closeQuietly(android.content.ContentProviderClient);
method public int delete(android.net.Uri, java.lang.String, java.lang.String[]) throws android.os.RemoteException;
method public android.content.ContentProvider getLocalContentProvider();
method public java.lang.String[] getStreamTypes(android.net.Uri, java.lang.String) throws android.os.RemoteException;
@@ -32547,6 +32548,21 @@ package android.os {
ctor public FileUriExposedException(java.lang.String);
}
+ public class FileUtils {
+ method public static void closeQuietly(java.lang.AutoCloseable);
+ method public static void closeQuietly(java.io.FileDescriptor);
+ method public static long copy(java.io.File, java.io.File) throws java.io.IOException;
+ method public static long copy(java.io.File, java.io.File, android.os.CancellationSignal, java.util.concurrent.Executor, android.os.FileUtils.ProgressListener) throws java.io.IOException;
+ method public static long copy(java.io.InputStream, java.io.OutputStream) throws java.io.IOException;
+ method public static long copy(java.io.InputStream, java.io.OutputStream, android.os.CancellationSignal, java.util.concurrent.Executor, android.os.FileUtils.ProgressListener) throws java.io.IOException;
+ method public static long copy(java.io.FileDescriptor, java.io.FileDescriptor) throws java.io.IOException;
+ method public static long copy(java.io.FileDescriptor, java.io.FileDescriptor, android.os.CancellationSignal, java.util.concurrent.Executor, android.os.FileUtils.ProgressListener) throws java.io.IOException;
+ }
+
+ public static abstract interface FileUtils.ProgressListener {
+ method public abstract void onProgress(long);
+ }
+
public class Handler {
ctor public Handler();
ctor public Handler(android.os.Handler.Callback);
@@ -42510,13 +42526,11 @@ package android.telephony {
method public java.lang.String getIccAuthentication(int, int, java.lang.String);
method public java.lang.String getImei();
method public java.lang.String getImei(int);
- method public java.lang.String getTypeAllocationCode();
- method public java.lang.String getTypeAllocationCode(int);
method public java.lang.String getLine1Number();
- method public java.lang.String getMeid();
- method public java.lang.String getMeid(int);
method public java.lang.String getManufacturerCode();
method public java.lang.String getManufacturerCode(int);
+ method public java.lang.String getMeid();
+ method public java.lang.String getMeid(int);
method public java.lang.String getMmsUAProfUrl();
method public java.lang.String getMmsUserAgent();
method public java.lang.String getNai();
@@ -42539,6 +42553,8 @@ package android.telephony {
method public int getSimState();
method public int getSimState(int);
method public java.lang.String getSubscriberId();
+ method public java.lang.String getTypeAllocationCode();
+ method public java.lang.String getTypeAllocationCode(int);
method public java.lang.String getVisualVoicemailPackageName();
method public java.lang.String getVoiceMailAlphaTag();
method public java.lang.String getVoiceMailNumber();
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index 2d490a03bd76..9d8c318f8092 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -39,6 +39,8 @@ import com.android.internal.util.Preconditions;
import dalvik.system.CloseGuard;
+import libcore.io.IoUtils;
+
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -560,14 +562,17 @@ public class ContentProviderClient implements AutoCloseable {
return ContentProvider.coerceToLocalContentProvider(mContentProvider);
}
+ /**
+ * Closes the given object quietly, ignoring any checked exceptions. Does
+ * nothing if the given object is {@code null}.
+ */
+ public static void closeQuietly(ContentProviderClient client) {
+ IoUtils.closeQuietly(client);
+ }
+
/** {@hide} */
public static void releaseQuietly(ContentProviderClient client) {
- if (client != null) {
- try {
- client.release();
- } catch (Exception ignored) {
- }
- }
+ IoUtils.closeQuietly(client);
}
private class NotRespondingRunnable implements Runnable {
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 88d6e847b644..9fccd1ec7b43 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -53,32 +53,35 @@ import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
+import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
/**
- * Tools for managing files. Not for public consumption.
- * @hide
+ * Utility methods useful for working with files.
*/
public class FileUtils {
private static final String TAG = "FileUtils";
- public static final int S_IRWXU = 00700;
- public static final int S_IRUSR = 00400;
- public static final int S_IWUSR = 00200;
- public static final int S_IXUSR = 00100;
+ /** {@hide} */ public static final int S_IRWXU = 00700;
+ /** {@hide} */ public static final int S_IRUSR = 00400;
+ /** {@hide} */ public static final int S_IWUSR = 00200;
+ /** {@hide} */ public static final int S_IXUSR = 00100;
- public static final int S_IRWXG = 00070;
- public static final int S_IRGRP = 00040;
- public static final int S_IWGRP = 00020;
- public static final int S_IXGRP = 00010;
+ /** {@hide} */ public static final int S_IRWXG = 00070;
+ /** {@hide} */ public static final int S_IRGRP = 00040;
+ /** {@hide} */ public static final int S_IWGRP = 00020;
+ /** {@hide} */ public static final int S_IXGRP = 00010;
- public static final int S_IRWXO = 00007;
- public static final int S_IROTH = 00004;
- public static final int S_IWOTH = 00002;
- public static final int S_IXOTH = 00001;
+ /** {@hide} */ public static final int S_IRWXO = 00007;
+ /** {@hide} */ public static final int S_IROTH = 00004;
+ /** {@hide} */ public static final int S_IWOTH = 00002;
+ /** {@hide} */ public static final int S_IXOTH = 00001;
+
+ private FileUtils() {
+ }
/** Regular expression for safe filenames: no spaces or metacharacters.
*
@@ -94,6 +97,9 @@ public class FileUtils {
private static final long COPY_CHECKPOINT_BYTES = 524288;
+ /**
+ * Listener that is called periodically as progress is made.
+ */
public interface ProgressListener {
public void onProgress(long progress);
}
@@ -105,6 +111,7 @@ public class FileUtils {
* @param uid to apply through {@code chown}, or -1 to leave unchanged
* @param gid to apply through {@code chown}, or -1 to leave unchanged
* @return 0 on success, otherwise errno.
+ * @hide
*/
public static int setPermissions(File path, int mode, int uid, int gid) {
return setPermissions(path.getAbsolutePath(), mode, uid, gid);
@@ -117,6 +124,7 @@ public class FileUtils {
* @param uid to apply through {@code chown}, or -1 to leave unchanged
* @param gid to apply through {@code chown}, or -1 to leave unchanged
* @return 0 on success, otherwise errno.
+ * @hide
*/
public static int setPermissions(String path, int mode, int uid, int gid) {
try {
@@ -145,6 +153,7 @@ public class FileUtils {
* @param uid to apply through {@code chown}, or -1 to leave unchanged
* @param gid to apply through {@code chown}, or -1 to leave unchanged
* @return 0 on success, otherwise errno.
+ * @hide
*/
public static int setPermissions(FileDescriptor fd, int mode, int uid, int gid) {
try {
@@ -166,7 +175,14 @@ public class FileUtils {
return 0;
}
- public static void copyPermissions(File from, File to) throws IOException {
+ /**
+ * Copy the owner UID, owner GID, and mode bits from one file to another.
+ *
+ * @param from File where attributes should be copied from.
+ * @param to File where attributes should be copied to.
+ * @hide
+ */
+ public static void copyPermissions(@NonNull File from, @NonNull File to) throws IOException {
try {
final StructStat stat = Os.stat(from.getAbsolutePath());
Os.chmod(to.getAbsolutePath(), stat.st_mode);
@@ -177,8 +193,10 @@ public class FileUtils {
}
/**
- * Return owning UID of given path, otherwise -1.
+ * @deprecated use {@link Os#stat(String)} instead.
+ * @hide
*/
+ @Deprecated
public static int getUid(String path) {
try {
return Os.stat(path).st_uid;
@@ -190,6 +208,8 @@ public class FileUtils {
/**
* Perform an fsync on the given FileOutputStream. The stream at this
* point must be flushed but not yet closed.
+ *
+ * @hide
*/
public static boolean sync(FileOutputStream stream) {
try {
@@ -204,6 +224,7 @@ public class FileUtils {
/**
* @deprecated use {@link #copy(File, File)} instead.
+ * @hide
*/
@Deprecated
public static boolean copyFile(File srcFile, File destFile) {
@@ -217,6 +238,7 @@ public class FileUtils {
/**
* @deprecated use {@link #copy(File, File)} instead.
+ * @hide
*/
@Deprecated
public static void copyFileOrThrow(File srcFile, File destFile) throws IOException {
@@ -227,6 +249,7 @@ public class FileUtils {
/**
* @deprecated use {@link #copy(InputStream, OutputStream)} instead.
+ * @hide
*/
@Deprecated
public static boolean copyToFile(InputStream inputStream, File destFile) {
@@ -240,6 +263,7 @@ public class FileUtils {
/**
* @deprecated use {@link #copy(InputStream, OutputStream)} instead.
+ * @hide
*/
@Deprecated
public static void copyToFileOrThrow(InputStream in, File destFile) throws IOException {
@@ -265,7 +289,7 @@ public class FileUtils {
* @return number of bytes copied.
*/
public static long copy(@NonNull File from, @NonNull File to) throws IOException {
- return copy(from, to, null, null);
+ return copy(from, to, null, null, null);
}
/**
@@ -274,16 +298,17 @@ public class FileUtils {
* Attempts to use several optimization strategies to copy the data in the
* kernel before falling back to a userspace copy as a last resort.
*
- * @param listener to be periodically notified as the copy progresses.
* @param signal to signal if the copy should be cancelled early.
+ * @param executor that listener events should be delivered via.
+ * @param listener to be periodically notified as the copy progresses.
* @return number of bytes copied.
*/
public static long copy(@NonNull File from, @NonNull File to,
- @Nullable ProgressListener listener, @Nullable CancellationSignal signal)
- throws IOException {
+ @Nullable CancellationSignal signal, @Nullable Executor executor,
+ @Nullable ProgressListener listener) throws IOException {
try (FileInputStream in = new FileInputStream(from);
FileOutputStream out = new FileOutputStream(to)) {
- return copy(in, out, listener, signal);
+ return copy(in, out, signal, executor, listener);
}
}
@@ -296,7 +321,7 @@ public class FileUtils {
* @return number of bytes copied.
*/
public static long copy(@NonNull InputStream in, @NonNull OutputStream out) throws IOException {
- return copy(in, out, null, null);
+ return copy(in, out, null, null, null);
}
/**
@@ -305,22 +330,23 @@ public class FileUtils {
* Attempts to use several optimization strategies to copy the data in the
* kernel before falling back to a userspace copy as a last resort.
*
- * @param listener to be periodically notified as the copy progresses.
* @param signal to signal if the copy should be cancelled early.
+ * @param executor that listener events should be delivered via.
+ * @param listener to be periodically notified as the copy progresses.
* @return number of bytes copied.
*/
public static long copy(@NonNull InputStream in, @NonNull OutputStream out,
- @Nullable ProgressListener listener, @Nullable CancellationSignal signal)
- throws IOException {
+ @Nullable CancellationSignal signal, @Nullable Executor executor,
+ @Nullable ProgressListener listener) throws IOException {
if (ENABLE_COPY_OPTIMIZATIONS) {
if (in instanceof FileInputStream && out instanceof FileOutputStream) {
return copy(((FileInputStream) in).getFD(), ((FileOutputStream) out).getFD(),
- listener, signal);
+ signal, executor, listener);
}
}
// Worse case fallback to userspace
- return copyInternalUserspace(in, out, listener, signal);
+ return copyInternalUserspace(in, out, signal, executor, listener);
}
/**
@@ -333,7 +359,7 @@ public class FileUtils {
*/
public static long copy(@NonNull FileDescriptor in, @NonNull FileDescriptor out)
throws IOException {
- return copy(in, out, null, null);
+ return copy(in, out, null, null, null);
}
/**
@@ -342,14 +368,15 @@ public class FileUtils {
* Attempts to use several optimization strategies to copy the data in the
* kernel before falling back to a userspace copy as a last resort.
*
- * @param listener to be periodically notified as the copy progresses.
* @param signal to signal if the copy should be cancelled early.
+ * @param executor that listener events should be delivered via.
+ * @param listener to be periodically notified as the copy progresses.
* @return number of bytes copied.
*/
public static long copy(@NonNull FileDescriptor in, @NonNull FileDescriptor out,
- @Nullable ProgressListener listener, @Nullable CancellationSignal signal)
- throws IOException {
- return copy(in, out, listener, signal, Long.MAX_VALUE);
+ @Nullable CancellationSignal signal, @Nullable Executor executor,
+ @Nullable ProgressListener listener) throws IOException {
+ return copy(in, out, Long.MAX_VALUE, signal, executor, listener);
}
/**
@@ -358,22 +385,24 @@ public class FileUtils {
* Attempts to use several optimization strategies to copy the data in the
* kernel before falling back to a userspace copy as a last resort.
*
- * @param listener to be periodically notified as the copy progresses.
- * @param signal to signal if the copy should be cancelled early.
* @param count the number of bytes to copy.
+ * @param signal to signal if the copy should be cancelled early.
+ * @param executor that listener events should be delivered via.
+ * @param listener to be periodically notified as the copy progresses.
* @return number of bytes copied.
+ * @hide
*/
- public static long copy(@NonNull FileDescriptor in, @NonNull FileDescriptor out,
- @Nullable ProgressListener listener, @Nullable CancellationSignal signal, long count)
- throws IOException {
+ public static long copy(@NonNull FileDescriptor in, @NonNull FileDescriptor out, long count,
+ @Nullable CancellationSignal signal, @Nullable Executor executor,
+ @Nullable ProgressListener listener) throws IOException {
if (ENABLE_COPY_OPTIMIZATIONS) {
try {
final StructStat st_in = Os.fstat(in);
final StructStat st_out = Os.fstat(out);
if (S_ISREG(st_in.st_mode) && S_ISREG(st_out.st_mode)) {
- return copyInternalSendfile(in, out, listener, signal, count);
+ return copyInternalSendfile(in, out, count, signal, executor, listener);
} else if (S_ISFIFO(st_in.st_mode) || S_ISFIFO(st_out.st_mode)) {
- return copyInternalSplice(in, out, listener, signal, count);
+ return copyInternalSplice(in, out, count, signal, executor, listener);
}
} catch (ErrnoException e) {
throw e.rethrowAsIOException();
@@ -381,15 +410,17 @@ public class FileUtils {
}
// Worse case fallback to userspace
- return copyInternalUserspace(in, out, listener, signal, count);
+ return copyInternalUserspace(in, out, count, signal, executor, listener);
}
/**
* Requires one of input or output to be a pipe.
+ *
+ * @hide
*/
@VisibleForTesting
- public static long copyInternalSplice(FileDescriptor in, FileDescriptor out,
- ProgressListener listener, CancellationSignal signal, long count)
+ public static long copyInternalSplice(FileDescriptor in, FileDescriptor out, long count,
+ CancellationSignal signal, Executor executor, ProgressListener listener)
throws ErrnoException {
long progress = 0;
long checkpoint = 0;
@@ -405,24 +436,32 @@ public class FileUtils {
if (signal != null) {
signal.throwIfCanceled();
}
- if (listener != null) {
- listener.onProgress(progress);
+ if (executor != null && listener != null) {
+ final long progressSnapshot = progress;
+ executor.execute(() -> {
+ listener.onProgress(progressSnapshot);
+ });
}
checkpoint = 0;
}
}
- if (listener != null) {
- listener.onProgress(progress);
+ if (executor != null && listener != null) {
+ final long progressSnapshot = progress;
+ executor.execute(() -> {
+ listener.onProgress(progressSnapshot);
+ });
}
return progress;
}
/**
* Requires both input and output to be a regular file.
+ *
+ * @hide
*/
@VisibleForTesting
- public static long copyInternalSendfile(FileDescriptor in, FileDescriptor out,
- ProgressListener listener, CancellationSignal signal, long count)
+ public static long copyInternalSendfile(FileDescriptor in, FileDescriptor out, long count,
+ CancellationSignal signal, Executor executor, ProgressListener listener)
throws ErrnoException {
long progress = 0;
long checkpoint = 0;
@@ -437,33 +476,52 @@ public class FileUtils {
if (signal != null) {
signal.throwIfCanceled();
}
- if (listener != null) {
- listener.onProgress(progress);
+ if (executor != null && listener != null) {
+ final long progressSnapshot = progress;
+ executor.execute(() -> {
+ listener.onProgress(progressSnapshot);
+ });
}
checkpoint = 0;
}
}
- if (listener != null) {
- listener.onProgress(progress);
+ if (executor != null && listener != null) {
+ final long progressSnapshot = progress;
+ executor.execute(() -> {
+ listener.onProgress(progressSnapshot);
+ });
}
return progress;
}
+ /** {@hide} */
+ @Deprecated
@VisibleForTesting
public static long copyInternalUserspace(FileDescriptor in, FileDescriptor out,
- ProgressListener listener, CancellationSignal signal, long count) throws IOException {
+ ProgressListener listener, CancellationSignal signal, long count)
+ throws IOException {
+ return copyInternalUserspace(in, out, count, signal, Runnable::run, listener);
+ }
+
+ /** {@hide} */
+ @VisibleForTesting
+ public static long copyInternalUserspace(FileDescriptor in, FileDescriptor out, long count,
+ CancellationSignal signal, Executor executor, ProgressListener listener)
+ throws IOException {
if (count != Long.MAX_VALUE) {
return copyInternalUserspace(new SizedInputStream(new FileInputStream(in), count),
- new FileOutputStream(out), listener, signal);
+ new FileOutputStream(out), signal, executor, listener);
} else {
return copyInternalUserspace(new FileInputStream(in),
- new FileOutputStream(out), listener, signal);
+ new FileOutputStream(out), signal, executor, listener);
}
}
+ /** {@hide} */
@VisibleForTesting
public static long copyInternalUserspace(InputStream in, OutputStream out,
- ProgressListener listener, CancellationSignal signal) throws IOException {
+ CancellationSignal signal, Executor executor, ProgressListener listener)
+ throws IOException {
long progress = 0;
long checkpoint = 0;
byte[] buffer = new byte[8192];
@@ -479,14 +537,20 @@ public class FileUtils {
if (signal != null) {
signal.throwIfCanceled();
}
- if (listener != null) {
- listener.onProgress(progress);
+ if (executor != null && listener != null) {
+ final long progressSnapshot = progress;
+ executor.execute(() -> {
+ listener.onProgress(progressSnapshot);
+ });
}
checkpoint = 0;
}
}
- if (listener != null) {
- listener.onProgress(progress);
+ if (executor != null && listener != null) {
+ final long progressSnapshot = progress;
+ executor.execute(() -> {
+ listener.onProgress(progressSnapshot);
+ });
}
return progress;
}
@@ -494,6 +558,7 @@ public class FileUtils {
/**
* Check if a filename is "safe" (no metacharacters or spaces).
* @param file The file to check
+ * @hide
*/
public static boolean isFilenameSafe(File file) {
// Note, we check whether it matches what's known to be safe,
@@ -509,6 +574,7 @@ public class FileUtils {
* @param ellipsis to add of the file was truncated (can be null)
* @return the contents of the file, possibly truncated
* @throws IOException if something goes wrong reading the file
+ * @hide
*/
public static String readTextFile(File file, int max, String ellipsis) throws IOException {
InputStream input = new FileInputStream(file);
@@ -563,13 +629,16 @@ public class FileUtils {
}
}
+ /** {@hide} */
public static void stringToFile(File file, String string) throws IOException {
stringToFile(file.getAbsolutePath(), string);
}
- /*
+ /**
* Writes the bytes given in {@code content} to the file whose absolute path
* is {@code filename}.
+ *
+ * @hide
*/
public static void bytesToFile(String filename, byte[] content) throws IOException {
if (filename.startsWith("/proc/")) {
@@ -592,18 +661,23 @@ public class FileUtils {
* @param filename
* @param string
* @throws IOException
+ * @hide
*/
public static void stringToFile(String filename, String string) throws IOException {
bytesToFile(filename, string.getBytes(StandardCharsets.UTF_8));
}
/**
- * Computes the checksum of a file using the CRC32 checksum routine.
- * The value of the checksum is returned.
+ * Computes the checksum of a file using the CRC32 checksum routine. The
+ * value of the checksum is returned.
*
- * @param file the file to checksum, must not be null
+ * @param file the file to checksum, must not be null
* @return the checksum value or an exception is thrown.
+ * @deprecated this is a weak hashing algorithm, and should not be used due
+ * to its potential for collision.
+ * @hide
*/
+ @Deprecated
public static long checksumCrc32(File file) throws FileNotFoundException, IOException {
CRC32 checkSummer = new CRC32();
CheckedInputStream cis = null;
@@ -632,6 +706,7 @@ public class FileUtils {
* @param minCount Always keep at least this many files.
* @param minAgeMs Always keep files younger than this age, in milliseconds.
* @return if any files were deleted.
+ * @hide
*/
public static boolean deleteOlderFiles(File dir, int minCount, long minAgeMs) {
if (minCount < 0 || minAgeMs < 0) {
@@ -673,6 +748,8 @@ public class FileUtils {
* Both files <em>must</em> have been resolved using
* {@link File#getCanonicalFile()} to avoid symlink or path traversal
* attacks.
+ *
+ * @hide
*/
public static boolean contains(File[] dirs, File file) {
for (File dir : dirs) {
@@ -690,12 +767,15 @@ public class FileUtils {
* Both files <em>must</em> have been resolved using
* {@link File#getCanonicalFile()} to avoid symlink or path traversal
* attacks.
+ *
+ * @hide
*/
public static boolean contains(File dir, File file) {
if (dir == null || file == null) return false;
return contains(dir.getAbsolutePath(), file.getAbsolutePath());
}
+ /** {@hide} */
public static boolean contains(String dirPath, String filePath) {
if (dirPath.equals(filePath)) {
return true;
@@ -706,6 +786,7 @@ public class FileUtils {
return filePath.startsWith(dirPath);
}
+ /** {@hide} */
public static boolean deleteContentsAndDir(File dir) {
if (deleteContents(dir)) {
return dir.delete();
@@ -714,6 +795,7 @@ public class FileUtils {
}
}
+ /** {@hide} */
public static boolean deleteContents(File dir) {
File[] files = dir.listFiles();
boolean success = true;
@@ -743,6 +825,8 @@ public class FileUtils {
/**
* Check if given filename is valid for an ext4 filesystem.
+ *
+ * @hide
*/
public static boolean isValidExtFilename(String name) {
return (name != null) && name.equals(buildValidExtFilename(name));
@@ -751,6 +835,8 @@ public class FileUtils {
/**
* Mutate the given filename to make it valid for an ext4 filesystem,
* replacing any invalid characters with "_".
+ *
+ * @hide
*/
public static String buildValidExtFilename(String name) {
if (TextUtils.isEmpty(name) || ".".equals(name) || "..".equals(name)) {
@@ -792,6 +878,8 @@ public class FileUtils {
/**
* Check if given filename is valid for a FAT filesystem.
+ *
+ * @hide
*/
public static boolean isValidFatFilename(String name) {
return (name != null) && name.equals(buildValidFatFilename(name));
@@ -800,6 +888,8 @@ public class FileUtils {
/**
* Mutate the given filename to make it valid for a FAT filesystem,
* replacing any invalid characters with "_".
+ *
+ * @hide
*/
public static String buildValidFatFilename(String name) {
if (TextUtils.isEmpty(name) || ".".equals(name) || "..".equals(name)) {
@@ -820,6 +910,7 @@ public class FileUtils {
return res.toString();
}
+ /** {@hide} */
@VisibleForTesting
public static String trimFilename(String str, int maxBytes) {
final StringBuilder res = new StringBuilder(str);
@@ -827,6 +918,7 @@ public class FileUtils {
return res.toString();
}
+ /** {@hide} */
private static void trimFilename(StringBuilder res, int maxBytes) {
byte[] raw = res.toString().getBytes(StandardCharsets.UTF_8);
if (raw.length > maxBytes) {
@@ -839,12 +931,14 @@ public class FileUtils {
}
}
+ /** {@hide} */
public static String rewriteAfterRename(File beforeDir, File afterDir, String path) {
if (path == null) return null;
final File result = rewriteAfterRename(beforeDir, afterDir, new File(path));
return (result != null) ? result.getAbsolutePath() : null;
}
+ /** {@hide} */
public static String[] rewriteAfterRename(File beforeDir, File afterDir, String[] paths) {
if (paths == null) return null;
final String[] result = new String[paths.length];
@@ -858,6 +952,8 @@ public class FileUtils {
* Given a path under the "before" directory, rewrite it to live under the
* "after" directory. For example, {@code /before/foo/bar.txt} would become
* {@code /after/foo/bar.txt}.
+ *
+ * @hide
*/
public static File rewriteAfterRename(File beforeDir, File afterDir, File file) {
if (file == null || beforeDir == null || afterDir == null) return null;
@@ -869,6 +965,7 @@ public class FileUtils {
return null;
}
+ /** {@hide} */
private static File buildUniqueFileWithExtension(File parent, String name, String ext)
throws FileNotFoundException {
File file = buildFile(parent, name, ext);
@@ -895,6 +992,7 @@ public class FileUtils {
* 'example.txt' or 'example (1).txt', etc.
*
* @throws FileNotFoundException
+ * @hide
*/
public static File buildUniqueFile(File parent, String mimeType, String displayName)
throws FileNotFoundException {
@@ -905,6 +1003,8 @@ public class FileUtils {
/**
* Generates a unique file name under the given parent directory, keeping
* any extension intact.
+ *
+ * @hide
*/
public static File buildUniqueFile(File parent, String displayName)
throws FileNotFoundException {
@@ -929,6 +1029,8 @@ public class FileUtils {
* If the display name doesn't have an extension that matches the requested MIME type, the
* extension is regarded as a part of filename and default extension for that MIME type is
* appended.
+ *
+ * @hide
*/
public static String[] splitFileName(String mimeType, String displayName) {
String name;
@@ -975,6 +1077,7 @@ public class FileUtils {
return new String[] { name, ext };
}
+ /** {@hide} */
private static File buildFile(File parent, String name, String ext) {
if (TextUtils.isEmpty(ext)) {
return new File(parent, name);
@@ -983,6 +1086,7 @@ public class FileUtils {
}
}
+ /** {@hide} */
public static @NonNull String[] listOrEmpty(@Nullable File dir) {
if (dir == null) return EmptyArray.STRING;
final String[] res = dir.list();
@@ -993,6 +1097,7 @@ public class FileUtils {
}
}
+ /** {@hide} */
public static @NonNull File[] listFilesOrEmpty(@Nullable File dir) {
if (dir == null) return EMPTY;
final File[] res = dir.listFiles();
@@ -1003,6 +1108,7 @@ public class FileUtils {
}
}
+ /** {@hide} */
public static @NonNull File[] listFilesOrEmpty(@Nullable File dir, FilenameFilter filter) {
if (dir == null) return EMPTY;
final File[] res = dir.listFiles(filter);
@@ -1013,6 +1119,7 @@ public class FileUtils {
}
}
+ /** {@hide} */
public static @Nullable File newFileOrNull(@Nullable String path) {
return (path != null) ? new File(path) : null;
}
@@ -1021,6 +1128,8 @@ public class FileUtils {
* Creates a directory with name {@code name} under an existing directory {@code baseDir}.
* Returns a {@code File} object representing the directory on success, {@code null} on
* failure.
+ *
+ * @hide
*/
public static @Nullable File createDir(File baseDir, String name) {
final File dir = new File(baseDir, name);
@@ -1036,6 +1145,8 @@ public class FileUtils {
* Round the given size of a storage device to a nice round power-of-two
* value, such as 256MB or 32GB. This avoids showing weird values like
* "29.5GB" in UI.
+ *
+ * @hide
*/
public static long roundStorageSize(long size) {
long val = 1;
@@ -1050,6 +1161,23 @@ public class FileUtils {
return val * pow;
}
+ /**
+ * Closes the given object quietly, ignoring any checked exceptions. Does
+ * nothing if the given object is {@code null}.
+ */
+ public static void closeQuietly(@Nullable AutoCloseable closeable) {
+ IoUtils.closeQuietly(closeable);
+ }
+
+ /**
+ * Closes the given object quietly, ignoring any checked exceptions. Does
+ * nothing if the given object is {@code null}.
+ */
+ public static void closeQuietly(@Nullable FileDescriptor fd) {
+ IoUtils.closeQuietly(fd);
+ }
+
+ /** {@hide} */
@VisibleForTesting
public static class MemoryPipe extends Thread implements AutoCloseable {
private final FileDescriptor[] pipe;
diff --git a/core/java/android/print/PrintFileDocumentAdapter.java b/core/java/android/print/PrintFileDocumentAdapter.java
index a5f93050e307..eb4b31510880 100644
--- a/core/java/android/print/PrintFileDocumentAdapter.java
+++ b/core/java/android/print/PrintFileDocumentAdapter.java
@@ -118,7 +118,7 @@ public class PrintFileDocumentAdapter extends PrintDocumentAdapter {
protected Void doInBackground(Void... params) {
try (InputStream in = new FileInputStream(mFile);
OutputStream out = new FileOutputStream(mDestination.getFileDescriptor())) {
- FileUtils.copy(in, out, null, mCancellationSignal);
+ FileUtils.copy(in, out, mCancellationSignal, null, null);
} catch (OperationCanceledException e) {
// Ignored; already handled below
} catch (IOException e) {
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index a80dcedf9915..f97c64c96a7a 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -100,7 +100,8 @@ public final class DocumentsContract {
public static final String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER";
/** {@hide} */
- public static final String EXTRA_PACKAGE_NAME = "android.content.extra.PACKAGE_NAME";
+ @Deprecated
+ public static final String EXTRA_PACKAGE_NAME = Intent.EXTRA_PACKAGE_NAME;
/** {@hide} */
public static final String EXTRA_SHOW_ADVANCED = "android.content.extra.SHOW_ADVANCED";
diff --git a/core/tests/benchmarks/src/android/os/FileUtilsBenchmark.java b/core/tests/benchmarks/src/android/os/FileUtilsBenchmark.java
index 5989da7af655..c70fc3cce43c 100644
--- a/core/tests/benchmarks/src/android/os/FileUtilsBenchmark.java
+++ b/core/tests/benchmarks/src/android/os/FileUtilsBenchmark.java
@@ -54,7 +54,7 @@ public class FileUtilsBenchmark {
for (int i = 0; i < reps; i++) {
try (FileInputStream in = new FileInputStream(mSrc);
FileOutputStream out = new FileOutputStream(mDest)) {
- copyInternalUserspace(in.getFD(), out.getFD(), null, null, Long.MAX_VALUE);
+ copyInternalUserspace(in.getFD(), out.getFD(), Long.MAX_VALUE, null, null, null);
}
}
}
@@ -63,7 +63,7 @@ public class FileUtilsBenchmark {
for (int i = 0; i < reps; i++) {
try (FileInputStream in = new FileInputStream(mSrc);
FileOutputStream out = new FileOutputStream(mDest)) {
- copyInternalSendfile(in.getFD(), out.getFD(), null, null, Long.MAX_VALUE);
+ copyInternalSendfile(in.getFD(), out.getFD(), Long.MAX_VALUE, null, null, null);
}
}
}
@@ -72,7 +72,7 @@ public class FileUtilsBenchmark {
for (int i = 0; i < reps; i++) {
try (MemoryPipe in = MemoryPipe.createSource(mData);
FileOutputStream out = new FileOutputStream(mDest)) {
- copyInternalUserspace(in.getFD(), out.getFD(), null, null, Long.MAX_VALUE);
+ copyInternalUserspace(in.getFD(), out.getFD(), Long.MAX_VALUE, null, null, null);
}
}
}
@@ -81,7 +81,7 @@ public class FileUtilsBenchmark {
for (int i = 0; i < reps; i++) {
try (MemoryPipe in = MemoryPipe.createSource(mData);
FileOutputStream out = new FileOutputStream(mDest)) {
- copyInternalSplice(in.getFD(), out.getFD(), null, null, Long.MAX_VALUE);
+ copyInternalSplice(in.getFD(), out.getFD(), Long.MAX_VALUE, null, null, null);
}
}
}
@@ -90,7 +90,7 @@ public class FileUtilsBenchmark {
for (int i = 0; i < reps; i++) {
try (FileInputStream in = new FileInputStream(mSrc);
MemoryPipe out = MemoryPipe.createSink(mData)) {
- copyInternalUserspace(in.getFD(), out.getFD(), null, null, Long.MAX_VALUE);
+ copyInternalUserspace(in.getFD(), out.getFD(), Long.MAX_VALUE, null, null, null);
}
}
}
@@ -99,7 +99,7 @@ public class FileUtilsBenchmark {
for (int i = 0; i < reps; i++) {
try (FileInputStream in = new FileInputStream(mSrc);
MemoryPipe out = MemoryPipe.createSink(mData)) {
- copyInternalSplice(in.getFD(), out.getFD(), null, null, Long.MAX_VALUE);
+ copyInternalSplice(in.getFD(), out.getFD(), Long.MAX_VALUE, null, null, null);
}
}
}
diff --git a/core/tests/coretests/src/android/os/FileUtilsTest.java b/core/tests/coretests/src/android/os/FileUtilsTest.java
index 0bc3a2d879ab..9c9f11b76ab4 100644
--- a/core/tests/coretests/src/android/os/FileUtilsTest.java
+++ b/core/tests/coretests/src/android/os/FileUtilsTest.java
@@ -193,7 +193,7 @@ public class FileUtilsTest {
try (MemoryPipe in = MemoryPipe.createSource(source);
FileOutputStream out = new FileOutputStream(dest)) {
- FileUtils.copy(in.getFD(), out.getFD(), null, null, size);
+ FileUtils.copy(in.getFD(), out.getFD(), size, null, null, null);
}
actual = readFile(dest);
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 06fbf9f6e1c1..59f272ff70f6 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -297,7 +297,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
+ " cannot be null");
}
- mCallingPackageName = extras.getString(DocumentsContract.EXTRA_PACKAGE_NAME);
+ mCallingPackageName = extras.getString(Intent.EXTRA_PACKAGE_NAME);
if (savedInstanceState == null) {
MetricsLogger.action(this, MetricsEvent.PRINT_PREVIEW, mCallingPackageName);
@@ -715,7 +715,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.setType("application/pdf");
intent.putExtra(Intent.EXTRA_TITLE, info.getName());
- intent.putExtra(DocumentsContract.EXTRA_PACKAGE_NAME, mCallingPackageName);
+ intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mCallingPackageName);
try {
startActivityForResult(intent, ACTIVITY_REQUEST_CREATE_FILE);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index fa934fe23fff..9b6850b3c798 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -685,13 +685,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
// inserted above to hold the session active.
try {
final Int64Ref last = new Int64Ref(0);
- FileUtils.copy(incomingFd.getFileDescriptor(), targetFd, (long progress) -> {
- if (params.sizeBytes > 0) {
- final long delta = progress - last.value;
- last.value = progress;
- addClientProgress((float) delta / (float) params.sizeBytes);
- }
- }, null, lengthBytes);
+ FileUtils.copy(incomingFd.getFileDescriptor(), targetFd, lengthBytes, null,
+ Runnable::run, (long progress) -> {
+ if (params.sizeBytes > 0) {
+ final long delta = progress - last.value;
+ last.value = progress;
+ addClientProgress((float) delta / (float) params.sizeBytes);
+ }
+ });
} finally {
IoUtils.closeQuietly(targetFd);
IoUtils.closeQuietly(incomingFd);
diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java
index 4fbc14c0097f..e8266a574bf5 100644
--- a/services/print/java/com/android/server/print/UserState.java
+++ b/services/print/java/com/android/server/print/UserState.java
@@ -243,7 +243,7 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks,
intent.setData(Uri.fromParts("printjob", printJob.getId().flattenToString(), null));
intent.putExtra(PrintManager.EXTRA_PRINT_DOCUMENT_ADAPTER, adapter.asBinder());
intent.putExtra(PrintManager.EXTRA_PRINT_JOB, printJob);
- intent.putExtra(DocumentsContract.EXTRA_PACKAGE_NAME, packageName);
+ intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
IntentSender intentSender = PendingIntent.getActivityAsUser(
mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT