Fix rounded corners bitmap double free

Fixes #4732
// FREEBIE
This commit is contained in:
Moxie Marlinspike 2017-01-08 13:06:11 -08:00
parent 5804213152
commit 4ad989cc38
3 changed files with 26 additions and 15 deletions

View File

@ -9,7 +9,8 @@
<ImageView android:id="@+id/thumbnail" <ImageView android:id="@+id/thumbnail"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"/> android:layout_height="match_parent"
android:scaleType="centerCrop"/>
</org.thoughtcrime.securesms.components.SquareFrameLayout> </org.thoughtcrime.securesms.components.SquareFrameLayout>

View File

@ -22,6 +22,7 @@ import android.widget.ImageView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.load.Key; import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.signature.MediaStoreSignature; import com.bumptech.glide.signature.MediaStoreSignature;
import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.R;
@ -77,6 +78,8 @@ public class RecentPhotoViewRail extends FrameLayout implements LoaderManager.Lo
private static class RecentPhotoAdapter extends CursorRecyclerViewAdapter<RecentPhotoAdapter.RecentPhotoViewHolder> { private static class RecentPhotoAdapter extends CursorRecyclerViewAdapter<RecentPhotoAdapter.RecentPhotoViewHolder> {
private static final String TAG = RecentPhotoAdapter.class.getName();
@NonNull private final Uri baseUri; @NonNull private final Uri baseUri;
@Nullable private OnItemClickedListener clickedListener; @Nullable private OnItemClickedListener clickedListener;
@ -112,7 +115,7 @@ public class RecentPhotoViewRail extends FrameLayout implements LoaderManager.Lo
.fromMediaStore() .fromMediaStore()
.load(uri) .load(uri)
.signature(signature) .signature(signature)
.centerCrop() .diskCacheStrategy(DiskCacheStrategy.NONE)
.into(viewHolder.imageView); .into(viewHolder.imageView);
viewHolder.imageView.setOnClickListener(new OnClickListener() { viewHolder.imageView.setOnClickListener(new OnClickListener() {

View File

@ -38,19 +38,24 @@ public class RoundedCorners extends BitmapTransformation {
{ {
final Bitmap toRound = crop ? centerCrop(pool, toTransform, outWidth, outHeight) final Bitmap toRound = crop ? centerCrop(pool, toTransform, outWidth, outHeight)
: fitCenter(pool, toTransform, outWidth, outHeight); : fitCenter(pool, toTransform, outWidth, outHeight);
final Bitmap rounded = round(pool, toRound); 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(); toRound.recycle();
} }
return rounded; return rounded;
} }
private Bitmap centerCrop(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { private Bitmap centerCrop(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
final Bitmap toReuse = pool.get(outWidth, outHeight, getSafeConfig(toTransform)); final Bitmap toReuse = pool.get(outWidth, outHeight, getSafeConfig(toTransform));
final Bitmap transformed = TransformationUtils.centerCrop(toReuse, toTransform, outWidth, outHeight); final Bitmap transformed = TransformationUtils.centerCrop(toReuse, toTransform, outWidth, outHeight);
if (toReuse != null && toReuse != transformed && !pool.put(toReuse)) { if (toReuse != null && toReuse != transformed && !pool.put(toReuse)) {
toReuse.recycle(); toReuse.recycle();
} }
return transformed; return transformed;
} }
@ -63,28 +68,29 @@ public class RoundedCorners extends BitmapTransformation {
return null; return null;
} }
final Bitmap result; Bitmap result = pool.get(toRound.getWidth(), toRound.getHeight(), getSafeConfig(toRound));
final Bitmap toReuse = pool.get(toRound.getWidth(), toRound.getHeight(), getSafeConfig(toRound));
if (toReuse != null) { if (result == null) {
result = toReuse;
} else {
result = Bitmap.createBitmap(toRound.getWidth(), toRound.getHeight(), getSafeConfig(toRound)); result = Bitmap.createBitmap(toRound.getWidth(), toRound.getHeight(), getSafeConfig(toRound));
} }
final Canvas canvas = new Canvas(result); Canvas canvas = new Canvas(result);
final Paint cornerPaint = new Paint();
final Paint shaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
shaderPaint.setShader(new BitmapShader(toRound, TileMode.CLAMP, TileMode.CLAMP));
cornerPaint.setColor(colorHint);
if (Config.RGB_565.equals(result.getConfig())) { if (Config.RGB_565.equals(result.getConfig())) {
Paint cornerPaint = new Paint();
cornerPaint.setColor(colorHint);
canvas.drawRect(0, 0, radius, radius, cornerPaint); canvas.drawRect(0, 0, radius, radius, cornerPaint);
canvas.drawRect(0, toRound.getHeight() - radius, radius, toRound.getHeight(), 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, 0, toRound.getWidth(), radius, cornerPaint);
canvas.drawRect(toRound.getWidth() - radius, toRound.getHeight() - radius, toRound.getWidth(), toRound.getHeight(), 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); 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; return result;
} }
@ -92,7 +98,8 @@ public class RoundedCorners extends BitmapTransformation {
return bitmap.getConfig() != null ? bitmap.getConfig() : Bitmap.Config.ARGB_8888; return bitmap.getConfig() != null ? bitmap.getConfig() : Bitmap.Config.ARGB_8888;
} }
@Override public String getId() { @Override
public String getId() {
return RoundedCorners.class.getCanonicalName(); return RoundedCorners.class.getCanonicalName();
} }
} }