Home | History | Annotate | Download | only in shadows
      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 
     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
     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
     65     public int getColor(int id) throws Resources.NotFoundException {
     66         return resourceLoader.getColorValue(id);
     67     }
     68 
     69     @Implementation
     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
     82     public String getString(int id) throws Resources.NotFoundException {
     83         return resourceLoader.getStringValue(id);
     84     }
     85 
     86     @Implementation
     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
     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
     99     public String getQuantityString(int id, int quantity) throws Resources.NotFoundException {
    100         return resourceLoader.getPluralStringValue(id, quantity);
    101     }
    102 
    103     @Implementation
    104     public InputStream openRawResource(int id) throws Resources.NotFoundException {
    105         return resourceLoader.getRawValue(id);
    106     }
    107 
    108     @Implementation
    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
    118     public CharSequence[] getTextArray(int id) throws Resources.NotFoundException {
    119         return getStringArray(id);
    120     }
    121 
    122     @Implementation
    123     public CharSequence getText(int id) throws Resources.NotFoundException {
    124         return getString(id);
    125     }
    126 
    127     public void setDensity(float density) {
    128         this.density = density;
    129     }
    130 
    131     public void setDisplay(Display display) {
    132         this.display = display;
    133         displayMetrics = null;
    134     }
    135 
    136     @Implementation
    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
    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
    178     public float getDimension(int id) throws Resources.NotFoundException {
    179         return resourceLoader.getDimenValue(id);
    180     }
    181 
    182     @Implementation
    183     public int getInteger(int id) throws Resources.NotFoundException {
    184     	return resourceLoader.getIntegerValue( id );
    185     }
    186 
    187     @Implementation
    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
    197     public int getDimensionPixelOffset(int id) throws Resources.NotFoundException {
    198         return (int) getDimension(id);
    199     }
    200 
    201     @Implementation
    202     public AssetManager getAssets() {
    203         return ShadowAssetManager.bind(Robolectric.newInstanceOf(AssetManager.class), resourceLoader);
    204     }
    205 
    206     @Implementation
    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
    214         public TypedArray obtainStyledAttributes(int[] attrs) {
    215             return obtainStyledAttributes(0, attrs);
    216         }
    217 
    218         @Implementation
    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
    224         public TypedArray obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) {
    225             return newInstanceOf(TypedArray.class);
    226         }
    227     }
    228 }
    229