[go: nahoru, domu]

15fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey/*
25fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Copyright (C) 2014 The Android Open Source Project
35fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey *
45fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
55fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * you may not use this file except in compliance with the License.
65fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * You may obtain a copy of the License at
75fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey *
85fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
95fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey *
105fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
115fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
125fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * See the License for the specific language governing permissions and
145fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * limitations under the License.
155fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */
165fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
175fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeypackage android.support.v4.provider;
185fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
195fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.content.ContentResolver;
205fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.content.UriPermission;
215fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.net.Uri;
225fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.os.Environment;
235fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.os.SystemClock;
245fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.test.AndroidTestCase;
25120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viveretteimport android.util.Log;
265fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
275fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.DataInputStream;
285fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.DataOutputStream;
295fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.File;
305fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.FileInputStream;
315fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.FileOutputStream;
325fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.IOException;
335fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.util.List;
345fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
355fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey/**
365fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Tests for {@link DocumentFile}
375fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */
385fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeypublic class DocumentFileTest extends AndroidTestCase {
395fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
405fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private Uri treeUri;
415fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
425fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private File root;
435fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private File rootFoo;
445fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private File rootMeow;
455fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private File rootMeowCat;
465fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private File rootMeowDog;
475fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private File rootMeowBar;
485fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
495fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private static final String FOO = "foo.randomext";
505fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private static final String MEOW = "meow";
515fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private static final String CAT = "cat.jpg";
525fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private static final String DOG = "DOG.PDF";
535fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private static final String BAR = "bar.png";
545fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
555fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    @Override
565fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    protected void setUp() throws Exception {
575fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        super.setUp();
585fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
595fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        final ContentResolver resolver = getContext().getContentResolver();
605fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        final List<UriPermission> perms = resolver.getPersistedUriPermissions();
615fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
625fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        if (perms.isEmpty()) {
635fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            throw new RuntimeException(
645fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                    "Failed to find outstanding grant; did you run the activity first?");
655fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        } else {
665fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            treeUri = perms.get(0).getUri();
675fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        }
685fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
695fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        root = Environment.getExternalStorageDirectory();
705fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        rootFoo = new File(root, FOO);
715fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        rootMeow = new File(root, MEOW);
725fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        rootMeowCat = new File(rootMeow, CAT);
735fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        rootMeowDog = new File(rootMeow, DOG);
745fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        rootMeowBar = new File(rootMeow, BAR);
755fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
765fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        resetRoot();
775fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    }
785fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
795fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private void resetRoot() throws Exception {
805fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        final File tmp = new File(root, "bark.pdf");
81120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette        deleteContents(tmp);
825fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        tmp.delete();
835fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
84120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette        deleteContents(rootMeow);
855fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        rootMeow.mkdir();
865fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        rootMeowBar.mkdir();
875fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
885fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        writeInt(rootFoo, 12);
895fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        writeInt(rootMeowCat, 24);
905fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        writeInt(rootMeowDog, 48);
915fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    }
925fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
93120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette    public static boolean deleteContents(File dir) {
94120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette        File[] files = dir.listFiles();
95120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette        boolean success = true;
96120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette        if (files != null) {
97120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette            for (File file : files) {
98120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette                if (file.isDirectory()) {
99120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette                    success &= deleteContents(file);
100120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette                }
101120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette                if (!file.delete()) {
102120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette                    success = false;
103120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette                }
104120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette            }
105120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette        }
106120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette        return success;
107120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette    }
108120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette
1095fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private interface DocumentTest {
1105fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        public void exec(DocumentFile doc) throws Exception;
1115fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    }
1125fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1135fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    public void testSimple() throws Exception {
1145fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        final DocumentTest test = new DocumentTest() {
1155fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            @Override
1165fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            public void exec(DocumentFile doc) throws Exception {
1175fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                resetRoot();
1185fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue("isDirectory", doc.isDirectory());
1195fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertFalse("isFile", doc.isFile());
1205fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue("canRead", doc.canRead());
1215fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue("canWrite", doc.canWrite());
1225fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue("exists", doc.exists());
1235fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            }
1245fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        };
1255fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1265fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        test.exec(DocumentFile.fromFile(root));
1275fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        test.exec(DocumentFile.fromTreeUri(getContext(), treeUri));
1285fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    }
1295fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1305fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    public void testTraverse() throws Exception {
1315fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        final DocumentTest test = new DocumentTest() {
1325fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            @Override
1335fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            public void exec(DocumentFile doc) throws Exception {
1345fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                resetRoot();
1355fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1365fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Root needs to at least contain our test file and dir
1375fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile foo = doc.findFile(FOO);
1385fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile meow = doc.findFile(MEOW);
1395fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue("isFile", foo.isFile());
1405fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue("isDirectory", meow.isDirectory());
1415fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1425fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Traverse inside, and expect to find exact number of items
1435fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                DocumentFile[] docs = meow.listFiles();
1445fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("length", 3, docs.length);
1455fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1465fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile cat = meow.findFile(CAT);
1475fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile dog = meow.findFile(DOG);
1485fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile bar = meow.findFile(BAR);
1495fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue("isFile", cat.isFile());
1505fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue("isFile", dog.isFile());
1515fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue("isDirectory", bar.isDirectory());
1525fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1535fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Empty directory is empty
1545fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("length", 0, bar.listFiles().length);
1555fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            }
1565fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        };
1575fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1585fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        test.exec(DocumentFile.fromFile(root));
1595fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        test.exec(DocumentFile.fromTreeUri(getContext(), treeUri));
1605fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    }
1615fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1625fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    public void testReadAndWrite() throws Exception {
1635fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        final DocumentTest test = new DocumentTest() {
1645fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            @Override
1655fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            public void exec(DocumentFile doc) throws Exception {
1665fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                resetRoot();
1675fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1685fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile foo = doc.findFile(FOO);
1695fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("file", 12, readInt(rootFoo));
1705fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("uri", 12, readInt(foo.getUri()));
1715fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1725fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Underlying storage may not have sub-second resolution, so
1735fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // wait a few seconds.
1745fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                SystemClock.sleep(2000);
1755fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1765fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Ensure provider write makes its way to disk
1775fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final long beforeTime = foo.lastModified();
1785fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                writeInt(foo.getUri(), 13);
1795fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final long afterTime = foo.lastModified();
1805fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1815fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("file", 13, readInt(rootFoo));
1825fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("uri", 13, readInt(foo.getUri()));
1835fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1845fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Make sure we kicked time forward
1855fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue("lastModified", afterTime > beforeTime);
1865fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            }
1875fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        };
1885fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1895fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        test.exec(DocumentFile.fromFile(root));
1905fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        test.exec(DocumentFile.fromTreeUri(getContext(), treeUri));
1915fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    }
1925fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1935fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    public void testMimes() throws Exception {
1945fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        final DocumentTest test = new DocumentTest() {
1955fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            @Override
1965fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            public void exec(DocumentFile doc) throws Exception {
1975fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                resetRoot();
1985fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
1995fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile foo = doc.findFile(FOO);
2005fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile meow = doc.findFile(MEOW);
2015fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile cat = meow.findFile(CAT);
2025fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile dog = meow.findFile(DOG);
2035fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile bar = meow.findFile(BAR);
2045fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2055fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals(null, doc.getType());
2065fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("application/octet-stream", foo.getType());
2075fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals(null, meow.getType());
2085fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("image/jpeg", cat.getType());
2095fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("application/pdf", dog.getType());
2105fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals(null, bar.getType());
2115fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            }
2125fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        };
2135fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2145fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        test.exec(DocumentFile.fromFile(root));
2155fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        test.exec(DocumentFile.fromTreeUri(getContext(), treeUri));
2165fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    }
2175fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2185fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    public void testCreate() throws Exception {
2195fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        final DocumentTest test = new DocumentTest() {
2205fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            @Override
2215fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            public void exec(DocumentFile doc) throws Exception {
2225fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                resetRoot();
2235fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2245fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile meow = doc.findFile(MEOW);
2255fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("length", 3, meow.listFiles().length);
2265fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2275fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Create file with MIME
2285fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile newFile = meow.createFile("text/plain", "My New File");
2295fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("My New File.txt", newFile.getName());
2305fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("text/plain", newFile.getType());
2315fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue("isFile", newFile.isFile());
2325fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertFalse("isDirectory", newFile.isDirectory());
2335fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2345fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("length", 0, newFile.length());
2355fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                writeInt(newFile.getUri(), 0);
2365fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("length", 4, newFile.length());
2375fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2385fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Create raw file
2395fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile newRaw = meow.createFile("application/octet-stream",
2405fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                        "myrawfile");
2415fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("myrawfile", newRaw.getName());
2425fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("application/octet-stream", newRaw.getType());
2435fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue("isFile", newRaw.isFile());
2445fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertFalse("isDirectory", newRaw.isDirectory());
2455fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2465fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Create directory
2475fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile newDir = meow.createDirectory("My New Directory.png");
2485fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("My New Directory.png", newDir.getName());
2495fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertFalse("isFile", newDir.isFile());
2505fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue("isDirectory", newDir.isDirectory());
2515fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("length", 0, newDir.listFiles().length);
2525fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2535fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // And overall dir grew
2545fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("length", 6, meow.listFiles().length);
2555fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            }
2565fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        };
2575fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2585fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        test.exec(DocumentFile.fromFile(root));
2595fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        test.exec(DocumentFile.fromTreeUri(getContext(), treeUri));
2605fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    }
2615fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2625fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    public void testDelete() throws Exception {
2635fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        final DocumentTest test = new DocumentTest() {
2645fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            @Override
2655fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            public void exec(DocumentFile doc) throws Exception {
2665fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                resetRoot();
2675fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2685fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile meow = doc.findFile(MEOW);
2695fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile cat = meow.findFile(CAT);
2705fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                final DocumentFile dog = meow.findFile(DOG);
2715fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2725fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Delete single file
2735fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue(cat.delete());
2745fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertNull("cat", meow.findFile(CAT));
2755fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2765fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Other file still exists
2775fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue("exists", dog.exists());
2785fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2795fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Delete entire tree
2805fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue(meow.delete());
2815fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertNull("meow", doc.findFile(MEOW));
2825fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2835fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Nuking tree deleted other file
2845fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertFalse("exists", dog.exists());
2855fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            }
2865fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        };
2875fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2885fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        test.exec(DocumentFile.fromFile(root));
2895fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        test.exec(DocumentFile.fromTreeUri(getContext(), treeUri));
2905fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    }
2915fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2925fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    public void testRename() throws Exception {
2935fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        final DocumentTest test = new DocumentTest() {
2945fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            @Override
2955fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            public void exec(DocumentFile doc) throws Exception {
2965fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                resetRoot();
2975fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
2985fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                DocumentFile meow = doc.findFile(MEOW);
2995fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                DocumentFile cat = meow.findFile(CAT);
3005fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                DocumentFile dog = meow.findFile(DOG);
3015fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue(dog.exists());
3025fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
3035fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Rename a file
3045fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("cat.jpg", cat.getName());
3055fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("image/jpeg", cat.getType());
3065fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
3075fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue(cat.renameTo("music.aAc"));
3085fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("music.aAc", cat.getName());
3095fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("audio/aac", cat.getType());
3105fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
3115fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Rename a directory
3125fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("meow", meow.getName());
3135fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals(null, meow.getType());
3145fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue(meow.isDirectory());
3155fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals(3, meow.listFiles().length);
3165fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
3175fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue(meow.renameTo("bark.pdf"));
3185fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals("bark.pdf", meow.getName());
3195fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals(null, meow.getType());
3205fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue(meow.isDirectory());
3215fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertEquals(3, meow.listFiles().length);
3225fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
3235fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // Current implementation of ExternalStorageProvider invalidates
3245fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // all children documents when directory is renamed.
3255fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertFalse(dog.exists());
3265fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
3275fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                // But we can find it again
3285fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                dog = meow.findFile(DOG);
3295fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                assertTrue(dog.exists());
3305fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            }
3315fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        };
3325fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
3335fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        test.exec(DocumentFile.fromFile(root));
3345fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        test.exec(DocumentFile.fromTreeUri(getContext(), treeUri));
3355fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    }
3365fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
3375fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private void writeInt(Uri uri, int value) throws IOException {
3385fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        final DataOutputStream os = new DataOutputStream(
3395fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                getContext().getContentResolver().openOutputStream(uri));
3405fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        try {
3415fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            os.writeInt(value);
3425fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        } finally {
3435fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            os.close();
3445fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        }
3455fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    }
3465fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
3475fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private static void writeInt(File file, int value) throws IOException {
3485fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        final DataOutputStream os = new DataOutputStream(new FileOutputStream(file));
3495fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        try {
3505fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            os.writeInt(value);
3515fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        } finally {
3525fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            os.close();
3535fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        }
3545fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    }
3555fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
3565fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private int readInt(Uri uri) throws IOException {
3575fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        final DataInputStream is = new DataInputStream(
3585fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey                getContext().getContentResolver().openInputStream(uri));
3595fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        try {
3605fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            return is.readInt();
3615fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        } finally {
3625fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            is.close();
3635fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        }
3645fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    }
3655fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey
3665fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    private static int readInt(File file) throws IOException {
3675fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        final DataInputStream is = new DataInputStream(new FileInputStream(file));
3685fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        try {
3695fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            return is.readInt();
3705fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        } finally {
3715fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey            is.close();
3725fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey        }
3735fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey    }
3745fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey}
375