Fix leaks / init

Change-Id: I5befdc24cc89cdcfb73ee4d13f076b1c4a585cf6
diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
index 548bc8a..1b7408f 100644
--- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java
+++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
@@ -95,7 +95,7 @@
     // fields for supporting crop action
     public static final String CROP_ACTION = "com.android.camera.action.CROP";
     private CropExtras mCropExtras = null;
-    MasterImage mMasterImage = MasterImage.getImage();
+    MasterImage mMasterImage = null;
 
     public static final String TINY_PLANET_ACTION = "com.android.camera.action.TINY_PLANET";
     public static final String LAUNCH_FULLSCREEN = "launch-fullscreen";
@@ -157,6 +157,7 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        setResources();
 
         Resources res = getResources();
         setupMasterImage();
@@ -387,18 +388,12 @@
 
         @Override
         protected Boolean doInBackground(Void... params) {
-            Resources res = getResources();
-            mBorders.add(new FilterImageBorderRepresentation(0, null));
-            Drawable npd1 = getBitmapDrawable(res, R.drawable.filtershow_border_4x5);
-            mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_4x5, npd1));
-            Drawable npd2 = getBitmapDrawable(res, R.drawable.filtershow_border_brush);
-            mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_brush, npd2));
-            Drawable npd3 = getBitmapDrawable(res, R.drawable.filtershow_border_grunge);
-            mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_grunge, npd3));
-            Drawable npd4 = getBitmapDrawable(res, R.drawable.filtershow_border_sumi_e);
-            mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_sumi_e, npd4));
-            Drawable npd5 = getBitmapDrawable(res, R.drawable.filtershow_border_tape);
-            mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_tape, npd5));
+            mBorders.add(new FilterImageBorderRepresentation(0));
+            mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_4x5));
+            mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_brush));
+            mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_grunge));
+            mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_sumi_e));
+            mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_tape));
             mBorders.add(new FilterColorBorderRepresentation(Color.BLACK, mImageBorderSize, 0));
             mBorders.add(new FilterColorBorderRepresentation(Color.BLACK, mImageBorderSize, mImageBorderSize));
             mBorders.add(new FilterColorBorderRepresentation(Color.WHITE, mImageBorderSize, 0));
@@ -464,9 +459,11 @@
 
         @Override
         protected void onPostExecute(Boolean result) {
+
             if (isCancelled()) {
                 return;
             }
+
             if (!result) {
                 cannotLoadImage();
             }
@@ -897,6 +894,7 @@
     public void onConfigurationChanged(Configuration newConfig)
     {
         super.onConfigurationChanged(newConfig);
+        setResources();
         if (mShowingHistoryPanel) {
             toggleHistoryPanel();
         }
@@ -909,6 +907,8 @@
         ImageStateAdapter mImageStateAdapter = new ImageStateAdapter(this,
                 R.layout.filtershow_imagestate_row);
 
+        MasterImage.reset();
+        mMasterImage = MasterImage.getImage();
         mMasterImage.setHistoryAdapter(mHistoryAdapter);
         mMasterImage.setStateAdapter(mImageStateAdapter);
         mMasterImage.setActivity(this);
@@ -1127,11 +1127,13 @@
         finish();
     }
 
+    private void setResources() {
+        ImageFilterBorder filterBorder = (ImageFilterBorder) FiltersManager.getManager().getFilter(ImageFilterBorder.class);
+        filterBorder.setResources(getResources());
+    }
+
     static {
         System.loadLibrary("jni_filtershow_filters");
     }
 
-    public static Drawable getBitmapDrawable(Resources res, int id) {
-        return new BitmapDrawable(res, BitmapFactory.decodeResource(res, id));
-    }
 }
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterImageBorderRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterImageBorderRepresentation.java
index 467409f..2b40fcc 100644
--- a/src/com/android/gallery3d/filtershow/filters/FilterImageBorderRepresentation.java
+++ b/src/com/android/gallery3d/filtershow/filters/FilterImageBorderRepresentation.java
@@ -16,18 +16,18 @@
 
 package com.android.gallery3d.filtershow.filters;
 
