1package com.xtremelabs.robolectric.shadows; 2 3import android.content.res.Resources; 4import android.graphics.Bitmap; 5import android.graphics.BitmapFactory; 6import android.graphics.Point; 7import android.graphics.Rect; 8import android.net.Uri; 9import com.xtremelabs.robolectric.Robolectric; 10import com.xtremelabs.robolectric.internal.Implementation; 11import com.xtremelabs.robolectric.internal.Implements; 12import com.xtremelabs.robolectric.util.Join; 13 14import java.io.InputStream; 15import java.util.ArrayList; 16import java.util.HashMap; 17import java.util.List; 18import java.util.Map; 19 20import static com.xtremelabs.robolectric.Robolectric.shadowOf; 21 22@SuppressWarnings({"UnusedDeclaration"}) 23@Implements(BitmapFactory.class) 24public class ShadowBitmapFactory { 25 private static Map<String, Point> widthAndHeightMap = new HashMap<String, Point>(); 26 27 @Implementation 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 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 41 private static String getResourceName(int id) { 42 return shadowOf(Robolectric.application).getResourceLoader().getNameForId(id); 43 } 44 45 @Implementation 46 public static Bitmap decodeFile(String pathName) { 47 return create("file:" + pathName); 48 } 49 50 @Implementation 51 public static Bitmap decodeFile(String pathName, BitmapFactory.Options options) { 52 return create("file:" + pathName, options); 53 } 54 55 @Implementation 56 public static Bitmap decodeStream(InputStream is) { 57 return decodeStream(is, null, new BitmapFactory.Options()); 58 } 59 60 @Implementation 61 public static Bitmap decodeStream(InputStream is, Rect outPadding, BitmapFactory.Options opts) { 62 return create(is.toString().replaceFirst("stream for ", ""), opts); 63 } 64 65 static Bitmap create(String name) { 66 return create(name, new BitmapFactory.Options()); 67 } 68 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 92 public static void provideWidthAndHeightHints(Uri uri, int width, int height) { 93 widthAndHeightMap.put(uri.toString(), new Point(width, height)); 94 } 95 96 public static void provideWidthAndHeightHints(int resourceId, int width, int height) { 97 widthAndHeightMap.put("resource:" + getResourceName(resourceId), new Point(width, height)); 98 } 99 100 public static void provideWidthAndHeightHints(String file, int width, int height) { 101 widthAndHeightMap.put("file:" + file, new Point(width, height)); 102 } 103 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 113 public static void reset() { 114 widthAndHeightMap.clear(); 115 } 116} 117