From 4ad989cc38f6cbe2963524ae3ace455c2ee951b4 Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Sun, 8 Jan 2017 13:06:11 -0800 Subject: [PATCH] Fix rounded corners bitmap double free Fixes #4732 // FREEBIE --- res/layout/recent_photo_view_item.xml | 3 +- .../components/RecentPhotoViewRail.java | 5 ++- .../securesms/mms/RoundedCorners.java | 33 +++++++++++-------- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/res/layout/recent_photo_view_item.xml b/res/layout/recent_photo_view_item.xml index 39214dfc50..a85a38f7e0 100644 --- a/res/layout/recent_photo_view_item.xml +++ b/res/layout/recent_photo_view_item.xml @@ -9,7 +9,8 @@ + android:layout_height="match_parent" + android:scaleType="centerCrop"/> diff --git a/src/org/thoughtcrime/securesms/components/RecentPhotoViewRail.java b/src/org/thoughtcrime/securesms/components/RecentPhotoViewRail.java index 71617436fe..7cfb44fd84 100644 --- a/src/org/thoughtcrime/securesms/components/RecentPhotoViewRail.java +++ b/src/org/thoughtcrime/securesms/components/RecentPhotoViewRail.java @@ -22,6 +22,7 @@ import android.widget.ImageView; import com.bumptech.glide.Glide; import com.bumptech.glide.load.Key; +import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.signature.MediaStoreSignature; import org.thoughtcrime.securesms.R; @@ -77,6 +78,8 @@ public class RecentPhotoViewRail extends FrameLayout implements LoaderManager.Lo private static class RecentPhotoAdapter extends CursorRecyclerViewAdapter { + private static final String TAG = RecentPhotoAdapter.class.getName(); + @NonNull private final Uri baseUri; @Nullable private OnItemClickedListener clickedListener; @@ -112,7 +115,7 @@ public class RecentPhotoViewRail extends FrameLayout implements LoaderManager.Lo .fromMediaStore() .load(uri) .signature(signature) - .centerCrop() + .diskCacheStrategy(DiskCacheStrategy.NONE) .into(viewHolder.imageView); viewHolder.imageView.setOnClickListener(new OnClickListener() { diff --git a/src/org/thoughtcrime/securesms/mms/RoundedCorners.java b/src/org/thoughtcrime/securesms/mms/RoundedCorners.java index 0e777fb102..4b11170104 100644 --- a/src/org/thoughtcrime/securesms/mms/RoundedCorners.java +++ b/src/org/thoughtcrime/securesms/mms/RoundedCorners.java @@ -38,19 +38,24 @@ public class RoundedCorners extends BitmapTransformation { { final Bitmap toRound = crop ? centerCrop(pool, toTransform, outWidth, outHeight) : fitCenter(pool, toTransform, outWidth, outHeight); + final Bitmap rounded = round(pool, toRound); - if (toRound != null && toRound != rounded && !pool.put(toRound)) { + + if (toRound != null && toRound != rounded && toRound != toTransform && !pool.put(toRound)) { toRound.recycle(); } + return rounded; } private Bitmap centerCrop(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { final Bitmap toReuse = pool.get(outWidth, outHeight, getSafeConfig(toTransform)); final Bitmap transformed = TransformationUtils.centerCrop(toReuse, toTransform, outWidth, outHeight); + if (toReuse != null && toReuse != transformed && !pool.put(toReuse)) { toReuse.recycle(); } + return transformed; } @@ -63,28 +68,29 @@ public class RoundedCorners extends BitmapTransformation { return null; } - final Bitmap result; - final Bitmap toReuse = pool.get(toRound.getWidth(), toRound.getHeight(), getSafeConfig(toRound)); - if (toReuse != null) { - result = toReuse; - } else { + Bitmap result = pool.get(toRound.getWidth(), toRound.getHeight(), getSafeConfig(toRound)); + + if (result == null) { result = Bitmap.createBitmap(toRound.getWidth(), toRound.getHeight(), getSafeConfig(toRound)); } - final Canvas canvas = new Canvas(result); - final Paint cornerPaint = new Paint(); - final Paint shaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + Canvas canvas = new Canvas(result); - shaderPaint.setShader(new BitmapShader(toRound, TileMode.CLAMP, TileMode.CLAMP)); - cornerPaint.setColor(colorHint); if (Config.RGB_565.equals(result.getConfig())) { + Paint cornerPaint = new Paint(); + cornerPaint.setColor(colorHint); + canvas.drawRect(0, 0, radius, radius, cornerPaint); canvas.drawRect(0, toRound.getHeight() - radius, radius, toRound.getHeight(), cornerPaint); canvas.drawRect(toRound.getWidth() - radius, 0, toRound.getWidth(), radius, cornerPaint); canvas.drawRect(toRound.getWidth() - radius, toRound.getHeight() - radius, toRound.getWidth(), toRound.getHeight(), cornerPaint); } + + Paint shaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + shaderPaint.setShader(new BitmapShader(toRound, TileMode.CLAMP, TileMode.CLAMP)); + canvas.drawRoundRect(new RectF(0, 0, toRound.getWidth(), toRound.getHeight()), radius, radius, shaderPaint); -// Log.w("RoundedCorners", "in was " + toRound.getWidth() + "x" + toRound.getHeight() + ", out to " + result.getWidth() + "x" + result.getHeight()); + return result; } @@ -92,7 +98,8 @@ public class RoundedCorners extends BitmapTransformation { return bitmap.getConfig() != null ? bitmap.getConfig() : Bitmap.Config.ARGB_8888; } - @Override public String getId() { + @Override + public String getId() { return RoundedCorners.class.getCanonicalName(); } }