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