From 61d4192798163c882c38397b376c5a14094dc58f Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Sun, 30 Dec 2012 16:42:33 -0800 Subject: [PATCH] Refactor ContactPhotoFactory to handle changing local contact URIs. --- .../securesms/ConversationItem.java | 2 +- .../ContactPhotoFactory.java | 44 ++++++++++--------- .../recipients/RecipientFactory.java | 1 + .../recipients/RecipientProvider.java | 1 + 4 files changed, 27 insertions(+), 21 deletions(-) rename src/org/thoughtcrime/securesms/{recipients => contacts}/ContactPhotoFactory.java (59%) diff --git a/src/org/thoughtcrime/securesms/ConversationItem.java b/src/org/thoughtcrime/securesms/ConversationItem.java index 266940b019..a6076adc40 100644 --- a/src/org/thoughtcrime/securesms/ConversationItem.java +++ b/src/org/thoughtcrime/securesms/ConversationItem.java @@ -42,6 +42,7 @@ import android.widget.TextView; import android.widget.Toast; import org.thoughtcrime.securesms.contacts.ContactIdentityManager; +import org.thoughtcrime.securesms.contacts.ContactPhotoFactory; import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord; @@ -51,7 +52,6 @@ import org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord; import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.mms.SlideDeck; import org.thoughtcrime.securesms.protocol.Tag; -import org.thoughtcrime.securesms.recipients.ContactPhotoFactory; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.service.SendReceiveService; diff --git a/src/org/thoughtcrime/securesms/recipients/ContactPhotoFactory.java b/src/org/thoughtcrime/securesms/contacts/ContactPhotoFactory.java similarity index 59% rename from src/org/thoughtcrime/securesms/recipients/ContactPhotoFactory.java rename to src/org/thoughtcrime/securesms/contacts/ContactPhotoFactory.java index d579e63af8..4120944ca0 100644 --- a/src/org/thoughtcrime/securesms/recipients/ContactPhotoFactory.java +++ b/src/org/thoughtcrime/securesms/contacts/ContactPhotoFactory.java @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.recipients; +package org.thoughtcrime.securesms.contacts; import android.content.Context; import android.database.Cursor; @@ -9,16 +9,19 @@ import android.provider.ContactsContract; import android.provider.ContactsContract.Contacts; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.util.LRUCache; import java.io.InputStream; +import java.util.Collections; +import java.util.Map; public class ContactPhotoFactory { private static final Object defaultPhotoLock = new Object(); - private static final Object localUserLock = new Object(); private static Bitmap defaultContactPhoto; - private static Bitmap localUserContactPhoto; + private static final Map localUserContactPhotoCache = + Collections.synchronizedMap(new LRUCache(2)); private static final String[] CONTENT_URI_PROJECTION = new String[] { ContactsContract.Contacts._ID, @@ -31,33 +34,34 @@ public class ContactPhotoFactory { if (defaultContactPhoto == null) defaultContactPhoto = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_contact_picture); + return defaultContactPhoto; } - - return defaultContactPhoto; } public static Bitmap getLocalUserContactPhoto(Context context, Uri uri) { - synchronized (localUserLock) { - if (localUserContactPhoto == null) { - Cursor cursor = context.getContentResolver().query(uri, CONTENT_URI_PROJECTION, - null, null, null); - - if (cursor != null && cursor.moveToFirst()) { - localUserContactPhoto = getContactPhoto(context, Uri.withAppendedPath(Contacts.CONTENT_URI, - cursor.getLong(0) + "")); - } else { - localUserContactPhoto = getDefaultContactPhoto(context); - } + if (uri == null) return getDefaultContactPhoto(context); + + Bitmap contactPhoto = localUserContactPhotoCache.get(uri); + + if (contactPhoto == null) { + Cursor cursor = context.getContentResolver().query(uri, CONTENT_URI_PROJECTION, + null, null, null); + + if (cursor != null && cursor.moveToFirst()) { + contactPhoto = getContactPhoto(context, Uri.withAppendedPath(Contacts.CONTENT_URI, + cursor.getLong(0) + "")); + } else { + contactPhoto = getDefaultContactPhoto(context); } + + localUserContactPhotoCache.put(uri, contactPhoto); } - return localUserContactPhoto; + return contactPhoto; } public static void clearCache() { - synchronized (localUserLock) { - localUserContactPhoto = null; - } + localUserContactPhotoCache.clear(); } private static Bitmap getContactPhoto(Context context, Uri uri) { diff --git a/src/org/thoughtcrime/securesms/recipients/RecipientFactory.java b/src/org/thoughtcrime/securesms/recipients/RecipientFactory.java index 732ff4c60d..c6ce3a4609 100644 --- a/src/org/thoughtcrime/securesms/recipients/RecipientFactory.java +++ b/src/org/thoughtcrime/securesms/recipients/RecipientFactory.java @@ -18,6 +18,7 @@ package org.thoughtcrime.securesms.recipients; import android.content.Context; +import org.thoughtcrime.securesms.contacts.ContactPhotoFactory; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.util.NumberUtil; diff --git a/src/org/thoughtcrime/securesms/recipients/RecipientProvider.java b/src/org/thoughtcrime/securesms/recipients/RecipientProvider.java index 5ae2df03c8..daecba17bd 100644 --- a/src/org/thoughtcrime/securesms/recipients/RecipientProvider.java +++ b/src/org/thoughtcrime/securesms/recipients/RecipientProvider.java @@ -27,6 +27,7 @@ import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.PhoneLookup; import android.util.Log; +import org.thoughtcrime.securesms.contacts.ContactPhotoFactory; import org.thoughtcrime.securesms.util.LRUCache; import org.thoughtcrime.securesms.util.ListenableFutureTask; import org.thoughtcrime.securesms.util.Util;