1 package com.xtremelabs.robolectric.shadows;
2 
3 import android.content.res.Resources;
4 import android.graphics.Bitmap;
5 import android.graphics.BitmapFactory;
6 import android.graphics.Point;
7 import android.graphics.Rect;
8 import android.net.Uri;
9 import com.xtremelabs.robolectric.Robolectric;
10 import com.xtremelabs.robolectric.internal.Implementation;
11 import com.xtremelabs.robolectric.internal.Implements;
12 import com.xtremelabs.robolectric.util.Join;
13 
14 import java.io.InputStream;
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Map;
19 
20 import static com.xtremelabs.robolectric.Robolectric.shadowOf;
21 
22 @SuppressWarnings({"UnusedDeclaration"})
23 @Implements(BitmapFactory.class)
24 public class ShadowBitmapFactory {
25     private static Map<String, Point> widthAndHeightMap = new HashMap<String, Point>();
26 
27     @Implementation
decodeResource(Resources res, int id)28     public static Bitmap decodeResource(Resources res, int id) {
29         Bitmap bitmap = create("resource:" + getResourceName(id));
30         shadowOf(bitmap).setLoadedFromResourceId(id);
31         return bitmap;
32     }
33 
34     @Implementation
decodeResource(Resources res, int id, BitmapFactory.Options options)35     public static Bitmap decodeResource(Resources res, int id, BitmapFactory.Options options) {
36         Bitmap bitmap = create("resource:" + getResourceName(id), options);
37         shadowOf(bitmap).setLoadedFromResourceId(id);
38         return bitmap;
39     }
40 
getResourceName(int id)41     private static String getResourceName(int id) {
42         return shadowOf(Robolectric.application).getResourceLoader().getNameForId(id);
43     }
44 
45     @Implementation
decodeFile(String pathName)46     public static Bitmap decodeFile(String pathName) {
47         return create("file:" + pathName);
48     }
49 
50     @Implementation
decodeFile(String pathName, BitmapFactory.Options options)51     public static Bitmap decodeFile(String pathName, BitmapFactory.Options options) {
52         return create("file:" + pathName, options);
53     }
54 
55     @Implementation
decodeStream(InputStream is)56     public static Bitmap decodeStream(InputStream is) {
57         return decodeStream(is, null, new BitmapFactory.Options());
58     }
59 
60     @Implementation
decodeStream(InputStream is, Rect outPadding, BitmapFactory.Options opts)61     public static Bitmap decodeStream(InputStream is, Rect outPadding, BitmapFactory.Options opts) {
62         return create(is.toString().replaceFirst("stream for ", ""), opts);
63     }
64 
create(String name)65     static Bitmap create(String name) {
66         return create(name, new BitmapFactory.Options());
67     }
68 
create(String name, BitmapFactory.Options options)69     public static Bitmap create(String name, BitmapFactory.Options options) {
70         Bitmap bitmap = Robolectric.newInstanceOf(Bitmap.class);
71         ShadowBitmap shadowBitmap = shadowOf(bitmap);
72         shadowBitmap.appendDescription("Bitmap for " + name);
73 
74         String optionsString = stringify(options);
75         if (optionsString.length() > 0) {
76             shadowBitmap.appendDescription(" with options ");
77             shadowBitmap.appendDescription(optionsString);
78         }
79 
80         Point widthAndHeight = widthAndHeightMap.get(name);
81         if (widthAndHeight == null) {
82             widthAndHeight = new Point(100, 100);
83         }
84 
85         shadowBitmap.setWidth(widthAndHeight.x);
86         shadowBitmap.setHeight(widthAndHeight.y);
87         options.outWidth = widthAndHeight.x;
88         options.outHeight = widthAndHeight.y;
89         return bitmap;
90     }
91 
provideWidthAndHeightHints(Uri uri, int width, int height)92     public static void provideWidthAndHeightHints(Uri uri, int width, int height) {
93         widthAndHeightMap.put(uri.toString(), new Point(width, height));
94     }
95 
provideWidthAndHeightHints(int resourceId, int width, int height)96     public static void provideWidthAndHeightHints(int resourceId, int width, int height) {
97         widthAndHeightMap.put("resource:" + getResourceName(resourceId), new Point(width, height));
98     }
99 
provideWidthAndHeightHints(String file, int width, int height)100     public static void provideWidthAndHeightHints(String file, int width, int height) {
101         widthAndHeightMap.put("file:" + file, new Point(width, height));
102     }
103 
stringify(BitmapFactory.Options options)104     private static String stringify(BitmapFactory.Options options) {
105         List<String> opts = new ArrayList<String>();
106 
107         if (options.inJustDecodeBounds) opts.add("inJustDecodeBounds");
108         if (options.inSampleSize > 1) opts.add("inSampleSize=" + options.inSampleSize);
109 
110         return Join.join(", ", opts);
111     }
112 
reset()113     public static void reset() {
114         widthAndHeightMap.clear();
115     }
116 }
117