ShadowResources.java revision 9daa83d905eccca3b027ce27e4a77b3f57441a1e
1package com.xtremelabs.robolectric.shadows; 2 3import android.content.res.AssetManager; 4import android.content.res.Configuration; 5import android.content.res.Resources; 6import android.content.res.TypedArray; 7import android.graphics.BitmapFactory; 8import android.graphics.drawable.BitmapDrawable; 9import android.graphics.drawable.Drawable; 10import android.util.AttributeSet; 11import android.util.DisplayMetrics; 12import com.xtremelabs.robolectric.Robolectric; 13import com.xtremelabs.robolectric.internal.Implementation; 14import com.xtremelabs.robolectric.internal.Implements; 15import com.xtremelabs.robolectric.internal.RealObject; 16import com.xtremelabs.robolectric.res.ResourceExtractor; 17import com.xtremelabs.robolectric.res.ResourceLoader; 18 19import java.io.InputStream; 20import java.util.Locale; 21 22import static com.xtremelabs.robolectric.Robolectric.newInstanceOf; 23import static com.xtremelabs.robolectric.Robolectric.shadowOf; 24 25/** 26 * Shadow of {@code Resources} that simulates the loading of resources 27 * 28 * @see com.xtremelabs.robolectric.RobolectricTestRunner#RobolectricTestRunner(Class, String, String) 29 */ 30@SuppressWarnings({"UnusedDeclaration"}) 31@Implements(Resources.class) 32public class ShadowResources { 33 private float density = 1.0f; 34 35 static Resources bind(Resources resources, ResourceLoader resourceLoader) { 36 ShadowResources shadowResources = shadowOf(resources); 37 if (shadowResources.resourceLoader != null) throw new RuntimeException("ResourceLoader already set!"); 38 shadowResources.resourceLoader = resourceLoader; 39 return resources; 40 } 41 42 @RealObject Resources realResources; 43 private ResourceLoader resourceLoader; 44 45 @Implementation 46 public int getIdentifier(String name, String defType, String defPackage) { 47 Integer index = 0; 48 49 ResourceExtractor resourceExtractor = resourceLoader.getResourceExtractor(); 50 51 index = resourceExtractor.getResourceId(defType + "/" + name); 52 if (index == null) { 53 return 0; 54 } 55 return index; 56 } 57 58 @Implementation 59 public int getColor(int id) throws Resources.NotFoundException { 60 return resourceLoader.getColorValue(id); 61 } 62 63 @Implementation 64 public Configuration getConfiguration() { 65 Configuration configuration = new Configuration(); 66 configuration.setToDefaults(); 67 if (configuration.locale == null) { 68 configuration.locale = Locale.getDefault(); 69 } 70 return configuration; 71 } 72 73 @Implementation 74 public String getString(int id) throws Resources.NotFoundException { 75 return resourceLoader.getStringValue(id); 76 } 77 78 @Implementation 79 public String getString(int id, Object... formatArgs) throws Resources.NotFoundException { 80 String raw = getString(id); 81 return String.format(Locale.ENGLISH, raw, formatArgs); 82 } 83 84 @Implementation 85 public String getQuantityString(int id, int quantity, Object... formatArgs) throws Resources.NotFoundException { 86 String raw = getQuantityString(id, quantity); 87 return String.format(Locale.ENGLISH, raw, formatArgs); 88 } 89 90 @Implementation 91 public String getQuantityString(int id, int quantity) throws Resources.NotFoundException { 92 return resourceLoader.getPluralStringValue(id, quantity); 93 } 94 95 @Implementation 96 public InputStream openRawResource(int id) throws Resources.NotFoundException { 97 return resourceLoader.getRawValue(id); 98 } 99 100 @Implementation 101 public String[] getStringArray(int id) throws Resources.NotFoundException { 102 String[] arrayValue = resourceLoader.getStringArrayValue(id); 103 if (arrayValue == null) { 104 throw new Resources.NotFoundException(); 105 } 106 return arrayValue; 107 } 108 109 @Implementation 110 public CharSequence[] getTextArray(int id) throws Resources.NotFoundException { 111 return getStringArray(id); 112 } 113 114 @Implementation 115 public CharSequence getText(int id) throws Resources.NotFoundException { 116 return getString(id); 117 } 118 119 public void setDensity(float density) { 120 this.density = density; 121 } 122 123 @Implementation 124 public DisplayMetrics getDisplayMetrics() { 125 DisplayMetrics displayMetrics = new DisplayMetrics(); 126 displayMetrics.density = this.density; 127 return displayMetrics; 128 } 129 130 @Implementation 131 public Drawable getDrawable(int drawableResourceId) throws Resources.NotFoundException { 132 return new BitmapDrawable(BitmapFactory.decodeResource(realResources, drawableResourceId)); 133 } 134 135 @Implementation 136 public float getDimension(int id) throws Resources.NotFoundException { 137 // todo: get this value from the xml resources and scale it by display metrics [xw 20101011] 138 if (resourceLoader.dimensions.containsKey(id)) { 139 return resourceLoader.dimensions.get(id); 140 } 141 return id - 0x7f000000; 142 } 143 144 @Implementation 145 public int getDimensionPixelSize(int id) throws Resources.NotFoundException { 146 // The int value returned from here is probably going to be handed to TextView.setTextSize(), 147 // which takes a float. Avoid int-to-float conversion errors by returning a value generated from this 148 // resource ID but which isn't too big (resource values in R.java are all greater than 0x7f000000). 149 150 return (int) getDimension(id); 151 } 152 153 @Implementation 154 public int getDimensionPixelOffset(int id) throws Resources.NotFoundException { 155 return (int) getDimension(id); 156 } 157 158 @Implementation 159 public AssetManager getAssets() { 160 return ShadowAssetManager.bind(Robolectric.newInstanceOf(AssetManager.class), resourceLoader); 161 } 162 163 @Implementation 164 public final android.content.res.Resources.Theme newTheme() { 165 return newInstanceOf(Resources.Theme.class); 166 } 167 168 /** 169 * Non-Android accessor that sets the value to be returned by {@link #getDimension(int)} 170 * 171 * @param id ID to set the dimension for 172 * @param value value to be returned 173 */ 174 public void setDimension(int id, int value) { 175 resourceLoader.dimensions.put(id, value); 176 } 177 178 @Implements(Resources.Theme.class) 179 public static class ShadowTheme { 180 @Implementation 181 public TypedArray obtainStyledAttributes(int[] attrs) { 182 return obtainStyledAttributes(0, attrs); 183 } 184 185 @Implementation 186 public TypedArray obtainStyledAttributes(int resid, int[] attrs) throws android.content.res.Resources.NotFoundException { 187 return obtainStyledAttributes(null, attrs, 0, 0); 188 } 189 190 @Implementation 191 public TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) { 192 return newInstanceOf(TypedArray.class); 193 } 194 } 195} 196