-import android.graphics.drawable.Drawable;
-
 public class FilterImageBorderRepresentation extends FilterRepresentation {
-    private Drawable mDrawable;
     private int mDrawableResource = 0;
 
-    public FilterImageBorderRepresentation(int drawableResource, Drawable drawable) {
+    public FilterImageBorderRepresentation(int drawableResource) {
         super("ImageBorder");
         mDrawableResource = drawableResource;
-        mDrawable = drawable;
         setFilterClass(ImageFilterBorder.class);
         setPriority(ImageFilter.TYPE_BORDER);
+        // load the drawable at init as we are in a background thread
+        // (see FilterShowActivity's LoadBordersTask)
+        ImageFilterBorder filter = (ImageFilterBorder) FiltersManager.getManager().getFilter(getFilterClass());
+        filter.getDrawable(getDrawableResource());
     }
 
     public String toString() {
@@ -38,7 +38,6 @@
     public FilterRepresentation clone() throws CloneNotSupportedException {
         FilterImageBorderRepresentation representation = (FilterImageBorderRepresentation) super.clone();
         representation.setName(getName());
-        representation.setDrawable(getDrawable());
         representation.setDrawableResource(getDrawableResource());
         return representation;
     }
@@ -47,7 +46,6 @@
         if (a instanceof FilterImageBorderRepresentation) {
             FilterImageBorderRepresentation representation = (FilterImageBorderRepresentation) a;
             setName(representation.getName());
-            setDrawable(representation.getDrawable());
             setDrawableResource(representation.getDrawableResource());
         }
     }
@@ -70,14 +68,6 @@
         return true;
     }
 
-    public Drawable getDrawable() {
-        return mDrawable;
-    }
-
-    public void setDrawable(Drawable drawable) {
-        mDrawable = drawable;
-    }
-
     public int getDrawableResource() {
         return mDrawableResource;
     }
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterBorder.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterBorder.java
index 6362124..200bcf1 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterBorder.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterBorder.java
@@ -16,17 +16,25 @@
 
 package com.android.gallery3d.filtershow.filters;
 
+import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 
 import com.android.gallery3d.R;
 
+import java.util.HashMap;
+
 public class ImageFilterBorder extends ImageFilter {
     private static final float NINEPATCH_ICON_SCALING = 10;
     private static final float BITMAP_ICON_SCALING = 1 / 3.0f;
     private FilterImageBorderRepresentation mParameters = null;
+    private Resources mResources = null;
+
+    private HashMap<Integer, Drawable> mDrawables = new HashMap<Integer, Drawable>();
 
     public ImageFilterBorder() {
         mName = "Border";
@@ -67,14 +75,15 @@
         Rect bounds = new Rect(0, 0, (int) (w * scale1), (int) (h * scale1));
         Canvas canvas = new Canvas(bitmap);
         canvas.scale(scale2, scale2);
-        getParameters().getDrawable().setBounds(bounds);
-        getParameters().getDrawable().draw(canvas);
+        Drawable drawable = getDrawable(getParameters().getDrawableResource());
+        drawable.setBounds(bounds);
+        drawable.draw(canvas);
         return bitmap;
     }
 
     @Override
     public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
-        if (getParameters() == null || getParameters().getDrawable() == null) {
+        if (getParameters() == null || getParameters().getDrawableResource() == 0) {
             return bitmap;
         }
         float scale2 = scaleFactor * 2.0f;
@@ -84,11 +93,28 @@
 
     @Override
     public Bitmap iconApply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
-        if (getParameters() == null || getParameters().getDrawable() == null) {
+        if (getParameters() == null || getParameters().getDrawableResource() == 0) {
             return bitmap;
         }
         float scale1 = NINEPATCH_ICON_SCALING;
         float scale2 = BITMAP_ICON_SCALING;
         return applyHelper(bitmap, scale1, scale2);
     }
+
+    public void setResources(Resources resources) {
+        if (mResources != resources) {
+            mResources = resources;
+            mDrawables.clear();
+        }
+    }
+
+    public Drawable getDrawable(int rsc) {
+        Drawable drawable = mDrawables.get(rsc);
+        if (drawable == null && mResources != null) {
+            drawable = new BitmapDrawable(mResources, BitmapFactory.decodeResource(mResources, rsc));
+            mDrawables.put(rsc, drawable);
+        }
+        return drawable;
+    }
+
 }
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
index 368e29a..4778d3c 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
@@ -31,7 +31,6 @@
     private static Bitmap sOldBitmap = null;
     private Bitmap mOldBitmap = null;
 
-    private static Bitmap mReturnBitmap = null;
     private final Bitmap.Config mBitmapConfig = Bitmap.Config.ARGB_8888;
 
     public void prepare(Bitmap bitmap, float scaleFactor, boolean highQuality) {
@@ -95,6 +94,15 @@
     public static void setRenderScriptContext(Activity context) {
         mRS = RenderScript.create(context);
         mResources = context.getResources();
+        if (mInPixelsAllocation != null) {
+            mInPixelsAllocation.destroy();
+            mInPixelsAllocation = null;
+        }
+        if (mOutPixelsAllocation != null) {
+            mOutPixelsAllocation.destroy();
+            mOutPixelsAllocation = null;
+        }
+        sOldBitmap = null;
     }
 
 }
diff --git a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
index 7c45ee2..87acd5f 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
@@ -34,7 +34,7 @@
 
     private static final String LOGTAG = "MasterImage";
 
-    private static MasterImage sMasterImage = new MasterImage();
+    private static MasterImage sMasterImage = null;
 
     private ImageFilter mCurrentFilter = null;
     private ImagePreset mPreset = null;
@@ -58,6 +58,9 @@
     private MasterImage() { }
 
     public static MasterImage getImage() {
+        if (sMasterImage == null) {
+            sMasterImage = new MasterImage();
+        }
         return sMasterImage;
     }
 
@@ -230,4 +233,8 @@
             mFiltersOnlyBitmap = request.getBitmap();
         }
     }
+
+    public static void reset() {
+        sMasterImage = null;
+    }
 }