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

Commit 6e690ac8 authored by Tomasz Mikolajewski's avatar Tomasz Mikolajewski Committed by Android (Google) Code Review
Browse files

Merge "Add tests for copying virtual typed files."

parents f3378a29 f65fdebd
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -501,16 +501,23 @@ public class CopyService extends IntentService {

        // If the file is virtual, but can be converted to another format, then try to copy it
        // as such format. Also, append an extension for the target mime type (if known).
        if (srcInfo.isVirtualDocument() && srcInfo.isTypedDocument()) {
        if (srcInfo.isVirtualDocument()) {
            if (!srcInfo.isTypedDocument()) {
                // Impossible to copy a file which is virtual, but not typed.
                mFailedFiles.add(srcInfo);
                return false;
            }
            final String[] streamTypes = getContentResolver().getStreamTypes(
                    srcInfo.derivedUri, "*/*");
            if (streamTypes.length > 0) {
            if (streamTypes != null && streamTypes.length > 0) {
                dstMimeType = streamTypes[0];
                final String extension = MimeTypeMap.getSingleton().
                        getExtensionFromMimeType(dstMimeType);
                dstDisplayName = srcInfo.displayName +
                        (extension != null ? "." + extension : srcInfo.displayName);
            } else {
                // The provider says that it supports typed documents, but doesn't say
                // anything about available formats.
                // TODO: Log failures. b/26192412
                mFailedFiles.add(srcInfo);
                return false;
+58 −15
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ public class CopyServiceTest extends ServiceTestCase<CopyService> {

    public void testCopyFile() throws Exception {
        String srcPath = "/test0.txt";
        Uri testFile = mStorage.createFile(SRC_ROOT, srcPath, "text/plain",
        Uri testFile = mStorage.createRegularFile(SRC_ROOT, srcPath, "text/plain",
                "The five boxing wizards jump quickly".getBytes());

        startService(createCopyIntent(Lists.newArrayList(testFile)));
@@ -110,10 +110,33 @@ public class CopyServiceTest extends ServiceTestCase<CopyService> {
        assertCopied(srcPath);
    }

    public void testCopyVirtualTypedFile() throws Exception {
        String srcPath = "/virtual.sth";
        String expectedDstPath = "/virtual.sth.pdf";
        ArrayList<String> streamTypes = new ArrayList<>();
        streamTypes.add("application/pdf");
        streamTypes.add("text/html");
        String testContent = "I love fruit cakes!";
        Uri testFile = mStorage.createVirtualFile(SRC_ROOT, srcPath, "virtual/mime-type",
                streamTypes, testContent.getBytes());

        startService(createCopyIntent(Lists.newArrayList(testFile)));

        // 2 operations: file creation, then writing data.
        mResolver.waitForChanges(2);

        // Verify that one file was copied.
        assertDestFileCount(1);

        byte[] dstContent = readFile(DST_ROOT, expectedDstPath);
        MoreAsserts.assertEquals("Moved file contents differ", testContent.getBytes(), dstContent);
    }

    public void testMoveFile() throws Exception {
        String srcPath = "/test0.txt";
        String testContent = "The five boxing wizards jump quickly";
        Uri testFile = mStorage.createFile(SRC_ROOT, srcPath, "text/plain", testContent.getBytes());
        Uri testFile = mStorage.createRegularFile(SRC_ROOT, srcPath, "text/plain",
                testContent.getBytes());

        Intent moveIntent = createCopyIntent(Lists.newArrayList(testFile));
        moveIntent.putExtra(CopyService.EXTRA_TRANSFER_MODE, CopyService.TRANSFER_MODE_MOVE);
@@ -142,9 +165,12 @@ public class CopyServiceTest extends ServiceTestCase<CopyService> {
                "/test2.txt"
        };
        List<Uri> testFiles = Lists.newArrayList(
                mStorage.createFile(SRC_ROOT, srcPaths[0], "text/plain", testContent[0].getBytes()),
                mStorage.createFile(SRC_ROOT, srcPaths[1], "text/plain", testContent[1].getBytes()),
                mStorage.createFile(SRC_ROOT, srcPaths[2], "text/plain", testContent[2].getBytes()));
                mStorage.createRegularFile(SRC_ROOT, srcPaths[0], "text/plain",
                        testContent[0].getBytes()),
                mStorage.createRegularFile(SRC_ROOT, srcPaths[1], "text/plain",
                        testContent[1].getBytes()),
                mStorage.createRegularFile(SRC_ROOT, srcPaths[2], "text/plain",
                        testContent[2].getBytes()));

        // Copy all the test files.
        startService(createCopyIntent(testFiles));
@@ -195,7 +221,6 @@ public class CopyServiceTest extends ServiceTestCase<CopyService> {

        Intent intent = createCopyIntent(Lists.newArrayList(testDir), descDir);
        startService(intent);

        getService().addFinishedListener(mListener);

        mListener.waitForFinished();
@@ -240,9 +265,9 @@ public class CopyServiceTest extends ServiceTestCase<CopyService> {
        };
        // Create test dir; put some files in it.
        Uri testDir = createTestDirectory(srcDir);
        mStorage.createFile(SRC_ROOT, srcFiles[0], "text/plain", testContent[0].getBytes());
        mStorage.createFile(SRC_ROOT, srcFiles[1], "text/plain", testContent[1].getBytes());
        mStorage.createFile(SRC_ROOT, srcFiles[2], "text/plain", testContent[2].getBytes());
        mStorage.createRegularFile(SRC_ROOT, srcFiles[0], "text/plain", testContent[0].getBytes());
        mStorage.createRegularFile(SRC_ROOT, srcFiles[1], "text/plain", testContent[1].getBytes());
        mStorage.createRegularFile(SRC_ROOT, srcFiles[2], "text/plain", testContent[2].getBytes());

        Intent moveIntent = createCopyIntent(Lists.newArrayList(testDir));
        moveIntent.putExtra(CopyService.EXTRA_TRANSFER_MODE, CopyService.TRANSFER_MODE_MOVE);
@@ -270,7 +295,7 @@ public class CopyServiceTest extends ServiceTestCase<CopyService> {

    public void testCopyFileWithReadErrors() throws Exception {
        String srcPath = "/test0.txt";
        Uri testFile = mStorage.createFile(SRC_ROOT, srcPath, "text/plain",
        Uri testFile = mStorage.createRegularFile(SRC_ROOT, srcPath, "text/plain",
                "The five boxing wizards jump quickly".getBytes());

        mStorage.simulateReadErrorsForFile(testFile);
@@ -284,9 +309,26 @@ public class CopyServiceTest extends ServiceTestCase<CopyService> {
        assertDestFileCount(0);
    }

    public void testCopyVirtualNonTypedFile() throws Exception {
        String srcPath = "/non-typed.sth";
        // Empty stream types causes the FLAG_SUPPORTS_TYPED_DOCUMENT to be not set.
        ArrayList<String> streamTypes = new ArrayList<>();
        Uri testFile = mStorage.createVirtualFile(SRC_ROOT, srcPath, "virtual/mime-type",
                streamTypes, "I love Tokyo!".getBytes());

        Intent intent = createCopyIntent(Lists.newArrayList(testFile));
        startService(intent);
        getService().addFinishedListener(mListener);

        mListener.waitForFinished();
        mListener.assertFailedCount(1);
        mListener.assertFileFailed("non-typed.sth");
        assertDestFileCount(0);
    }

    public void testMoveFileWithReadErrors() throws Exception {
        String srcPath = "/test0.txt";
        Uri testFile = mStorage.createFile(SRC_ROOT, srcPath, "text/plain",
        Uri testFile = mStorage.createRegularFile(SRC_ROOT, srcPath, "text/plain",
                "The five boxing wizards jump quickly".getBytes());

        mStorage.simulateReadErrorsForFile(testFile);
@@ -326,10 +368,10 @@ public class CopyServiceTest extends ServiceTestCase<CopyService> {
        };
        // Create test dir; put some files in it.
        Uri testDir = createTestDirectory(srcDir);
        mStorage.createFile(SRC_ROOT, srcFiles[0], "text/plain", testContent[0].getBytes());
        mStorage.createRegularFile(SRC_ROOT, srcFiles[0], "text/plain", testContent[0].getBytes());
        Uri errFile = mStorage
                .createFile(SRC_ROOT, srcFiles[1], "text/plain", testContent[1].getBytes());
        mStorage.createFile(SRC_ROOT, srcFiles[2], "text/plain", testContent[2].getBytes());
                .createRegularFile(SRC_ROOT, srcFiles[1], "text/plain", testContent[1].getBytes());
        mStorage.createRegularFile(SRC_ROOT, srcFiles[2], "text/plain", testContent[2].getBytes());

        mStorage.simulateReadErrorsForFile(errFile);

@@ -363,7 +405,7 @@ public class CopyServiceTest extends ServiceTestCase<CopyService> {
    }

    private Uri createTestDirectory(String dir) throws IOException {
        return mStorage.createFile(
        return mStorage.createRegularFile(
                SRC_ROOT, dir, DocumentsContract.Document.MIME_TYPE_DIR, null);
    }

@@ -473,6 +515,7 @@ public class CopyServiceTest extends ServiceTestCase<CopyService> {

        final CountDownLatch latch = new CountDownLatch(1);
        final List<DocumentInfo> failedDocs = new ArrayList<>();

        @Override
        public void onFinished(List<DocumentInfo> failed) {
            failedDocs.addAll(failed);
+50 −17
Original line number Diff line number Diff line
@@ -324,11 +324,11 @@ public class StubProvider extends DocumentsProvider {
        }
        for (final String mimeType : document.streamTypes) {
            // Strict compare won't accept wildcards, but that's OK for tests, as DocumentsUI
            // doesn't use them for openTypedDocument.
            // doesn't use them for getStreamTypes nor openTypedDocument.
            if (mimeType.equals(mimeTypeFilter)) {
                ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
                            document.file, ParcelFileDescriptor.MODE_READ_ONLY);
                if (!documentId.equals(mSimulateReadErrors)) {
                if (documentId.equals(mSimulateReadErrors)) {
                    pfd = new ParcelFileDescriptor(pfd) {
                        @Override
                        public void checkError() throws IOException {
@@ -342,6 +342,23 @@ public class StubProvider extends DocumentsProvider {
        throw new IllegalArgumentException("Invalid MIME type filter for openTypedDocument().");
    }

    @Override
    public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
        final StubDocument document = mStorage.get(DocumentsContract.getDocumentId(uri));
        if (document == null) {
            throw new IllegalArgumentException(
                    "The provided Uri is incorrect, or the file is gone.");
        }
        if ((document.flags & Document.FLAG_SUPPORTS_TYPED_DOCUMENT) == 0) {
            return null;
        }
        if (!"*/*".equals(mimeTypeFilter)) {
            // Not used by DocumentsUI, so don't bother implementing it.
            throw new UnsupportedOperationException();
        }
        return document.streamTypes.toArray(new String[document.streamTypes.size()]);
    }

    private ParcelFileDescriptor startWrite(final StubDocument document)
            throws FileNotFoundException {
        ParcelFileDescriptor[] pipe;
@@ -476,23 +493,14 @@ public class StubProvider extends DocumentsProvider {
    }

    @VisibleForTesting
    public Uri createFile(String rootId, String path, String mimeType, byte[] content)
    public File createFile(String rootId, String path, String mimeType, byte[] content)
            throws FileNotFoundException, IOException {
        Log.d(TAG, "Creating test file " + rootId + ":" + path);
        StubDocument root = mRoots.get(rootId).document;
        if (root == null) {
            throw new FileNotFoundException("No roots with the ID " + rootId + " were found");
        }
        File file = new File(root.file, path.substring(1));
        StubDocument parent = mStorage.get(getDocumentIdForFile(file.getParentFile()));
        if (parent == null) {
            parent = mStorage.get(createFile(rootId, file.getParentFile().getPath(),
                    DocumentsContract.Document.MIME_TYPE_DIR, null));
            Log.d(TAG, "Created parent " + parent.documentId);
        } else {
            Log.d(TAG, "Found parent " + parent.documentId);
        }

        final File file = new File(root.file, path.substring(1));
        if (DocumentsContract.Document.MIME_TYPE_DIR.equals(mimeType)) {
            if (!file.mkdirs()) {
                throw new FileNotFoundException("Couldn't create directory " + file.getPath());
@@ -501,16 +509,41 @@ public class StubProvider extends DocumentsProvider {
            if (!file.createNewFile()) {
                throw new FileNotFoundException("Couldn't create file " + file.getPath());
            }
            // Add content to the file.
            FileOutputStream fout = new FileOutputStream(file);
            try (final FileOutputStream fout = new FileOutputStream(file)) {
                fout.write(content);
            fout.close();
            }
        }
        return file;
    }

    @VisibleForTesting
    public Uri createRegularFile(String rootId, String path, String mimeType, byte[] content)
            throws FileNotFoundException, IOException {
        final File file = createFile(rootId, path, mimeType, content);
        final StubDocument parent = mStorage.get(getDocumentIdForFile(file.getParentFile()));
        if (parent == null) {
            throw new FileNotFoundException("Parent not found.");
        }
        final StubDocument document = StubDocument.createRegularDocument(file, mimeType, parent);
        mStorage.put(document.documentId, document);
        return DocumentsContract.buildDocumentUri(mAuthority,  document.documentId);
    }

    @VisibleForTesting
    public Uri createVirtualFile(
            String rootId, String path, String mimeType, List<String> streamTypes, byte[] content)
            throws FileNotFoundException, IOException {
        final File file = createFile(rootId, path, mimeType, content);
        final StubDocument parent = mStorage.get(getDocumentIdForFile(file.getParentFile()));
        if (parent == null) {
            throw new FileNotFoundException("Parent not found.");
        }
        final StubDocument document = StubDocument.createVirtualDocument(
                file, mimeType, streamTypes, parent);
        mStorage.put(document.documentId, document);
        return DocumentsContract.buildDocumentUri(mAuthority,  document.documentId);
    }

    @VisibleForTesting
    public File getFile(String rootId, String path) throws FileNotFoundException {
        StubDocument root = mRoots.get(rootId).document;