1cfb3d242306311ce27ec51bf511764377c173a7cKiran Ryali + Christian Williamspackage org.robolectric.shadows; 2e9d4b241c1e9b9225da1424698942c358ef22162Chris Heisterkamp & Joe Moore 3d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabotimport static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; 4d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabotimport static android.os.Build.VERSION_CODES.KITKAT; 5d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabotimport static android.os.Build.VERSION_CODES.LOLLIPOP; 6d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabotimport static android.os.Build.VERSION_CODES.M; 7d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot 8d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabotimport android.os.Environment; 943a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglassimport java.io.File; 10c472650a6c989986a7276fcde482af7cdeba065aAlexander Blomimport java.io.IOException; 11c472650a6c989986a7276fcde482af7cdeba065aAlexander Blomimport java.nio.file.Files; 12c472650a6c989986a7276fcde482af7cdeba065aAlexander Blomimport java.nio.file.Path; 13084d588b645d53c1110ff24b82433b5a331cc6d3James Lemieuximport java.util.ArrayList; 1443a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglassimport java.util.HashMap; 15d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabotimport java.util.List; 16d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabotimport java.util.Map; 17d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabotimport org.robolectric.RuntimeEnvironment; 1843a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglassimport org.robolectric.annotation.Implementation; 19d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabotimport org.robolectric.annotation.Implements; 20d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabotimport org.robolectric.annotation.Resetter; 21d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabotimport org.robolectric.util.ReflectionHelpers; 229e11c64f01e0d72a3f469d5866b695c778387c26Christian Williams & Dimitris Couchell 23e9d4b241c1e9b9225da1424698942c358ef22162Chris Heisterkamp & Joe Moore@Implements(Environment.class) 24e9d4b241c1e9b9225da1424698942c358ef22162Chris Heisterkamp & Joe Moorepublic class ShadowEnvironment { 2543a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass private static String externalStorageState = Environment.MEDIA_REMOVED; 2643a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass private static final Map<File, Boolean> STORAGE_EMULATED = new HashMap<>(); 2743a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass private static final Map<File, Boolean> STORAGE_REMOVABLE = new HashMap<>(); 280a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie private static boolean sIsExternalStorageEmulated; 291b698c5055f7ad57d68b4b8fca1d3d7aa5fce1b0Jonathan Gerrish private static Path tmpExternalFilesDirBase; 30084d588b645d53c1110ff24b82433b5a331cc6d3James Lemieux private static final List<File> externalDirs = new ArrayList<>(); 31d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot private static Map<Path, String> storageState = new HashMap<>(); 3229a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams 33c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom static Path EXTERNAL_CACHE_DIR; 34c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom static Path EXTERNAL_FILES_DIR; 35c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom 3629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams @Implementation 3729a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams public static String getExternalStorageState() { 3829a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams return externalStorageState; 3929a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams } 4029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams 4143a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass /** 42d5dcccbc5fdf62c40af6fb046197878843c0cb5dChristian Williams * Sets the return value of {@link #getExternalStorageState()}. 4343a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass * 4443a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass * @param externalStorageState Value to return from {@link #getExternalStorageState()}. 4543a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass */ 4643a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass public static void setExternalStorageState(String externalStorageState) { 4743a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass ShadowEnvironment.externalStorageState = externalStorageState; 4843a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass } 4943a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass 500a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie /** 51d5dcccbc5fdf62c40af6fb046197878843c0cb5dChristian Williams * Sets the return value of {@link #isExternalStorageEmulated()}. 520a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie * 530a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie * @param emulated Value to return from {@link #isExternalStorageEmulated()}. 540a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie */ 550a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie public static void setIsExternalStorageEmulated(boolean emulated) { 560a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie ShadowEnvironment.sIsExternalStorageEmulated = emulated; 570a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie } 580a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie 5943a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass @Implementation 6043a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass public static File getExternalStorageDirectory() { 611b698c5055f7ad57d68b4b8fca1d3d7aa5fce1b0Jonathan Gerrish if (!exists(EXTERNAL_CACHE_DIR)) EXTERNAL_CACHE_DIR = RuntimeEnvironment.getTempDirectory().create("external-cache"); 62c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom return EXTERNAL_CACHE_DIR.toFile(); 6343a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass } 6443a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass 6543a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass @Implementation 6643a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass public static File getExternalStoragePublicDirectory(String type) { 671b698c5055f7ad57d68b4b8fca1d3d7aa5fce1b0Jonathan Gerrish if (!exists(EXTERNAL_FILES_DIR)) EXTERNAL_FILES_DIR = RuntimeEnvironment.getTempDirectory().create("external-files"); 68c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom if (type == null) return EXTERNAL_FILES_DIR.toFile(); 69c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom Path path = EXTERNAL_FILES_DIR.resolve(type); 70c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom try { 71f00fb170b988ce99dcc1ff5190e17c0d35b67234Alexander Blom Files.createDirectories(path); 72c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom } catch (IOException e) { 73c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom throw new RuntimeException(e); 74c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom } 75c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom return path.toFile(); 7643a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass } 7743a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass 7843a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass @Resetter 7943a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass public static void reset() { 80c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom 81c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom EXTERNAL_CACHE_DIR = null; 82c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom EXTERNAL_FILES_DIR = null; 83c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom 8443a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass STORAGE_EMULATED.clear(); 8543a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass STORAGE_REMOVABLE.clear(); 860a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie 87d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot storageState = new HashMap<>(); 88d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot externalDirs.clear(); 89d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot 900a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie sIsExternalStorageEmulated = false; 9143a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass } 9243a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass 93c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom private static boolean exists(Path path) { 94c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom return path != null && Files.exists(path); 95c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom } 96c472650a6c989986a7276fcde482af7cdeba065aAlexander Blom 97df6ac64d05f00add83341e8f538072f0efcb85dcJonathan Gerrish @Implementation 98df6ac64d05f00add83341e8f538072f0efcb85dcJonathan Gerrish public static boolean isExternalStorageRemovable() { 99df6ac64d05f00add83341e8f538072f0efcb85dcJonathan Gerrish final Boolean exists = STORAGE_REMOVABLE.get(getExternalStorageDirectory()); 100df6ac64d05f00add83341e8f538072f0efcb85dcJonathan Gerrish return exists != null ? exists : false; 101df6ac64d05f00add83341e8f538072f0efcb85dcJonathan Gerrish } 102df6ac64d05f00add83341e8f538072f0efcb85dcJonathan Gerrish 103d5191fc46f3997c3dedfea14680ec4f114124619Christian Williams @Implementation(minSdk = KITKAT) 104d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot public static String getStorageState(File directory) { 105d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot Path directoryPath = directory.toPath(); 106d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot for (Map.Entry<Path, String> entry : storageState.entrySet()) { 107d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot if (directoryPath.startsWith(entry.getKey())) { 108d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot return entry.getValue(); 109d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } 110d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } 111d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot return null; 112ef61bd4a7e62b3e1623ac7d8735232f1d629d6dfJonathan Gerrish } 113ef61bd4a7e62b3e1623ac7d8735232f1d629d6dfJonathan Gerrish 114d5191fc46f3997c3dedfea14680ec4f114124619Christian Williams @Implementation(minSdk = LOLLIPOP) 115d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot public static String getExternalStorageState(File directory) { 116d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot Path directoryPath = directory.toPath(); 117d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot for (Map.Entry<Path, String> entry : storageState.entrySet()) { 118d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot if (directoryPath.startsWith(entry.getKey())) { 119d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot return entry.getValue(); 120d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } 121d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } 122d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot return null; 123ef61bd4a7e62b3e1623ac7d8735232f1d629d6dfJonathan Gerrish } 124ef61bd4a7e62b3e1623ac7d8735232f1d629d6dfJonathan Gerrish 125d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot 126d5191fc46f3997c3dedfea14680ec4f114124619Christian Williams @Implementation(minSdk = LOLLIPOP) 12743a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass public static boolean isExternalStorageRemovable(File path) { 12843a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass final Boolean exists = STORAGE_REMOVABLE.get(path); 12943a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass return exists != null ? exists : false; 13029a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams } 13129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams 132d5191fc46f3997c3dedfea14680ec4f114124619Christian Williams @Implementation(minSdk = LOLLIPOP) 13343a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass public static boolean isExternalStorageEmulated(File path) { 13443a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass final Boolean emulated = STORAGE_EMULATED.get(path); 13543a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass return emulated != null ? emulated : false; 13629a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams } 1379fbd34e2cfc7b9b2be99ae8e27afa623cc61ae72Dimitris Couchell 1380a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie @Implementation 1390a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie public static boolean isExternalStorageEmulated() { 1400a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie return sIsExternalStorageEmulated; 1410a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie } 1420a3c4710aadbab8090414c6c576fba7ad36e89feMichael Hoisie 14343a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass /** 144d5dcccbc5fdf62c40af6fb046197878843c0cb5dChristian Williams * Sets the "isRemovable" flag of a particular file. 14543a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass * 14643a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass * @param file Target file. 14743a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass * @param isRemovable True if the filesystem is removable. 14843a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass */ 14943a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass public static void setExternalStorageRemovable(File file, boolean isRemovable) { 15043a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass STORAGE_REMOVABLE.put(file, isRemovable); 15143a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass } 15243a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass 15343a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass /** 154d5dcccbc5fdf62c40af6fb046197878843c0cb5dChristian Williams * Sets the "isEmulated" flag of a particular file. 15543a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass * 15643a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass * @param file Target file. 15743a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass * @param isEmulated True if the filesystem is emulated. 15843a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass */ 15943a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass public static void setExternalStorageEmulated(File file, boolean isEmulated) { 16043a35d3623cad51c47f5b07c41d71665e891b6a3Erich Douglass STORAGE_EMULATED.put(file, isEmulated); 16129a8359eaef1ee9f40c967d3c4b5c1117c8c2a43Christian Williams } 162d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot 163d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot /** 164d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot * Adds a directory to list returned by {@link ShadowUserEnvironment#getExternalDirs()}. 165d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot * 166d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot * @param path the external dir to add 167d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot */ 168d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot public static File addExternalDir(String path) { 169d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot Path externalFileDir; 170d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot if (path == null) { 171d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot externalFileDir = null; 172d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } else { 173d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot try { 1741b698c5055f7ad57d68b4b8fca1d3d7aa5fce1b0Jonathan Gerrish if (tmpExternalFilesDirBase == null) { 1751b698c5055f7ad57d68b4b8fca1d3d7aa5fce1b0Jonathan Gerrish tmpExternalFilesDirBase = RuntimeEnvironment.getTempDirectory().create("external-files-base"); 1761b698c5055f7ad57d68b4b8fca1d3d7aa5fce1b0Jonathan Gerrish } 177d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot externalFileDir = tmpExternalFilesDirBase.resolve(path); 178d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot Files.createDirectories(externalFileDir); 179d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot externalDirs.add(externalFileDir.toFile()); 180d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } catch (IOException e) { 181d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot throw new RuntimeException("Could not create external files dir", e); 182d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } 183d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } 184d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot 185d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot if (RuntimeEnvironment.getApiLevel() >= JELLY_BEAN_MR1 186d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot && RuntimeEnvironment.getApiLevel() < KITKAT) { 187d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot if (externalDirs.size() == 1 && externalFileDir != null) { 188d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot Environment.UserEnvironment userEnvironment = 189d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot ReflectionHelpers.getStaticField(Environment.class, "sCurrentUser"); 190d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot ReflectionHelpers.setField( 191d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot userEnvironment, "mExternalStorageAndroidData", externalFileDir.toFile()); 192d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } 193d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } else if (RuntimeEnvironment.getApiLevel() >= KITKAT && RuntimeEnvironment.getApiLevel() < M) { 194d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot Environment.UserEnvironment userEnvironment = 195d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot ReflectionHelpers.getStaticField(Environment.class, "sCurrentUser"); 196d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot ReflectionHelpers.setField(userEnvironment, "mExternalDirsForApp", 197d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot externalDirs.toArray(new File[externalDirs.size()])); 198d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } 199d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot 200d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot if (externalFileDir == null) { 201d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot return null; 202d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } 203d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot return externalFileDir.toFile(); 204d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } 205d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot 206d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot /** 207d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot * Sets the {@link #getExternalStorageState(File)} for given directory. 208d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot * 209d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot * @param externalStorageState Value to return from {@link #getExternalStorageState(File)}. 210d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot */ 211d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot public static void setExternalStorageState(File directory, String state) { 212d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot storageState.put(directory.toPath(), state); 213d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } 214d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot 215d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot /** 216d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot * Shadow for {@link android.os.Environment.UserEnvironment} 217d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot */ 218d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot @Implements(className = "android.os.Environment$UserEnvironment", isInAndroidSdk = false) 219d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot public static class ShadowUserEnvironment { 220d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot 221d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot @Implementation 222d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot public File[] getExternalDirs() { 223d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot return externalDirs.toArray(new File[externalDirs.size()]); 224d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } 225d1f45b44eb9b6ebb83fb9ae1f4adbfb52861c886Brett Chabot } 226e9d4b241c1e9b9225da1424698942c358ef22162Chris Heisterkamp & Joe Moore} 227