Loading core/java/android/os/Environment.java +74 −0 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.text.TextUtils; import android.util.Log; import android.util.Log; import java.io.File; import java.io.File; import java.util.LinkedList; /** /** * Provides access to environment variables. * Provides access to environment variables. Loading Loading @@ -609,6 +610,79 @@ public class Environment { return false; return false; } } /** {@hide} */ public static final int HAS_MUSIC = 1 << 0; /** {@hide} */ public static final int HAS_PODCASTS = 1 << 1; /** {@hide} */ public static final int HAS_RINGTONES = 1 << 2; /** {@hide} */ public static final int HAS_ALARMS = 1 << 3; /** {@hide} */ public static final int HAS_NOTIFICATIONS = 1 << 4; /** {@hide} */ public static final int HAS_PICTURES = 1 << 5; /** {@hide} */ public static final int HAS_MOVIES = 1 << 6; /** {@hide} */ public static final int HAS_DOWNLOADS = 1 << 7; /** {@hide} */ public static final int HAS_DCIM = 1 << 8; /** {@hide} */ public static final int HAS_DOCUMENTS = 1 << 9; /** {@hide} */ public static final int HAS_ANDROID = 1 << 16; /** {@hide} */ public static final int HAS_OTHER = 1 << 17; /** * Classify the content types present on the given external storage device. * <p> * This is typically useful for deciding if an inserted SD card is empty, or * if it contains content like photos that should be preserved. * * @hide */ public static int classifyExternalStorageDirectory(File dir) { int res = 0; for (File f : FileUtils.listFilesOrEmpty(dir)) { if (f.isFile() && isInterestingFile(f)) { res |= HAS_OTHER; } else if (f.isDirectory() && hasInterestingFiles(f)) { final String name = f.getName(); if (DIRECTORY_MUSIC.equals(name)) res |= HAS_MUSIC; else if (DIRECTORY_PODCASTS.equals(name)) res |= HAS_PODCASTS; else if (DIRECTORY_RINGTONES.equals(name)) res |= HAS_RINGTONES; else if (DIRECTORY_ALARMS.equals(name)) res |= HAS_ALARMS; else if (DIRECTORY_NOTIFICATIONS.equals(name)) res |= HAS_NOTIFICATIONS; else if (DIRECTORY_PICTURES.equals(name)) res |= HAS_PICTURES; else if (DIRECTORY_MOVIES.equals(name)) res |= HAS_MOVIES; else if (DIRECTORY_DOWNLOADS.equals(name)) res |= HAS_DOWNLOADS; else if (DIRECTORY_DCIM.equals(name)) res |= HAS_DCIM; else if (DIRECTORY_DOCUMENTS.equals(name)) res |= HAS_DOCUMENTS; else if (DIRECTORY_ANDROID.equals(name)) res |= HAS_ANDROID; else res |= HAS_OTHER; } } return res; } private static boolean hasInterestingFiles(File dir) { final LinkedList<File> explore = new LinkedList<>(); explore.add(dir); while (!explore.isEmpty()) { dir = explore.pop(); for (File f : FileUtils.listFilesOrEmpty(dir)) { if (isInterestingFile(f)) return true; if (f.isDirectory()) explore.add(f); } } return false; } private static boolean isInterestingFile(File file) { if (file.isFile()) { final String name = file.getName().toLowerCase(); if (name.endsWith(".exe") || name.equals("autorun.inf") || name.equals("launchpad.zip") || name.equals(".nomedia")) { return false; } else { return true; } } else { return false; } } /** /** * Get a top-level shared/external storage directory for placing files of a * Get a top-level shared/external storage directory for placing files of a * particular type. This is where the user will typically place and manage * particular type. This is where the user will typically place and manage Loading core/tests/coretests/src/android/os/EnvironmentTest.java 0 → 100644 +103 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.os; import static android.os.Environment.HAS_ANDROID; import static android.os.Environment.HAS_DCIM; import static android.os.Environment.HAS_DOWNLOADS; import static android.os.Environment.HAS_OTHER; import static android.os.Environment.classifyExternalStorageDirectory; import static org.junit.Assert.assertEquals; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.io.File; @RunWith(AndroidJUnit4.class) public class EnvironmentTest { private File dir; private Context getContext() { return InstrumentationRegistry.getContext(); } @Before public void setUp() throws Exception { dir = getContext().getDir("testing", Context.MODE_PRIVATE); FileUtils.deleteContents(dir); } @After public void tearDown() throws Exception { FileUtils.deleteContents(dir); } @Test public void testClassify_empty() { assertEquals(0, classifyExternalStorageDirectory(dir)); } @Test public void testClassify_emptyDirs() { Environment.buildPath(dir, "DCIM").mkdirs(); Environment.buildPath(dir, "DCIM", "January").mkdirs(); Environment.buildPath(dir, "Downloads").mkdirs(); Environment.buildPath(dir, "LOST.DIR").mkdirs(); assertEquals(0, classifyExternalStorageDirectory(dir)); } @Test public void testClassify_emptyFactory() throws Exception { Environment.buildPath(dir, "autorun.inf").createNewFile(); Environment.buildPath(dir, "LaunchU3.exe").createNewFile(); Environment.buildPath(dir, "LaunchPad.zip").createNewFile(); assertEquals(0, classifyExternalStorageDirectory(dir)); } @Test public void testClassify_photos() throws Exception { Environment.buildPath(dir, "DCIM").mkdirs(); Environment.buildPath(dir, "DCIM", "IMG_1024.JPG").createNewFile(); Environment.buildPath(dir, "Download").mkdirs(); Environment.buildPath(dir, "Download", "foobar.pdf").createNewFile(); assertEquals(HAS_DCIM | HAS_DOWNLOADS, classifyExternalStorageDirectory(dir)); } @Test public void testClassify_other() throws Exception { Environment.buildPath(dir, "Android").mkdirs(); Environment.buildPath(dir, "Android", "com.example").mkdirs(); Environment.buildPath(dir, "Android", "com.example", "internal.dat").createNewFile(); Environment.buildPath(dir, "Linux").mkdirs(); Environment.buildPath(dir, "Linux", "install-amd64-minimal-20170907.iso").createNewFile(); assertEquals(HAS_ANDROID | HAS_OTHER, classifyExternalStorageDirectory(dir)); } @Test public void testClassify_otherRoot() throws Exception { Environment.buildPath(dir, "Taxes.pdf").createNewFile(); assertEquals(HAS_OTHER, classifyExternalStorageDirectory(dir)); } } core/tests/coretests/src/android/os/FileUtilsTest.java +40 −9 Original line number Original line Diff line number Diff line Loading @@ -21,15 +21,24 @@ import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.WEEK_IN_MILLIS; import static android.text.format.DateUtils.WEEK_IN_MILLIS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.content.Context; import android.content.Context; import android.provider.DocumentsContract.Document; import android.provider.DocumentsContract.Document; import android.test.AndroidTestCase; import android.support.test.InstrumentationRegistry; import android.test.suitebuilder.annotation.MediumTest; import android.support.test.runner.AndroidJUnit4; import libcore.io.IoUtils; import libcore.io.IoUtils; import com.google.android.collect.Sets; import com.google.android.collect.Sets; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.File; import java.io.FileOutputStream; import java.io.FileOutputStream; Loading @@ -37,8 +46,8 @@ import java.io.FileWriter; import java.util.Arrays; import java.util.Arrays; import java.util.HashSet; import java.util.HashSet; @MediumTest @RunWith(AndroidJUnit4.class) public class FileUtilsTest extends AndroidTestCase { public class FileUtilsTest { private static final String TEST_DATA = private static final String TEST_DATA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; Loading @@ -47,10 +56,12 @@ public class FileUtilsTest extends AndroidTestCase { private File mCopyFile; private File mCopyFile; private File mTarget; private File mTarget; private Context getContext() { return InstrumentationRegistry.getContext(); } @Override @Before protected void setUp() throws Exception { public void setUp() throws Exception { super.setUp(); mDir = getContext().getDir("testing", Context.MODE_PRIVATE); mDir = getContext().getDir("testing", Context.MODE_PRIVATE); mTestFile = new File(mDir, "test.file"); mTestFile = new File(mDir, "test.file"); mCopyFile = new File(mDir, "copy.file"); mCopyFile = new File(mDir, "copy.file"); Loading @@ -59,14 +70,15 @@ public class FileUtilsTest extends AndroidTestCase { FileUtils.deleteContents(mTarget); FileUtils.deleteContents(mTarget); } } @Override @After protected void tearDown() throws Exception { public void tearDown() throws Exception { IoUtils.deleteContents(mDir); IoUtils.deleteContents(mDir); FileUtils.deleteContents(mTarget); FileUtils.deleteContents(mTarget); } } // TODO: test setPermissions(), getPermissions() // TODO: test setPermissions(), getPermissions() @Test public void testCopyFile() throws Exception { public void testCopyFile() throws Exception { stageFile(mTestFile, TEST_DATA); stageFile(mTestFile, TEST_DATA); assertFalse(mCopyFile.exists()); assertFalse(mCopyFile.exists()); Loading @@ -75,6 +87,7 @@ public class FileUtilsTest extends AndroidTestCase { assertEquals(TEST_DATA, FileUtils.readTextFile(mCopyFile, 0, null)); assertEquals(TEST_DATA, FileUtils.readTextFile(mCopyFile, 0, null)); } } @Test public void testCopyToFile() throws Exception { public void testCopyToFile() throws Exception { final String s = "Foo Bar"; final String s = "Foo Bar"; assertFalse(mCopyFile.exists()); assertFalse(mCopyFile.exists()); Loading @@ -83,6 +96,7 @@ public class FileUtilsTest extends AndroidTestCase { assertEquals(s, FileUtils.readTextFile(mCopyFile, 0, null)); assertEquals(s, FileUtils.readTextFile(mCopyFile, 0, null)); } } @Test public void testIsFilenameSafe() throws Exception { public void testIsFilenameSafe() throws Exception { assertTrue(FileUtils.isFilenameSafe(new File("foobar"))); assertTrue(FileUtils.isFilenameSafe(new File("foobar"))); assertTrue(FileUtils.isFilenameSafe(new File("a_b-c=d.e/0,1+23"))); assertTrue(FileUtils.isFilenameSafe(new File("a_b-c=d.e/0,1+23"))); Loading @@ -90,6 +104,7 @@ public class FileUtilsTest extends AndroidTestCase { assertFalse(FileUtils.isFilenameSafe(new File("foo\nbar"))); assertFalse(FileUtils.isFilenameSafe(new File("foo\nbar"))); } } @Test public void testReadTextFile() throws Exception { public void testReadTextFile() throws Exception { stageFile(mTestFile, TEST_DATA); stageFile(mTestFile, TEST_DATA); Loading @@ -110,6 +125,7 @@ public class FileUtilsTest extends AndroidTestCase { assertEquals(TEST_DATA, FileUtils.readTextFile(mTestFile, -100, "<>")); assertEquals(TEST_DATA, FileUtils.readTextFile(mTestFile, -100, "<>")); } } @Test public void testReadTextFileWithZeroLengthFile() throws Exception { public void testReadTextFileWithZeroLengthFile() throws Exception { stageFile(mTestFile, TEST_DATA); stageFile(mTestFile, TEST_DATA); new FileOutputStream(mTestFile).close(); // Zero out the file new FileOutputStream(mTestFile).close(); // Zero out the file Loading @@ -120,6 +136,7 @@ public class FileUtilsTest extends AndroidTestCase { assertEquals("", FileUtils.readTextFile(mTestFile, -10, "<>")); assertEquals("", FileUtils.readTextFile(mTestFile, -10, "<>")); } } @Test public void testContains() throws Exception { public void testContains() throws Exception { assertTrue(FileUtils.contains(new File("/"), new File("/moo.txt"))); assertTrue(FileUtils.contains(new File("/"), new File("/moo.txt"))); assertTrue(FileUtils.contains(new File("/"), new File("/"))); assertTrue(FileUtils.contains(new File("/"), new File("/"))); Loading @@ -137,11 +154,13 @@ public class FileUtilsTest extends AndroidTestCase { assertFalse(FileUtils.contains(new File("/sdcard/"), new File("/sdcard.txt"))); assertFalse(FileUtils.contains(new File("/sdcard/"), new File("/sdcard.txt"))); } } @Test public void testDeleteOlderEmptyDir() throws Exception { public void testDeleteOlderEmptyDir() throws Exception { FileUtils.deleteOlderFiles(mDir, 10, WEEK_IN_MILLIS); FileUtils.deleteOlderFiles(mDir, 10, WEEK_IN_MILLIS); assertDirContents(); assertDirContents(); } } @Test public void testDeleteOlderTypical() throws Exception { public void testDeleteOlderTypical() throws Exception { touch("file1", HOUR_IN_MILLIS); touch("file1", HOUR_IN_MILLIS); touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); Loading @@ -152,6 +171,7 @@ public class FileUtilsTest extends AndroidTestCase { assertDirContents("file1", "file2", "file3"); assertDirContents("file1", "file2", "file3"); } } @Test public void testDeleteOlderInFuture() throws Exception { public void testDeleteOlderInFuture() throws Exception { touch("file1", -HOUR_IN_MILLIS); touch("file1", -HOUR_IN_MILLIS); touch("file2", HOUR_IN_MILLIS); touch("file2", HOUR_IN_MILLIS); Loading @@ -166,6 +186,7 @@ public class FileUtilsTest extends AndroidTestCase { assertDirContents("file1", "file2"); assertDirContents("file1", "file2"); } } @Test public void testDeleteOlderOnlyAge() throws Exception { public void testDeleteOlderOnlyAge() throws Exception { touch("file1", HOUR_IN_MILLIS); touch("file1", HOUR_IN_MILLIS); touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); Loading @@ -177,6 +198,7 @@ public class FileUtilsTest extends AndroidTestCase { assertDirContents("file1"); assertDirContents("file1"); } } @Test public void testDeleteOlderOnlyCount() throws Exception { public void testDeleteOlderOnlyCount() throws Exception { touch("file1", HOUR_IN_MILLIS); touch("file1", HOUR_IN_MILLIS); touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); Loading @@ -188,6 +210,7 @@ public class FileUtilsTest extends AndroidTestCase { assertDirContents("file1", "file2"); assertDirContents("file1", "file2"); } } @Test public void testValidExtFilename() throws Exception { public void testValidExtFilename() throws Exception { assertTrue(FileUtils.isValidExtFilename("a")); assertTrue(FileUtils.isValidExtFilename("a")); assertTrue(FileUtils.isValidExtFilename("foo.bar")); assertTrue(FileUtils.isValidExtFilename("foo.bar")); Loading @@ -208,6 +231,7 @@ public class FileUtilsTest extends AndroidTestCase { assertEquals("foo.bar", FileUtils.buildValidExtFilename("foo.bar")); assertEquals("foo.bar", FileUtils.buildValidExtFilename("foo.bar")); } } @Test public void testValidFatFilename() throws Exception { public void testValidFatFilename() throws Exception { assertTrue(FileUtils.isValidFatFilename("a")); assertTrue(FileUtils.isValidFatFilename("a")); assertTrue(FileUtils.isValidFatFilename("foo bar.baz")); assertTrue(FileUtils.isValidFatFilename("foo bar.baz")); Loading @@ -233,6 +257,7 @@ public class FileUtilsTest extends AndroidTestCase { assertEquals("foo_bar__baz", FileUtils.buildValidFatFilename("foo?bar**baz")); assertEquals("foo_bar__baz", FileUtils.buildValidFatFilename("foo?bar**baz")); } } @Test public void testTrimFilename() throws Exception { public void testTrimFilename() throws Exception { assertEquals("short.txt", FileUtils.trimFilename("short.txt", 16)); assertEquals("short.txt", FileUtils.trimFilename("short.txt", 16)); assertEquals("extrem...eme.txt", FileUtils.trimFilename("extremelylongfilename.txt", 16)); assertEquals("extrem...eme.txt", FileUtils.trimFilename("extremelylongfilename.txt", 16)); Loading @@ -245,6 +270,7 @@ public class FileUtilsTest extends AndroidTestCase { assertEquals("a...z", FileUtils.trimFilename(unicode, 6)); assertEquals("a...z", FileUtils.trimFilename(unicode, 6)); } } @Test public void testBuildUniqueFile_normal() throws Exception { public void testBuildUniqueFile_normal() throws Exception { assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test")); assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test")); assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg")); assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg")); Loading @@ -263,6 +289,7 @@ public class FileUtilsTest extends AndroidTestCase { FileUtils.buildUniqueFile(mTarget, "application/x-flac", "test.flac")); FileUtils.buildUniqueFile(mTarget, "application/x-flac", "test.flac")); } } @Test public void testBuildUniqueFile_unknown() throws Exception { public void testBuildUniqueFile_unknown() throws Exception { assertNameEquals("test", assertNameEquals("test", FileUtils.buildUniqueFile(mTarget, "application/octet-stream", "test")); FileUtils.buildUniqueFile(mTarget, "application/octet-stream", "test")); Loading @@ -275,6 +302,7 @@ public class FileUtilsTest extends AndroidTestCase { assertNameEquals("test.lolz", FileUtils.buildUniqueFile(mTarget, "lolz/lolz", "test.lolz")); assertNameEquals("test.lolz", FileUtils.buildUniqueFile(mTarget, "lolz/lolz", "test.lolz")); } } @Test public void testBuildUniqueFile_dir() throws Exception { public void testBuildUniqueFile_dir() throws Exception { assertNameEquals("test", FileUtils.buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test")); assertNameEquals("test", FileUtils.buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test")); new File(mTarget, "test").mkdir(); new File(mTarget, "test").mkdir(); Loading @@ -288,6 +316,7 @@ public class FileUtilsTest extends AndroidTestCase { FileUtils.buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test.jpg")); FileUtils.buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test.jpg")); } } @Test public void testBuildUniqueFile_increment() throws Exception { public void testBuildUniqueFile_increment() throws Exception { assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg")); assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg")); new File(mTarget, "test.jpg").createNewFile(); new File(mTarget, "test.jpg").createNewFile(); Loading @@ -298,6 +327,7 @@ public class FileUtilsTest extends AndroidTestCase { FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg")); FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg")); } } @Test public void testBuildUniqueFile_mimeless() throws Exception { public void testBuildUniqueFile_mimeless() throws Exception { assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "test.jpg")); assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "test.jpg")); new File(mTarget, "test.jpg").createNewFile(); new File(mTarget, "test.jpg").createNewFile(); Loading @@ -312,6 +342,7 @@ public class FileUtilsTest extends AndroidTestCase { assertNameEquals("test.foo (1).bar", FileUtils.buildUniqueFile(mTarget, "test.foo.bar")); assertNameEquals("test.foo (1).bar", FileUtils.buildUniqueFile(mTarget, "test.foo.bar")); } } @Test public void testRoundStorageSize() throws Exception { public void testRoundStorageSize() throws Exception { final long M128 = 128000000L; final long M128 = 128000000L; final long M256 = 256000000L; final long M256 = 256000000L; Loading Loading
core/java/android/os/Environment.java +74 −0 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.text.TextUtils; import android.util.Log; import android.util.Log; import java.io.File; import java.io.File; import java.util.LinkedList; /** /** * Provides access to environment variables. * Provides access to environment variables. Loading Loading @@ -609,6 +610,79 @@ public class Environment { return false; return false; } } /** {@hide} */ public static final int HAS_MUSIC = 1 << 0; /** {@hide} */ public static final int HAS_PODCASTS = 1 << 1; /** {@hide} */ public static final int HAS_RINGTONES = 1 << 2; /** {@hide} */ public static final int HAS_ALARMS = 1 << 3; /** {@hide} */ public static final int HAS_NOTIFICATIONS = 1 << 4; /** {@hide} */ public static final int HAS_PICTURES = 1 << 5; /** {@hide} */ public static final int HAS_MOVIES = 1 << 6; /** {@hide} */ public static final int HAS_DOWNLOADS = 1 << 7; /** {@hide} */ public static final int HAS_DCIM = 1 << 8; /** {@hide} */ public static final int HAS_DOCUMENTS = 1 << 9; /** {@hide} */ public static final int HAS_ANDROID = 1 << 16; /** {@hide} */ public static final int HAS_OTHER = 1 << 17; /** * Classify the content types present on the given external storage device. * <p> * This is typically useful for deciding if an inserted SD card is empty, or * if it contains content like photos that should be preserved. * * @hide */ public static int classifyExternalStorageDirectory(File dir) { int res = 0; for (File f : FileUtils.listFilesOrEmpty(dir)) { if (f.isFile() && isInterestingFile(f)) { res |= HAS_OTHER; } else if (f.isDirectory() && hasInterestingFiles(f)) { final String name = f.getName(); if (DIRECTORY_MUSIC.equals(name)) res |= HAS_MUSIC; else if (DIRECTORY_PODCASTS.equals(name)) res |= HAS_PODCASTS; else if (DIRECTORY_RINGTONES.equals(name)) res |= HAS_RINGTONES; else if (DIRECTORY_ALARMS.equals(name)) res |= HAS_ALARMS; else if (DIRECTORY_NOTIFICATIONS.equals(name)) res |= HAS_NOTIFICATIONS; else if (DIRECTORY_PICTURES.equals(name)) res |= HAS_PICTURES; else if (DIRECTORY_MOVIES.equals(name)) res |= HAS_MOVIES; else if (DIRECTORY_DOWNLOADS.equals(name)) res |= HAS_DOWNLOADS; else if (DIRECTORY_DCIM.equals(name)) res |= HAS_DCIM; else if (DIRECTORY_DOCUMENTS.equals(name)) res |= HAS_DOCUMENTS; else if (DIRECTORY_ANDROID.equals(name)) res |= HAS_ANDROID; else res |= HAS_OTHER; } } return res; } private static boolean hasInterestingFiles(File dir) { final LinkedList<File> explore = new LinkedList<>(); explore.add(dir); while (!explore.isEmpty()) { dir = explore.pop(); for (File f : FileUtils.listFilesOrEmpty(dir)) { if (isInterestingFile(f)) return true; if (f.isDirectory()) explore.add(f); } } return false; } private static boolean isInterestingFile(File file) { if (file.isFile()) { final String name = file.getName().toLowerCase(); if (name.endsWith(".exe") || name.equals("autorun.inf") || name.equals("launchpad.zip") || name.equals(".nomedia")) { return false; } else { return true; } } else { return false; } } /** /** * Get a top-level shared/external storage directory for placing files of a * Get a top-level shared/external storage directory for placing files of a * particular type. This is where the user will typically place and manage * particular type. This is where the user will typically place and manage Loading
core/tests/coretests/src/android/os/EnvironmentTest.java 0 → 100644 +103 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.os; import static android.os.Environment.HAS_ANDROID; import static android.os.Environment.HAS_DCIM; import static android.os.Environment.HAS_DOWNLOADS; import static android.os.Environment.HAS_OTHER; import static android.os.Environment.classifyExternalStorageDirectory; import static org.junit.Assert.assertEquals; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.io.File; @RunWith(AndroidJUnit4.class) public class EnvironmentTest { private File dir; private Context getContext() { return InstrumentationRegistry.getContext(); } @Before public void setUp() throws Exception { dir = getContext().getDir("testing", Context.MODE_PRIVATE); FileUtils.deleteContents(dir); } @After public void tearDown() throws Exception { FileUtils.deleteContents(dir); } @Test public void testClassify_empty() { assertEquals(0, classifyExternalStorageDirectory(dir)); } @Test public void testClassify_emptyDirs() { Environment.buildPath(dir, "DCIM").mkdirs(); Environment.buildPath(dir, "DCIM", "January").mkdirs(); Environment.buildPath(dir, "Downloads").mkdirs(); Environment.buildPath(dir, "LOST.DIR").mkdirs(); assertEquals(0, classifyExternalStorageDirectory(dir)); } @Test public void testClassify_emptyFactory() throws Exception { Environment.buildPath(dir, "autorun.inf").createNewFile(); Environment.buildPath(dir, "LaunchU3.exe").createNewFile(); Environment.buildPath(dir, "LaunchPad.zip").createNewFile(); assertEquals(0, classifyExternalStorageDirectory(dir)); } @Test public void testClassify_photos() throws Exception { Environment.buildPath(dir, "DCIM").mkdirs(); Environment.buildPath(dir, "DCIM", "IMG_1024.JPG").createNewFile(); Environment.buildPath(dir, "Download").mkdirs(); Environment.buildPath(dir, "Download", "foobar.pdf").createNewFile(); assertEquals(HAS_DCIM | HAS_DOWNLOADS, classifyExternalStorageDirectory(dir)); } @Test public void testClassify_other() throws Exception { Environment.buildPath(dir, "Android").mkdirs(); Environment.buildPath(dir, "Android", "com.example").mkdirs(); Environment.buildPath(dir, "Android", "com.example", "internal.dat").createNewFile(); Environment.buildPath(dir, "Linux").mkdirs(); Environment.buildPath(dir, "Linux", "install-amd64-minimal-20170907.iso").createNewFile(); assertEquals(HAS_ANDROID | HAS_OTHER, classifyExternalStorageDirectory(dir)); } @Test public void testClassify_otherRoot() throws Exception { Environment.buildPath(dir, "Taxes.pdf").createNewFile(); assertEquals(HAS_OTHER, classifyExternalStorageDirectory(dir)); } }
core/tests/coretests/src/android/os/FileUtilsTest.java +40 −9 Original line number Original line Diff line number Diff line Loading @@ -21,15 +21,24 @@ import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.WEEK_IN_MILLIS; import static android.text.format.DateUtils.WEEK_IN_MILLIS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.content.Context; import android.content.Context; import android.provider.DocumentsContract.Document; import android.provider.DocumentsContract.Document; import android.test.AndroidTestCase; import android.support.test.InstrumentationRegistry; import android.test.suitebuilder.annotation.MediumTest; import android.support.test.runner.AndroidJUnit4; import libcore.io.IoUtils; import libcore.io.IoUtils; import com.google.android.collect.Sets; import com.google.android.collect.Sets; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.File; import java.io.FileOutputStream; import java.io.FileOutputStream; Loading @@ -37,8 +46,8 @@ import java.io.FileWriter; import java.util.Arrays; import java.util.Arrays; import java.util.HashSet; import java.util.HashSet; @MediumTest @RunWith(AndroidJUnit4.class) public class FileUtilsTest extends AndroidTestCase { public class FileUtilsTest { private static final String TEST_DATA = private static final String TEST_DATA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; Loading @@ -47,10 +56,12 @@ public class FileUtilsTest extends AndroidTestCase { private File mCopyFile; private File mCopyFile; private File mTarget; private File mTarget; private Context getContext() { return InstrumentationRegistry.getContext(); } @Override @Before protected void setUp() throws Exception { public void setUp() throws Exception { super.setUp(); mDir = getContext().getDir("testing", Context.MODE_PRIVATE); mDir = getContext().getDir("testing", Context.MODE_PRIVATE); mTestFile = new File(mDir, "test.file"); mTestFile = new File(mDir, "test.file"); mCopyFile = new File(mDir, "copy.file"); mCopyFile = new File(mDir, "copy.file"); Loading @@ -59,14 +70,15 @@ public class FileUtilsTest extends AndroidTestCase { FileUtils.deleteContents(mTarget); FileUtils.deleteContents(mTarget); } } @Override @After protected void tearDown() throws Exception { public void tearDown() throws Exception { IoUtils.deleteContents(mDir); IoUtils.deleteContents(mDir); FileUtils.deleteContents(mTarget); FileUtils.deleteContents(mTarget); } } // TODO: test setPermissions(), getPermissions() // TODO: test setPermissions(), getPermissions() @Test public void testCopyFile() throws Exception { public void testCopyFile() throws Exception { stageFile(mTestFile, TEST_DATA); stageFile(mTestFile, TEST_DATA); assertFalse(mCopyFile.exists()); assertFalse(mCopyFile.exists()); Loading @@ -75,6 +87,7 @@ public class FileUtilsTest extends AndroidTestCase { assertEquals(TEST_DATA, FileUtils.readTextFile(mCopyFile, 0, null)); assertEquals(TEST_DATA, FileUtils.readTextFile(mCopyFile, 0, null)); } } @Test public void testCopyToFile() throws Exception { public void testCopyToFile() throws Exception { final String s = "Foo Bar"; final String s = "Foo Bar"; assertFalse(mCopyFile.exists()); assertFalse(mCopyFile.exists()); Loading @@ -83,6 +96,7 @@ public class FileUtilsTest extends AndroidTestCase { assertEquals(s, FileUtils.readTextFile(mCopyFile, 0, null)); assertEquals(s, FileUtils.readTextFile(mCopyFile, 0, null)); } } @Test public void testIsFilenameSafe() throws Exception { public void testIsFilenameSafe() throws Exception { assertTrue(FileUtils.isFilenameSafe(new File("foobar"))); assertTrue(FileUtils.isFilenameSafe(new File("foobar"))); assertTrue(FileUtils.isFilenameSafe(new File("a_b-c=d.e/0,1+23"))); assertTrue(FileUtils.isFilenameSafe(new File("a_b-c=d.e/0,1+23"))); Loading @@ -90,6 +104,7 @@ public class FileUtilsTest extends AndroidTestCase { assertFalse(FileUtils.isFilenameSafe(new File("foo\nbar"))); assertFalse(FileUtils.isFilenameSafe(new File("foo\nbar"))); } } @Test public void testReadTextFile() throws Exception { public void testReadTextFile() throws Exception { stageFile(mTestFile, TEST_DATA); stageFile(mTestFile, TEST_DATA); Loading @@ -110,6 +125,7 @@ public class FileUtilsTest extends AndroidTestCase { assertEquals(TEST_DATA, FileUtils.readTextFile(mTestFile, -100, "<>")); assertEquals(TEST_DATA, FileUtils.readTextFile(mTestFile, -100, "<>")); } } @Test public void testReadTextFileWithZeroLengthFile() throws Exception { public void testReadTextFileWithZeroLengthFile() throws Exception { stageFile(mTestFile, TEST_DATA); stageFile(mTestFile, TEST_DATA); new FileOutputStream(mTestFile).close(); // Zero out the file new FileOutputStream(mTestFile).close(); // Zero out the file Loading @@ -120,6 +136,7 @@ public class FileUtilsTest extends AndroidTestCase { assertEquals("", FileUtils.readTextFile(mTestFile, -10, "<>")); assertEquals("", FileUtils.readTextFile(mTestFile, -10, "<>")); } } @Test public void testContains() throws Exception { public void testContains() throws Exception { assertTrue(FileUtils.contains(new File("/"), new File("/moo.txt"))); assertTrue(FileUtils.contains(new File("/"), new File("/moo.txt"))); assertTrue(FileUtils.contains(new File("/"), new File("/"))); assertTrue(FileUtils.contains(new File("/"), new File("/"))); Loading @@ -137,11 +154,13 @@ public class FileUtilsTest extends AndroidTestCase { assertFalse(FileUtils.contains(new File("/sdcard/"), new File("/sdcard.txt"))); assertFalse(FileUtils.contains(new File("/sdcard/"), new File("/sdcard.txt"))); } } @Test public void testDeleteOlderEmptyDir() throws Exception { public void testDeleteOlderEmptyDir() throws Exception { FileUtils.deleteOlderFiles(mDir, 10, WEEK_IN_MILLIS); FileUtils.deleteOlderFiles(mDir, 10, WEEK_IN_MILLIS); assertDirContents(); assertDirContents(); } } @Test public void testDeleteOlderTypical() throws Exception { public void testDeleteOlderTypical() throws Exception { touch("file1", HOUR_IN_MILLIS); touch("file1", HOUR_IN_MILLIS); touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); Loading @@ -152,6 +171,7 @@ public class FileUtilsTest extends AndroidTestCase { assertDirContents("file1", "file2", "file3"); assertDirContents("file1", "file2", "file3"); } } @Test public void testDeleteOlderInFuture() throws Exception { public void testDeleteOlderInFuture() throws Exception { touch("file1", -HOUR_IN_MILLIS); touch("file1", -HOUR_IN_MILLIS); touch("file2", HOUR_IN_MILLIS); touch("file2", HOUR_IN_MILLIS); Loading @@ -166,6 +186,7 @@ public class FileUtilsTest extends AndroidTestCase { assertDirContents("file1", "file2"); assertDirContents("file1", "file2"); } } @Test public void testDeleteOlderOnlyAge() throws Exception { public void testDeleteOlderOnlyAge() throws Exception { touch("file1", HOUR_IN_MILLIS); touch("file1", HOUR_IN_MILLIS); touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); Loading @@ -177,6 +198,7 @@ public class FileUtilsTest extends AndroidTestCase { assertDirContents("file1"); assertDirContents("file1"); } } @Test public void testDeleteOlderOnlyCount() throws Exception { public void testDeleteOlderOnlyCount() throws Exception { touch("file1", HOUR_IN_MILLIS); touch("file1", HOUR_IN_MILLIS); touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); touch("file2", 1 * DAY_IN_MILLIS + HOUR_IN_MILLIS); Loading @@ -188,6 +210,7 @@ public class FileUtilsTest extends AndroidTestCase { assertDirContents("file1", "file2"); assertDirContents("file1", "file2"); } } @Test public void testValidExtFilename() throws Exception { public void testValidExtFilename() throws Exception { assertTrue(FileUtils.isValidExtFilename("a")); assertTrue(FileUtils.isValidExtFilename("a")); assertTrue(FileUtils.isValidExtFilename("foo.bar")); assertTrue(FileUtils.isValidExtFilename("foo.bar")); Loading @@ -208,6 +231,7 @@ public class FileUtilsTest extends AndroidTestCase { assertEquals("foo.bar", FileUtils.buildValidExtFilename("foo.bar")); assertEquals("foo.bar", FileUtils.buildValidExtFilename("foo.bar")); } } @Test public void testValidFatFilename() throws Exception { public void testValidFatFilename() throws Exception { assertTrue(FileUtils.isValidFatFilename("a")); assertTrue(FileUtils.isValidFatFilename("a")); assertTrue(FileUtils.isValidFatFilename("foo bar.baz")); assertTrue(FileUtils.isValidFatFilename("foo bar.baz")); Loading @@ -233,6 +257,7 @@ public class FileUtilsTest extends AndroidTestCase { assertEquals("foo_bar__baz", FileUtils.buildValidFatFilename("foo?bar**baz")); assertEquals("foo_bar__baz", FileUtils.buildValidFatFilename("foo?bar**baz")); } } @Test public void testTrimFilename() throws Exception { public void testTrimFilename() throws Exception { assertEquals("short.txt", FileUtils.trimFilename("short.txt", 16)); assertEquals("short.txt", FileUtils.trimFilename("short.txt", 16)); assertEquals("extrem...eme.txt", FileUtils.trimFilename("extremelylongfilename.txt", 16)); assertEquals("extrem...eme.txt", FileUtils.trimFilename("extremelylongfilename.txt", 16)); Loading @@ -245,6 +270,7 @@ public class FileUtilsTest extends AndroidTestCase { assertEquals("a...z", FileUtils.trimFilename(unicode, 6)); assertEquals("a...z", FileUtils.trimFilename(unicode, 6)); } } @Test public void testBuildUniqueFile_normal() throws Exception { public void testBuildUniqueFile_normal() throws Exception { assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test")); assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test")); assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg")); assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg")); Loading @@ -263,6 +289,7 @@ public class FileUtilsTest extends AndroidTestCase { FileUtils.buildUniqueFile(mTarget, "application/x-flac", "test.flac")); FileUtils.buildUniqueFile(mTarget, "application/x-flac", "test.flac")); } } @Test public void testBuildUniqueFile_unknown() throws Exception { public void testBuildUniqueFile_unknown() throws Exception { assertNameEquals("test", assertNameEquals("test", FileUtils.buildUniqueFile(mTarget, "application/octet-stream", "test")); FileUtils.buildUniqueFile(mTarget, "application/octet-stream", "test")); Loading @@ -275,6 +302,7 @@ public class FileUtilsTest extends AndroidTestCase { assertNameEquals("test.lolz", FileUtils.buildUniqueFile(mTarget, "lolz/lolz", "test.lolz")); assertNameEquals("test.lolz", FileUtils.buildUniqueFile(mTarget, "lolz/lolz", "test.lolz")); } } @Test public void testBuildUniqueFile_dir() throws Exception { public void testBuildUniqueFile_dir() throws Exception { assertNameEquals("test", FileUtils.buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test")); assertNameEquals("test", FileUtils.buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test")); new File(mTarget, "test").mkdir(); new File(mTarget, "test").mkdir(); Loading @@ -288,6 +316,7 @@ public class FileUtilsTest extends AndroidTestCase { FileUtils.buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test.jpg")); FileUtils.buildUniqueFile(mTarget, Document.MIME_TYPE_DIR, "test.jpg")); } } @Test public void testBuildUniqueFile_increment() throws Exception { public void testBuildUniqueFile_increment() throws Exception { assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg")); assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg")); new File(mTarget, "test.jpg").createNewFile(); new File(mTarget, "test.jpg").createNewFile(); Loading @@ -298,6 +327,7 @@ public class FileUtilsTest extends AndroidTestCase { FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg")); FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg")); } } @Test public void testBuildUniqueFile_mimeless() throws Exception { public void testBuildUniqueFile_mimeless() throws Exception { assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "test.jpg")); assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "test.jpg")); new File(mTarget, "test.jpg").createNewFile(); new File(mTarget, "test.jpg").createNewFile(); Loading @@ -312,6 +342,7 @@ public class FileUtilsTest extends AndroidTestCase { assertNameEquals("test.foo (1).bar", FileUtils.buildUniqueFile(mTarget, "test.foo.bar")); assertNameEquals("test.foo (1).bar", FileUtils.buildUniqueFile(mTarget, "test.foo.bar")); } } @Test public void testRoundStorageSize() throws Exception { public void testRoundStorageSize() throws Exception { final long M128 = 128000000L; final long M128 = 128000000L; final long M256 = 256000000L; final long M256 = 256000000L; Loading