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

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

Merge "Add support to virtual and typed files in StubProvider."

parents c2d26a08 cca31ebb
Loading
Loading
Loading
Loading
+103 −36
Original line number Diff line number Diff line
@@ -44,9 +44,11 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class StubProvider extends DocumentsProvider {
@@ -105,7 +107,13 @@ public class StubProvider extends DocumentsProvider {

        mRoots.clear();
        for (String rootId : rootIds) {
            final RootInfo rootInfo = new RootInfo(rootId, getSize(rootId));
            // Make a subdir in the cache dir for each root.
            final File file = new File(getContext().getCacheDir(), rootId);
            if (file.mkdir()) {
                Log.i(TAG, "Created new root directory @ " + file.getPath());
            }
            final RootInfo rootInfo = new RootInfo(file, getSize(rootId));
            mStorage.put(rootInfo.document.documentId, rootInfo.document);
            mRoots.put(rootId, rootInfo);
        }
    }
@@ -188,7 +196,7 @@ public class StubProvider extends DocumentsProvider {
                created = file.createNewFile();
            } catch (IOException e) {
                // We'll throw an FNF exception later :)
                Log.e(TAG, "createnewFile operation failed for file: " + file, e);
                Log.e(TAG, "createNewFile operation failed for file: " + file, e);
            }
            if (!created) {
                throw new FileNotFoundException(
@@ -197,7 +205,8 @@ public class StubProvider extends DocumentsProvider {
            Log.i(TAG, "Created new file: " + file);
        }

        final StubDocument document = new StubDocument(file, mimeType, parent);
        final StubDocument document = StubDocument.createRegularDocument(file, mimeType, parent);
        mStorage.put(document.documentId, document);
        Log.d(TAG, "Created document " + document.documentId);
        notifyParentChanged(document.parentId);
        getContext().getContentResolver().notifyChange(
@@ -264,14 +273,18 @@ public class StubProvider extends DocumentsProvider {
    public ParcelFileDescriptor openDocument(String docId, String mode, CancellationSignal signal)
            throws FileNotFoundException {
        final StubDocument document = mStorage.get(docId);
        if (document == null || !document.file.isFile())
        if (document == null || !document.file.isFile()) {
            throw new FileNotFoundException();
        }
        if ((document.flags & Document.FLAG_VIRTUAL_DOCUMENT) != 0) {
            throw new IllegalStateException("Tried to open a virtual file.");
        }

        if ("r".equals(mode)) {
            ParcelFileDescriptor pfd = ParcelFileDescriptor.open(document.file,
            final ParcelFileDescriptor pfd = ParcelFileDescriptor.open(document.file,
                        ParcelFileDescriptor.MODE_READ_ONLY);
            if (docId.equals(mSimulateReadErrors)) {
                pfd = new ParcelFileDescriptor(pfd) {
                return new ParcelFileDescriptor(pfd) {
                    @Override
                    public void checkError() throws IOException {
                        throw new IOException("Test error");
@@ -298,6 +311,37 @@ public class StubProvider extends DocumentsProvider {
        throw new FileNotFoundException();
    }

    @Override
    public AssetFileDescriptor openTypedDocument(
            String documentId, String mimeTypeFilter, Bundle opts, CancellationSignal signal)
            throws FileNotFoundException {
        final StubDocument document = mStorage.get(documentId);
        if (document == null || !document.file.isFile()) {
            throw new FileNotFoundException();
        }
        if ((document.flags & Document.FLAG_SUPPORTS_TYPED_DOCUMENT) == 0) {
            throw new IllegalStateException("Tried to open a non-typed document as typed.");
        }
        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.
            if (mimeType.equals(mimeTypeFilter)) {
                ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
                            document.file, ParcelFileDescriptor.MODE_READ_ONLY);
                if (!documentId.equals(mSimulateReadErrors)) {
                    pfd = new ParcelFileDescriptor(pfd) {
                        @Override
                        public void checkError() throws IOException {
                            throw new IOException("Test error");
                        }
                    };
                }
                return new AssetFileDescriptor(pfd, 0, document.file.length());
            }
        }
        throw new IllegalArgumentException("Invalid MIME type filter for openTypedDocument().");
    }

    private ParcelFileDescriptor startWrite(final StubDocument document)
            throws FileNotFoundException {
        ParcelFileDescriptor[] pipe;
@@ -398,14 +442,7 @@ public class StubProvider extends DocumentsProvider {
        row.add(Document.COLUMN_DISPLAY_NAME, document.file.getName());
        row.add(Document.COLUMN_SIZE, document.file.length());
        row.add(Document.COLUMN_MIME_TYPE, document.mimeType);
        int flags = Document.FLAG_SUPPORTS_DELETE;
        // TODO: Add support for renaming.
        if (document.file.isDirectory()) {
            flags |= Document.FLAG_DIR_SUPPORTS_CREATE;
        } else {
            flags |= Document.FLAG_SUPPORTS_WRITE;
        }
        row.add(Document.COLUMN_FLAGS, flags);
        row.add(Document.COLUMN_FLAGS, document.flags);
        row.add(Document.COLUMN_LAST_MODIFIED, document.file.lastModified());
    }

@@ -469,7 +506,8 @@ public class StubProvider extends DocumentsProvider {
            fout.write(content);
            fout.close();
        }
        final StubDocument document = new StubDocument(file, mimeType, parent);
        final StubDocument document = StubDocument.createRegularDocument(file, mimeType, parent);
        mStorage.put(document.documentId, document);
        return DocumentsContract.buildDocumentUri(mAuthority,  document.documentId);
    }

@@ -489,21 +527,16 @@ public class StubProvider extends DocumentsProvider {
        return found.file;
    }

    final class RootInfo {
    final static class RootInfo {
        public final String name;
        public final StubDocument document;
        public long capacity;
        public long size;

        RootInfo(String name, long capacity) {
            this.name = name;
        RootInfo(File file, long capacity) {
            this.name = file.getName();
            this.capacity = 1024 * 1024;
            // Make a subdir in the cache dir for each root.
            File file = new File(getContext().getCacheDir(), name);
            if (file.mkdir()) {
                Log.i(TAG, "Created new root directory @ " + file.getPath());
            }
            this.document = new StubDocument(file, Document.MIME_TYPE_DIR, this);
            this.document = StubDocument.createRootDocument(file, this);
            this.capacity = capacity;
            this.size = 0;
        }
@@ -513,38 +546,72 @@ public class StubProvider extends DocumentsProvider {
        }
    }

    final class StubDocument {
    final static class StubDocument {
        public final File file;
        public final String mimeType;
        public final String documentId;
        public final String mimeType;
        public final List<String> streamTypes;
        public final int flags;
        public final String parentId;
        public final RootInfo rootInfo;

        StubDocument(File file, String mimeType, StubDocument parent) {
        private StubDocument(
                 File file, String mimeType, List<String> streamTypes, int flags,
                 StubDocument parent) {
            this.file = file;
            this.mimeType = mimeType;
            this.documentId = getDocumentIdForFile(file);
            this.mimeType = mimeType;
            this.streamTypes = streamTypes;
            this.flags = flags;
            this.parentId = parent.documentId;
            this.rootInfo = parent.rootInfo;
            mStorage.put(this.documentId, this);
        }

        StubDocument(File file, String mimeType, RootInfo rootInfo) {
        private StubDocument(File file, RootInfo rootInfo) {
            this.file = file;
            this.mimeType = mimeType;
            this.documentId = getDocumentIdForFile(file);
            this.mimeType = Document.MIME_TYPE_DIR;
            this.streamTypes = new ArrayList<String>();
            this.flags = Document.FLAG_DIR_SUPPORTS_CREATE;
            this.parentId = null;
            this.rootInfo = rootInfo;
            mStorage.put(this.documentId, this);
        }

        public static StubDocument createRootDocument(File file, RootInfo rootInfo) {
            return new StubDocument(file, rootInfo);
        }

        public static StubDocument createRegularDocument(
                File file, String mimeType, StubDocument parent) {
            int flags = Document.FLAG_SUPPORTS_DELETE;
            if (file.isDirectory()) {
                flags |= Document.FLAG_DIR_SUPPORTS_CREATE;
            } else {
                flags |= Document.FLAG_SUPPORTS_WRITE;
            }
            return new StubDocument(file, mimeType, new ArrayList<String>(), flags, parent);
        }

        public static StubDocument createVirtualDocument(
                File file, String mimeType, List<String> streamTypes, StubDocument parent) {
            int flags = Document.FLAG_SUPPORTS_DELETE | Document.FLAG_SUPPORTS_WRITE
                    | Document.FLAG_VIRTUAL_DOCUMENT;
            if (streamTypes.size() > 0) {
                flags |= Document.FLAG_SUPPORTS_TYPED_DOCUMENT;
            }
            return new StubDocument(file, mimeType, streamTypes, flags, parent);
        }

        @Override
        public String toString() {
            return "StubDocument{"
                    + "path:" + file.getPath()
                    + ", mimeType:" + mimeType
                    + ", rootInfo:" + rootInfo
                    + ", documentId:" + documentId
                    + ", mimeType:" + mimeType
                    + ", streamTypes:" + streamTypes.toString()
                    + ", flags:" + flags
                    + ", parentId:" + parentId
                    + ", rootInfo:" + rootInfo
                    + "}";
        }
    }