Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ebf8ad5d authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

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
parent b341a24b
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -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,17 +345,21 @@ 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;
    }

    /**
     * Test if a file lives under the given directory, either as a direct child
+7 −5
Original line number Diff line number Diff line
@@ -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");
    }

+22 −11
Original line number Diff line number Diff line
@@ -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);
        }