thumbnail generation and disk caching

// FREEBIE
This commit is contained in:
Jake McGinty
2014-12-17 11:47:19 -08:00
parent a57c7c3e09
commit 121b1493cc
11 changed files with 257 additions and 37 deletions

View File

@@ -20,7 +20,9 @@ import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.util.Log;
import android.provider.ContactsContract;
@@ -74,12 +76,23 @@ public class AttachmentManager {
setMedia(new AudioSlide(context, audio));
}
public void setMedia(Slide slide, int thumbnailWidth, int thumbnailHeight) {
public void setMedia(final Slide slide, final int thumbnailWidth, final int thumbnailHeight) {
slideDeck.clear();
slideDeck.addSlide(slide);
thumbnail.setImageDrawable(slide.getThumbnail(thumbnailWidth, thumbnailHeight));
attachmentView.setVisibility(View.VISIBLE);
attachmentListener.onAttachmentChanged();
new AsyncTask<Void,Void,Drawable>() {
@Override
protected Drawable doInBackground(Void... params) {
return slide.getThumbnail(thumbnailWidth, thumbnailHeight);
}
@Override
protected void onPostExecute(Drawable drawable) {
thumbnail.setImageDrawable(drawable);
attachmentView.setVisibility(View.VISIBLE);
attachmentListener.onAttachmentChanged();
}
}.execute();
}
public void setMedia(Slide slide) {

View File

@@ -17,6 +17,8 @@
package org.thoughtcrime.securesms.mms;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
@@ -41,7 +43,6 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.Collections;
@@ -51,6 +52,7 @@ import ws.com.google.android.mms.ContentType;
import ws.com.google.android.mms.pdu.PduPart;
public class ImageSlide extends Slide {
private static final String TAG = ImageSlide.class.getSimpleName();
private static final int MAX_CACHE_SIZE = 10;
private static final Map<Uri, SoftReference<Drawable>> thumbnailCache =
@@ -77,8 +79,15 @@ public class ImageSlide extends Slide {
}
try {
thumbnail = new BitmapDrawable(context.getResources(),
BitmapUtil.createScaledBitmap(context, masterSecret, getUri(), maxWidth, maxHeight));
Bitmap thumbnailBitmap;
long startDecode = System.currentTimeMillis();
Log.w(TAG, (part.getThumbnailUri() == null ? "generating" : "fetching pre-generated") + " thumbnail");
if (part.getThumbnailUri() != null) thumbnailBitmap = BitmapFactory.decodeStream(PartAuthority.getPartStream(context, masterSecret, part.getThumbnailUri()));
else thumbnailBitmap = BitmapUtil.createScaledBitmap(context, masterSecret, getUri(), maxWidth, maxHeight);
Log.w(TAG, "thumbnail decode/generate time: " + (System.currentTimeMillis() - startDecode) + "ms");
thumbnail = new BitmapDrawable(context.getResources(), thumbnailBitmap);
thumbnailCache.put(part.getDataUri(), new SoftReference<>(thumbnail));
return thumbnail;
@@ -115,7 +124,7 @@ public class ImageSlide extends Slide {
MmsDatabase.slideResolver.execute(new Runnable() {
@Override
public void run() {
final Drawable bitmap = getThumbnail(maxWidth, maxHeight);
final Drawable bitmap = getThumbnail(maxWidth, maxHeight);
final ImageView destination = weakImageView.get();
if (destination != null && destination.getDrawable() == temporaryDrawable) {

View File

@@ -15,16 +15,21 @@ import java.io.InputStream;
public class PartAuthority {
private static final String PART_URI_STRING = "content://org.thoughtcrime.securesms/part";
public static final Uri PART_CONTENT_URI = Uri.parse(PART_URI_STRING);
private static final String PART_URI_STRING = "content://org.thoughtcrime.securesms/part";
private static final String THUMB_URI_STRING = "content://org.thoughtcrime.securesms/thumb";
public static final Uri PART_CONTENT_URI = Uri.parse(PART_URI_STRING);
public static final Uri THUMB_CONTENT_URI = Uri.parse(THUMB_URI_STRING);
private static final int PART_ROW = 1;
private static final int THUMB_ROW = 2;
private static final UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI("org.thoughtcrime.securesms", "part/#", PART_ROW);
uriMatcher.addURI("org.thoughtcrime.securesms", "thumb/#", THUMB_ROW);
}
public static InputStream getPartStream(Context context, MasterSecret masterSecret, Uri uri)
@@ -35,6 +40,7 @@ public class PartAuthority {
switch (match) {
case PART_ROW: return partDatabase.getPartStream(masterSecret, ContentUris.parseId(uri));
case THUMB_ROW: return partDatabase.getThumbnailStream(masterSecret, ContentUris.parseId(uri));
default: return context.getContentResolver().openInputStream(uri);
}
}

View File

@@ -16,7 +16,6 @@
*/
package org.thoughtcrime.securesms.mms;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -25,10 +24,7 @@ import org.w3c.dom.smil.SMILDocument;
import org.w3c.dom.smil.SMILMediaElement;
import org.w3c.dom.smil.SMILRegionElement;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.providers.PartProvider;
import android.content.ContentUris;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
@@ -42,10 +38,10 @@ public abstract class Slide {
public static final int MAX_MESSAGE_SIZE = 280 * 1024;
protected final PduPart part;
protected final Context context;
protected MasterSecret masterSecret;
protected final PduPart part;
protected final Context context;
protected MasterSecret masterSecret;
public Slide(Context context, PduPart part) {
this.part = part;
this.context = context;
@@ -56,10 +52,6 @@ public abstract class Slide {
this.masterSecret = masterSecret;
}
public InputStream getPartDataInputStream() throws FileNotFoundException {
return PartAuthority.getPartStream(context, masterSecret, part.getDataUri());
}
protected byte[] getPartData() {
try {
if (part.getData() != null)

View File

@@ -19,6 +19,7 @@ package org.thoughtcrime.securesms.mms;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import android.widget.ImageView;
import org.thoughtcrime.securesms.util.SmilUtil;
import org.w3c.dom.smil.SMILDocument;