Update DrmOutputStream to use raw FileDescriptor.
This allows DownloadManager to use FDs, paving the way for downloading directly to content:// Uris. Also return flag indicating if deleteOlderFiles() actually deleted anything. Update tests to verify. Bug: 5287571 Change-Id: I2579e5e2113f31b2860d7b021bd61c91b6310963
This commit is contained in:
@@ -326,14 +326,15 @@ public class FileUtils {
|
||||
*
|
||||
* @param minCount Always keep at least this many files.
|
||||
* @param minAge Always keep files younger than this age.
|
||||
* @return if any files were deleted.
|
||||
*/
|
||||
public static void deleteOlderFiles(File dir, int minCount, long minAge) {
|
||||
public static boolean deleteOlderFiles(File dir, int minCount, long minAge) {
|
||||
if (minCount < 0 || minAge < 0) {
|
||||
throw new IllegalArgumentException("Constraints must be positive or 0");
|
||||
}
|
||||
|
||||
final File[] files = dir.listFiles();
|
||||
if (files == null) return;
|
||||
if (files == null) return false;
|
||||
|
||||
// Sort with newest files first
|
||||
Arrays.sort(files, new Comparator<File>() {
|
||||
@@ -344,16 +345,20 @@ public class FileUtils {
|
||||
});
|
||||
|
||||
// Keep at least minCount files
|
||||
boolean deleted = false;
|
||||
for (int i = minCount; i < files.length; i++) {
|
||||
final File file = files[i];
|
||||
|
||||
// Keep files newer than minAge
|
||||
final long age = System.currentTimeMillis() - file.lastModified();
|
||||
if (age > minAge) {
|
||||
Log.d(TAG, "Deleting old file " + file);
|
||||
file.delete();
|
||||
if (file.delete()) {
|
||||
Log.d(TAG, "Deleted old file " + file);
|
||||
deleted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -140,7 +140,7 @@ public class FileUtilsTest extends AndroidTestCase {
|
||||
touch("file3", 2 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
|
||||
touch("file4", 3 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
|
||||
touch("file5", 4 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
|
||||
FileUtils.deleteOlderFiles(mDir, 3, DAY_IN_MILLIS);
|
||||
assertTrue(FileUtils.deleteOlderFiles(mDir, 3, DAY_IN_MILLIS));
|
||||
assertDirContents("file1", "file2", "file3");
|
||||
}
|
||||
|
||||
@@ -148,13 +148,13 @@ public class FileUtilsTest extends AndroidTestCase {
|
||||
touch("file1", -HOUR_IN_MILLIS);
|
||||
touch("file2", HOUR_IN_MILLIS);
|
||||
touch("file3", WEEK_IN_MILLIS);
|
||||
FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS);
|
||||
assertTrue(FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS));
|
||||
assertDirContents("file1", "file2");
|
||||
|
||||
touch("file1", -HOUR_IN_MILLIS);
|
||||
touch("file2", HOUR_IN_MILLIS);
|
||||
touch("file3", WEEK_IN_MILLIS);
|
||||
FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS);
|
||||
assertTrue(FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS));
|
||||
assertDirContents("file1", "file2");
|
||||
}
|
||||
|
||||
@@ -164,7 +164,8 @@ public class FileUtilsTest extends AndroidTestCase {
|
||||
touch("file3", 2 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
|
||||
touch("file4", 3 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
|
||||
touch("file5", 4 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
|
||||
FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS);
|
||||
assertTrue(FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS));
|
||||
assertFalse(FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS));
|
||||
assertDirContents("file1");
|
||||
}
|
||||
|
||||
@@ -174,7 +175,8 @@ public class FileUtilsTest extends AndroidTestCase {
|
||||
touch("file3", 2 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
|
||||
touch("file4", 3 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
|
||||
touch("file5", 4 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
|
||||
FileUtils.deleteOlderFiles(mDir, 2, 0);
|
||||
assertTrue(FileUtils.deleteOlderFiles(mDir, 2, 0));
|
||||
assertFalse(FileUtils.deleteOlderFiles(mDir, 2, 0));
|
||||
assertDirContents("file1", "file2");
|
||||
}
|
||||
|
||||
|
||||
@@ -18,18 +18,23 @@ package android.drm;
|
||||
|
||||
import static android.drm.DrmConvertedStatus.STATUS_OK;
|
||||
import static android.drm.DrmManagerClient.INVALID_SESSION;
|
||||
import static libcore.io.OsConstants.SEEK_SET;
|
||||
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.util.Log;
|
||||
|
||||
import libcore.io.ErrnoException;
|
||||
import libcore.io.IoBridge;
|
||||
import libcore.io.Libcore;
|
||||
import libcore.io.Streams;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.UnknownServiceException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import libcore.io.Streams;
|
||||
|
||||
/**
|
||||
* Stream that applies a {@link DrmManagerClient} transformation to data before
|
||||
* writing to disk, similar to a {@link FilterOutputStream}.
|
||||
@@ -40,17 +45,19 @@ public class DrmOutputStream extends OutputStream {
|
||||
private static final String TAG = "DrmOutputStream";
|
||||
|
||||
private final DrmManagerClient mClient;
|
||||
private final RandomAccessFile mFile;
|
||||
private final ParcelFileDescriptor mPfd;
|
||||
private final FileDescriptor mFd;
|
||||
|
||||
private int mSessionId = INVALID_SESSION;
|
||||
|
||||
/**
|
||||
* @param file Opened with "rw" mode.
|
||||
* @param pfd Opened with "rw" mode.
|
||||
*/
|
||||
public DrmOutputStream(DrmManagerClient client, RandomAccessFile file, String mimeType)
|
||||
public DrmOutputStream(DrmManagerClient client, ParcelFileDescriptor pfd, String mimeType)
|
||||
throws IOException {
|
||||
mClient = client;
|
||||
mFile = file;
|
||||
mPfd = pfd;
|
||||
mFd = pfd.getFileDescriptor();
|
||||
|
||||
mSessionId = mClient.openConvertSession(mimeType);
|
||||
if (mSessionId == INVALID_SESSION) {
|
||||
@@ -61,8 +68,12 @@ public class DrmOutputStream extends OutputStream {
|
||||
public void finish() throws IOException {
|
||||
final DrmConvertedStatus status = mClient.closeConvertSession(mSessionId);
|
||||
if (status.statusCode == STATUS_OK) {
|
||||
mFile.seek(status.offset);
|
||||
mFile.write(status.convertedData);
|
||||
try {
|
||||
Libcore.os.lseek(mFd, status.offset, SEEK_SET);
|
||||
} catch (ErrnoException e) {
|
||||
e.rethrowAsIOException();
|
||||
}
|
||||
IoBridge.write(mFd, status.convertedData, 0, status.convertedData.length);
|
||||
mSessionId = INVALID_SESSION;
|
||||
} else {
|
||||
throw new IOException("Unexpected DRM status: " + status.statusCode);
|
||||
@@ -75,7 +86,7 @@ public class DrmOutputStream extends OutputStream {
|
||||
Log.w(TAG, "Closing stream without finishing");
|
||||
}
|
||||
|
||||
mFile.close();
|
||||
mPfd.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,7 +103,7 @@ public class DrmOutputStream extends OutputStream {
|
||||
|
||||
final DrmConvertedStatus status = mClient.convertData(mSessionId, exactBuffer);
|
||||
if (status.statusCode == STATUS_OK) {
|
||||
mFile.write(status.convertedData);
|
||||
IoBridge.write(mFd, status.convertedData, 0, status.convertedData.length);
|
||||
} else {
|
||||
throw new IOException("Unexpected DRM status: " + status.statusCode);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user