ShadowEnvironment.java revision df6ac64d05f00add83341e8f538072f0efcb85dc
1package org.robolectric.shadows; 2 3import java.io.File; 4import java.io.IOException; 5import java.nio.file.Files; 6import java.nio.file.Path; 7import java.util.Map; 8import java.util.HashMap; 9import android.os.Environment; 10import org.robolectric.annotation.Resetter; 11import org.robolectric.annotation.Implements; 12import org.robolectric.annotation.Implementation; 13import org.robolectric.util.TempDirectory; 14 15/** 16 * Shadow for {@link android.os.Environment}. 17 */ 18@Implements(Environment.class) 19public class ShadowEnvironment { 20 private static String externalStorageState = Environment.MEDIA_REMOVED; 21 private static final Map<File, Boolean> STORAGE_EMULATED = new HashMap<>(); 22 private static final Map<File, Boolean> STORAGE_REMOVABLE = new HashMap<>(); 23 24 static Path EXTERNAL_CACHE_DIR; 25 static Path EXTERNAL_FILES_DIR; 26 27 @Implementation 28 public static String getExternalStorageState() { 29 return externalStorageState; 30 } 31 32 /** 33 * Non-Android accessor. Sets the return value of {@link #getExternalStorageState()}. 34 * 35 * @param externalStorageState Value to return from {@link #getExternalStorageState()}. 36 */ 37 public static void setExternalStorageState(String externalStorageState) { 38 ShadowEnvironment.externalStorageState = externalStorageState; 39 } 40 41 @Implementation 42 public static File getExternalStorageDirectory() { 43 if (!exists(EXTERNAL_CACHE_DIR)) EXTERNAL_CACHE_DIR = TempDirectory.create(); 44 return EXTERNAL_CACHE_DIR.toFile(); 45 } 46 47 @Implementation 48 public static File getExternalStoragePublicDirectory(String type) { 49 if (!exists(EXTERNAL_FILES_DIR)) EXTERNAL_FILES_DIR = TempDirectory.create(); 50 if (type == null) return EXTERNAL_FILES_DIR.toFile(); 51 Path path = EXTERNAL_FILES_DIR.resolve(type); 52 try { 53 Files.createDirectories(path); 54 } catch (IOException e) { 55 throw new RuntimeException(e); 56 } 57 return path.toFile(); 58 } 59 60 @Resetter 61 public static void reset() { 62 TempDirectory.destroy(EXTERNAL_CACHE_DIR); 63 TempDirectory.destroy(EXTERNAL_FILES_DIR); 64 65 EXTERNAL_CACHE_DIR = null; 66 EXTERNAL_FILES_DIR = null; 67 68 STORAGE_EMULATED.clear(); 69 STORAGE_REMOVABLE.clear(); 70 } 71 72 private static boolean exists(Path path) { 73 return path != null && Files.exists(path); 74 } 75 76 @Implementation 77 public static boolean isExternalStorageRemovable() { 78 final Boolean exists = STORAGE_REMOVABLE.get(getExternalStorageDirectory()); 79 return exists != null ? exists : false; 80 } 81 82#if ($api >= 19) 83 @Implementation 84 public static String getStorageState(File path) { 85 return externalStorageState; 86 } 87#end 88 89#if ($api >= 21) 90 @Implementation 91 public static String getExternalStorageState(File path) { 92 return externalStorageState; 93 } 94 95 @Implementation 96 public static boolean isExternalStorageRemovable(File path) { 97 final Boolean exists = STORAGE_REMOVABLE.get(path); 98 return exists != null ? exists : false; 99 } 100 101 @Implementation 102 public static boolean isExternalStorageEmulated(File path) { 103 final Boolean emulated = STORAGE_EMULATED.get(path); 104 return emulated != null ? emulated : false; 105 } 106 107 /** 108 * Non-Android accessor. Sets the "isRemovable" flag of a particular file. 109 * 110 * @param file Target file. 111 * @param isRemovable True if the filesystem is removable. 112 */ 113 public static void setExternalStorageRemovable(File file, boolean isRemovable) { 114 STORAGE_REMOVABLE.put(file, isRemovable); 115 } 116 117 /** 118 * Non-Android accessor. Sets the "isEmulated" flag of a particular file. 119 * 120 * @param file Target file. 121 * @param isEmulated True if the filesystem is emulated. 122 */ 123 public static void setExternalStorageEmulated(File file, boolean isEmulated) { 124 STORAGE_EMULATED.put(file, isEmulated); 125 } 126#end 127} 128