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; 24754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport android.support.test.filters.MediumTest; 255fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.test.AndroidTestCase; 260357e3dab075ba93be2af9338f42d9cdb1217016Aurimas Liutikasimport android.test.suitebuilder.annotation.Suppress; 275fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 285fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.DataInputStream; 295fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.DataOutputStream; 305fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.File; 315fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.FileInputStream; 325fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.FileOutputStream; 335fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.IOException; 345fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.util.List; 355fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 365fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey/** 375fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Tests for {@link DocumentFile} 380357e3dab075ba93be2af9338f42d9cdb1217016Aurimas Liutikas * 395fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 400357e3dab075ba93be2af9338f42d9cdb1217016Aurimas Liutikas// These tests fail so it is marked @Suppress. Fix is tracked in b/27168036 410357e3dab075ba93be2af9338f42d9cdb1217016Aurimas Liutikas@Suppress 420357e3dab075ba93be2af9338f42d9cdb1217016Aurimas Liutikas@MediumTest 435fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeypublic class DocumentFileTest extends AndroidTestCase { 445fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 455fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private Uri treeUri; 465fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 475fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private File root; 485fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private File rootFoo; 495fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private File rootMeow; 505fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private File rootMeowCat; 515fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private File rootMeowDog; 525fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private File rootMeowBar; 535fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 545fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private static final String FOO = "foo.randomext"; 555fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private static final String MEOW = "meow"; 565fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private static final String CAT = "cat.jpg"; 575fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private static final String DOG = "DOG.PDF"; 585fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private static final String BAR = "bar.png"; 595fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 605fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 615fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey protected void setUp() throws Exception { 625fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey super.setUp(); 635fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 645fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final ContentResolver resolver = getContext().getContentResolver(); 655fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final List<UriPermission> perms = resolver.getPersistedUriPermissions(); 665fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 675fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (perms.isEmpty()) { 685fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey throw new RuntimeException( 695fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey "Failed to find outstanding grant; did you run the activity first?"); 705fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } else { 715fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey treeUri = perms.get(0).getUri(); 725fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 735fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 745fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey root = Environment.getExternalStorageDirectory(); 755fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey rootFoo = new File(root, FOO); 765fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey rootMeow = new File(root, MEOW); 775fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey rootMeowCat = new File(rootMeow, CAT); 785fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey rootMeowDog = new File(rootMeow, DOG); 795fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey rootMeowBar = new File(rootMeow, BAR); 805fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 815fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey resetRoot(); 825fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 835fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 845fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private void resetRoot() throws Exception { 855fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final File tmp = new File(root, "bark.pdf"); 86120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette deleteContents(tmp); 875fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey tmp.delete(); 885fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 89120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette deleteContents(rootMeow); 905fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey rootMeow.mkdir(); 915fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey rootMeowBar.mkdir(); 925fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 935fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey writeInt(rootFoo, 12); 945fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey writeInt(rootMeowCat, 24); 955fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey writeInt(rootMeowDog, 48); 965fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 975fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 98120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette public static boolean deleteContents(File dir) { 99120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette File[] files = dir.listFiles(); 100120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette boolean success = true; 101120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette if (files != null) { 102120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette for (File file : files) { 103120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette if (file.isDirectory()) { 104120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette success &= deleteContents(file); 105120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette } 106120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette if (!file.delete()) { 107120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette success = false; 108120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette } 109120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette } 110120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette } 111120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette return success; 112120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette } 113120325c4bd854c49fa50b872bdd84a7fac58210cAlan Viverette 1145fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private interface DocumentTest { 1155fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void exec(DocumentFile doc) throws Exception; 1165fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1175fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1185fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void testSimple() throws Exception { 1195fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentTest test = new DocumentTest() { 1205fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 1215fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void exec(DocumentFile doc) throws Exception { 1225fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey resetRoot(); 1235fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue("isDirectory", doc.isDirectory()); 1245fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertFalse("isFile", doc.isFile()); 12526f311a9b57b9551ad58d6b7f9a571bebcebf0dcTomasz Mikolajewski assertFalse("isVirtual", doc.isVirtual()); 1265fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue("canRead", doc.canRead()); 1275fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue("canWrite", doc.canWrite()); 1285fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue("exists", doc.exists()); 1295fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1305fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey }; 1315fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1325fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey test.exec(DocumentFile.fromFile(root)); 1335fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey test.exec(DocumentFile.fromTreeUri(getContext(), treeUri)); 1345fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1355fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1365fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void testTraverse() throws Exception { 1375fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentTest test = new DocumentTest() { 1385fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 1395fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void exec(DocumentFile doc) throws Exception { 1405fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey resetRoot(); 1415fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1425fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Root needs to at least contain our test file and dir 1435fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile foo = doc.findFile(FOO); 1445fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile meow = doc.findFile(MEOW); 1455fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue("isFile", foo.isFile()); 1465fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue("isDirectory", meow.isDirectory()); 1475fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1485fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Traverse inside, and expect to find exact number of items 1495fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey DocumentFile[] docs = meow.listFiles(); 1505fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("length", 3, docs.length); 1515fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1525fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile cat = meow.findFile(CAT); 1535fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile dog = meow.findFile(DOG); 1545fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile bar = meow.findFile(BAR); 1555fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue("isFile", cat.isFile()); 1565fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue("isFile", dog.isFile()); 1575fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue("isDirectory", bar.isDirectory()); 1585fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1595fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Empty directory is empty 1605fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("length", 0, bar.listFiles().length); 1615fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1625fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey }; 1635fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1645fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey test.exec(DocumentFile.fromFile(root)); 1655fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey test.exec(DocumentFile.fromTreeUri(getContext(), treeUri)); 1665fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1675fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1685fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void testReadAndWrite() throws Exception { 1695fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentTest test = new DocumentTest() { 1705fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 1715fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void exec(DocumentFile doc) throws Exception { 1725fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey resetRoot(); 1735fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1745fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile foo = doc.findFile(FOO); 1755fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("file", 12, readInt(rootFoo)); 1765fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("uri", 12, readInt(foo.getUri())); 1775fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1785fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Underlying storage may not have sub-second resolution, so 1795fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // wait a few seconds. 1805fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey SystemClock.sleep(2000); 1815fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1825fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Ensure provider write makes its way to disk 1835fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final long beforeTime = foo.lastModified(); 1845fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey writeInt(foo.getUri(), 13); 1855fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final long afterTime = foo.lastModified(); 1865fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1875fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("file", 13, readInt(rootFoo)); 1885fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("uri", 13, readInt(foo.getUri())); 1895fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1905fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Make sure we kicked time forward 1915fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue("lastModified", afterTime > beforeTime); 1925fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1935fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey }; 1945fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1955fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey test.exec(DocumentFile.fromFile(root)); 1965fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey test.exec(DocumentFile.fromTreeUri(getContext(), treeUri)); 1975fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1985fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1995fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void testMimes() throws Exception { 2005fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentTest test = new DocumentTest() { 2015fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 2025fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void exec(DocumentFile doc) throws Exception { 2035fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey resetRoot(); 2045fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2055fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile foo = doc.findFile(FOO); 2065fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile meow = doc.findFile(MEOW); 2075fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile cat = meow.findFile(CAT); 2085fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile dog = meow.findFile(DOG); 2095fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile bar = meow.findFile(BAR); 2105fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2115fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals(null, doc.getType()); 2125fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("application/octet-stream", foo.getType()); 2135fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals(null, meow.getType()); 2145fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("image/jpeg", cat.getType()); 2155fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("application/pdf", dog.getType()); 2165fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals(null, bar.getType()); 2175fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 2185fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey }; 2195fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2205fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey test.exec(DocumentFile.fromFile(root)); 2215fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey test.exec(DocumentFile.fromTreeUri(getContext(), treeUri)); 2225fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 2235fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2245fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void testCreate() throws Exception { 2255fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentTest test = new DocumentTest() { 2265fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 2275fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void exec(DocumentFile doc) throws Exception { 2285fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey resetRoot(); 2295fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2305fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile meow = doc.findFile(MEOW); 2315fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("length", 3, meow.listFiles().length); 2325fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2335fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Create file with MIME 2345fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile newFile = meow.createFile("text/plain", "My New File"); 2355fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("My New File.txt", newFile.getName()); 2365fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("text/plain", newFile.getType()); 2375fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue("isFile", newFile.isFile()); 2385fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertFalse("isDirectory", newFile.isDirectory()); 2395fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2405fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("length", 0, newFile.length()); 2415fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey writeInt(newFile.getUri(), 0); 2425fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("length", 4, newFile.length()); 2435fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2445fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Create raw file 2455fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile newRaw = meow.createFile("application/octet-stream", 2465fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey "myrawfile"); 2475fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("myrawfile", newRaw.getName()); 2485fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("application/octet-stream", newRaw.getType()); 2495fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue("isFile", newRaw.isFile()); 2505fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertFalse("isDirectory", newRaw.isDirectory()); 2515fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2525fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Create directory 2535fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile newDir = meow.createDirectory("My New Directory.png"); 2545fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("My New Directory.png", newDir.getName()); 2555fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertFalse("isFile", newDir.isFile()); 2565fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue("isDirectory", newDir.isDirectory()); 2575fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("length", 0, newDir.listFiles().length); 2585fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2595fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // And overall dir grew 2605fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("length", 6, meow.listFiles().length); 2615fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 2625fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey }; 2635fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2645fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey test.exec(DocumentFile.fromFile(root)); 2655fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey test.exec(DocumentFile.fromTreeUri(getContext(), treeUri)); 2665fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 2675fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2685fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void testDelete() throws Exception { 2695fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentTest test = new DocumentTest() { 2705fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 2715fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void exec(DocumentFile doc) throws Exception { 2725fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey resetRoot(); 2735fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2745fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile meow = doc.findFile(MEOW); 2755fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile cat = meow.findFile(CAT); 2765fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentFile dog = meow.findFile(DOG); 2775fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2785fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Delete single file 2795fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue(cat.delete()); 2805fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertNull("cat", meow.findFile(CAT)); 2815fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2825fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Other file still exists 2835fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue("exists", dog.exists()); 2845fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2855fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Delete entire tree 2865fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue(meow.delete()); 2875fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertNull("meow", doc.findFile(MEOW)); 2885fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2895fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Nuking tree deleted other file 2905fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertFalse("exists", dog.exists()); 2915fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 2925fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey }; 2935fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2945fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey test.exec(DocumentFile.fromFile(root)); 2955fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey test.exec(DocumentFile.fromTreeUri(getContext(), treeUri)); 2965fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 2975fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2985fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void testRename() throws Exception { 2995fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DocumentTest test = new DocumentTest() { 3005fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey @Override 3015fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public void exec(DocumentFile doc) throws Exception { 3025fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey resetRoot(); 3035fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 3045fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey DocumentFile meow = doc.findFile(MEOW); 3055fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey DocumentFile cat = meow.findFile(CAT); 3065fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey DocumentFile dog = meow.findFile(DOG); 3075fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue(dog.exists()); 3085fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 3095fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Rename a file 3105fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("cat.jpg", cat.getName()); 3115fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("image/jpeg", cat.getType()); 3125fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 3135fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue(cat.renameTo("music.aAc")); 3145fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("music.aAc", cat.getName()); 3155fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("audio/aac", cat.getType()); 3165fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 3175fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Rename a directory 3185fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("meow", meow.getName()); 3195fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals(null, meow.getType()); 3205fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue(meow.isDirectory()); 3215fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals(3, meow.listFiles().length); 3225fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 3235fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue(meow.renameTo("bark.pdf")); 3245fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals("bark.pdf", meow.getName()); 3255fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals(null, meow.getType()); 3265fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue(meow.isDirectory()); 3275fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertEquals(3, meow.listFiles().length); 3285fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 3295fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // Current implementation of ExternalStorageProvider invalidates 3305fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // all children documents when directory is renamed. 3315fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertFalse(dog.exists()); 3325fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 3335fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey // But we can find it again 3345fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey dog = meow.findFile(DOG); 3355fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey assertTrue(dog.exists()); 3365fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 3375fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey }; 3385fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 3395fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey test.exec(DocumentFile.fromFile(root)); 3405fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey test.exec(DocumentFile.fromTreeUri(getContext(), treeUri)); 3415fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 3425fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 3435fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private void writeInt(Uri uri, int value) throws IOException { 3445fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DataOutputStream os = new DataOutputStream( 3455fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey getContext().getContentResolver().openOutputStream(uri)); 3465fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey try { 3475fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey os.writeInt(value); 3485fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } finally { 3495fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey os.close(); 3505fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 3515fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 3525fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 3535fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private static void writeInt(File file, int value) throws IOException { 3545fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DataOutputStream os = new DataOutputStream(new FileOutputStream(file)); 3555fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey try { 3565fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey os.writeInt(value); 3575fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } finally { 3585fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey os.close(); 3595fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 3605fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 3615fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 3625fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private int readInt(Uri uri) throws IOException { 3635fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DataInputStream is = new DataInputStream( 3645fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey getContext().getContentResolver().openInputStream(uri)); 3655fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey try { 3665fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return is.readInt(); 3675fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } finally { 3685fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey is.close(); 3695fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 3705fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 3715fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 3725fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private static int readInt(File file) throws IOException { 3735fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final DataInputStream is = new DataInputStream(new FileInputStream(file)); 3745fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey try { 3755fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return is.readInt(); 3765fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } finally { 3775fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey is.close(); 3785fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 3795fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 3805fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey} 381