refactored avatar workers into single class

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/entities/Account.java               |   9 
src/main/java/eu/siacs/conversations/entities/Bookmark.java              |   5 
src/main/java/eu/siacs/conversations/entities/Contact.java               |   7 
src/main/java/eu/siacs/conversations/entities/Conversation.java          |  10 
src/main/java/eu/siacs/conversations/entities/ListItem.java              |   3 
src/main/java/eu/siacs/conversations/entities/Message.java               |  14 
src/main/java/eu/siacs/conversations/services/AvatarService.java         |  20 
src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java   |   3 
src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java      |   3 
src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java         |   5 
src/main/java/eu/siacs/conversations/ui/XmppActivity.java                |  10 
src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java      |  90 
src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java | 103 
src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java     |  91 
src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java      | 116 
src/main/java/eu/siacs/conversations/ui/util/AvatarWorkerTask.java       | 113 
src/main/res/values/dimens.xml                                           |   3 
17 files changed, 203 insertions(+), 402 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/entities/Account.java 🔗

@@ -22,12 +22,14 @@ import eu.siacs.conversations.R;
 import eu.siacs.conversations.crypto.PgpDecryptionService;
 import eu.siacs.conversations.crypto.axolotl.AxolotlService;
 import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession;
+import eu.siacs.conversations.services.AvatarService;
 import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.utils.UIHelper;
 import eu.siacs.conversations.utils.XmppUri;
 import eu.siacs.conversations.xmpp.XmppConnection;
 import rocks.xmpp.addr.Jid;
 
-public class Account extends AbstractEntity {
+public class Account extends AbstractEntity implements AvatarService.Avatarable {
 
     public static final String TABLENAME = "accounts";
 
@@ -579,6 +581,11 @@ public class Account extends AbstractEntity {
         return this.getStatus() == State.ONLINE && this.getXmppConnection() != null;
     }
 
+    @Override
+    public int getAvatarBackgroundColor() {
+        return UIHelper.getColorForName(jid.asBareJid().toString());
+    }
+
     public enum State {
         DISABLED(false, false),
         OFFLINE(false),

src/main/java/eu/siacs/conversations/entities/Bookmark.java 🔗

@@ -181,4 +181,9 @@ public class Bookmark extends Element implements ListItem {
 		}
 		return StringUtils.changed(before, name);
 	}
+
+	@Override
+	public int getAvatarBackgroundColor() {
+		return UIHelper.getColorForName(jid != null ? jid.asBareJid().toString() : getDisplayName());
+	}
 }

src/main/java/eu/siacs/conversations/entities/Contact.java 🔗

@@ -537,7 +537,12 @@ public class Contact implements ListItem, Blockable {
 		}
 	}
 
-    public final class Options {
+	@Override
+	public int getAvatarBackgroundColor() {
+		return UIHelper.getColorForName(jid != null ? jid.asBareJid().toString() : getDisplayName());
+	}
+
+	public final class Options {
 		public static final int TO = 0;
 		public static final int FROM = 1;
 		public static final int ASKING = 2;

src/main/java/eu/siacs/conversations/entities/Conversation.java 🔗

@@ -2,6 +2,7 @@ package eu.siacs.conversations.entities;
 
 import android.content.ContentValues;
 import android.database.Cursor;
+import android.graphics.Color;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.text.TextUtils;
@@ -24,8 +25,10 @@ import eu.siacs.conversations.crypto.OmemoSetting;
 import eu.siacs.conversations.crypto.PgpDecryptionService;
 import eu.siacs.conversations.crypto.axolotl.AxolotlService;
 import eu.siacs.conversations.persistance.DatabaseBackend;
+import eu.siacs.conversations.services.AvatarService;
 import eu.siacs.conversations.services.QuickConversationsService;
 import eu.siacs.conversations.utils.JidHelper;
+import eu.siacs.conversations.utils.UIHelper;
 import eu.siacs.conversations.xmpp.InvalidJid;
 import eu.siacs.conversations.xmpp.chatstate.ChatState;
 import eu.siacs.conversations.xmpp.mam.MamReference;
@@ -34,7 +37,7 @@ import rocks.xmpp.addr.Jid;
 import static eu.siacs.conversations.entities.Bookmark.printableValue;
 
 
-public class Conversation extends AbstractEntity implements Blockable, Comparable<Conversation>, Conversational {
+public class Conversation extends AbstractEntity implements Blockable, Comparable<Conversation>, Conversational, AvatarService.Avatarable {
 	public static final String TABLENAME = "conversations";
 
 	public static final int STATUS_AVAILABLE = 0;
@@ -991,6 +994,11 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
 		return 0;
 	}
 
+	@Override
+	public int getAvatarBackgroundColor() {
+		return UIHelper.getColorForName(getName().toString());
+	}
+
 	public interface OnMessageFound {
 		void onMessageFound(final Message message);
 	}

src/main/java/eu/siacs/conversations/entities/ListItem.java 🔗

@@ -4,10 +4,11 @@ import android.content.Context;
 
 import java.util.List;
 
+import eu.siacs.conversations.services.AvatarService;
 import rocks.xmpp.addr.Jid;
 
 
-public interface ListItem extends Comparable<ListItem> {
+public interface ListItem extends Comparable<ListItem>, AvatarService.Avatarable {
 	String getDisplayName();
 
 	Jid getJid();

src/main/java/eu/siacs/conversations/entities/Message.java 🔗

@@ -2,6 +2,8 @@ package eu.siacs.conversations.entities;
 
 import android.content.ContentValues;
 import android.database.Cursor;
+import android.graphics.Color;
+import android.support.annotation.ColorInt;
 import android.text.SpannableStringBuilder;
 import android.util.Log;
 
@@ -19,6 +21,7 @@ import java.util.Set;
 
 import eu.siacs.conversations.Config;
 import eu.siacs.conversations.crypto.axolotl.FingerprintStatus;
+import eu.siacs.conversations.services.AvatarService;
 import eu.siacs.conversations.utils.CryptoHelper;
 import eu.siacs.conversations.utils.Emoticons;
 import eu.siacs.conversations.utils.GeoHelper;
@@ -27,7 +30,7 @@ import eu.siacs.conversations.utils.MimeUtils;
 import eu.siacs.conversations.utils.UIHelper;
 import rocks.xmpp.addr.Jid;
 
-public class Message extends AbstractEntity {
+public class Message extends AbstractEntity implements AvatarService.Avatarable  {
 
 	public static final String TABLENAME = "messages";
 
@@ -627,6 +630,15 @@ public class Message extends AbstractEntity {
 		return this.counterparts;
 	}
 
+	@Override
+	public int getAvatarBackgroundColor() {
+		if (type == Message.TYPE_STATUS && getCounterparts() != null && getCounterparts().size() > 1) {
+			return Color.TRANSPARENT;
+		} else {
+			return UIHelper.getColorForName(UIHelper.getMessageDisplayName(this));
+		}
+	}
+
 	public static class MergeSeparator {
 	}
 

src/main/java/eu/siacs/conversations/services/AvatarService.java 🔗

@@ -13,6 +13,7 @@ import android.graphics.Typeface;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.support.annotation.ColorInt;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
 import android.support.v4.content.res.ResourcesCompat;
@@ -41,6 +42,7 @@ import eu.siacs.conversations.entities.MucOptions;
 import eu.siacs.conversations.utils.UIHelper;
 import eu.siacs.conversations.xmpp.OnAdvancedStreamFeaturesLoaded;
 import eu.siacs.conversations.xmpp.XmppConnection;
+import eu.siacs.conversations.xmpp.pep.Avatar;
 import rocks.xmpp.addr.Jid;
 
 public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
@@ -69,6 +71,20 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
 		return (int) (SYSTEM_UI_AVATAR_SIZE * context.getResources().getDisplayMetrics().density);
 	}
 
+	public Bitmap get(final Avatarable avatarable, final int size, final boolean cachedOnly) {
+		if (avatarable instanceof Account) {
+			return get((Account) avatarable,size,cachedOnly);
+		} else if (avatarable instanceof Conversation) {
+			return get((Conversation) avatarable, size, cachedOnly);
+		} else if (avatarable instanceof Message) {
+			return get((Message) avatarable, size, cachedOnly);
+		} else if (avatarable instanceof ListItem) {
+			return get((ListItem) avatarable, size, cachedOnly);
+		}
+		throw new AssertionError("AvatarService does not know how to generate avatar from "+avatarable.getClass().getName());
+
+	}
+
 	private Bitmap get(final Contact contact, final int size, boolean cachedOnly) {
 		if (contact.isSelf()) {
 			return get(contact.getAccount(), size, cachedOnly);
@@ -646,4 +662,8 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
 	private static String emptyOnNull(@Nullable Jid value) {
 		return value == null ? "" : value.toString();
 	}
+
+	public interface Avatarable {
+		@ColorInt int getAvatarBackgroundColor();
+	}
 }

src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java 🔗

@@ -55,6 +55,7 @@ import eu.siacs.conversations.ui.adapter.MediaAdapter;
 import eu.siacs.conversations.ui.interfaces.OnMediaLoaded;
 import eu.siacs.conversations.ui.service.EmojiService;
 import eu.siacs.conversations.ui.util.Attachment;
+import eu.siacs.conversations.ui.util.AvatarWorkerTask;
 import eu.siacs.conversations.ui.util.GridManager;
 import eu.siacs.conversations.ui.util.MenuDoubleTabUtil;
 import eu.siacs.conversations.ui.util.MucDetailsContextMenuHelper;
@@ -544,7 +545,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
         this.binding.editMucNameButton.setVisibility((self.getAffiliation().ranks(MucOptions.Affiliation.OWNER) || mucOptions.canChangeSubject()) ? View.VISIBLE : View.GONE);
         this.binding.detailsAccount.setText(getString(R.string.using_account, account));
         this.binding.jid.setText(mConversation.getJid().asBareJid().toEscapedString());
-        this.binding.yourPhoto.setImageBitmap(avatarService().get(mConversation,(int) getResources().getDimension(R.dimen.avatar_on_details_screen_size)));
+        AvatarWorkerTask.loadAvatar(mConversation,binding.yourPhoto,R.dimen.avatar_on_details_screen_size);
         String roomName = mucOptions.getName();
         String subject = mucOptions.getSubject();
         final boolean hasTitle;

src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java 🔗

@@ -43,6 +43,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
 import eu.siacs.conversations.ui.adapter.MediaAdapter;
 import eu.siacs.conversations.ui.interfaces.OnMediaLoaded;
 import eu.siacs.conversations.ui.util.Attachment;
+import eu.siacs.conversations.ui.util.AvatarWorkerTask;
 import eu.siacs.conversations.ui.util.GridManager;
 import eu.siacs.conversations.ui.util.JidDialog;
 import eu.siacs.conversations.ui.util.MenuDoubleTabUtil;
@@ -402,7 +403,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
             account = contact.getAccount().getJid().asBareJid().toString();
         }
         binding.detailsAccount.setText(getString(R.string.using_account, account));
-        binding.detailsContactBadge.setImageBitmap(avatarService().get(contact, (int) getResources().getDimension(R.dimen.avatar_on_details_screen_size)));
+        AvatarWorkerTask.loadAvatar(contact,binding.detailsContactBadge,R.dimen.avatar_on_details_screen_size);
         binding.detailsContactBadge.setOnClickListener(this.onBadgeClick);
 
         binding.detailsContactKeys.removeAllViews();

src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java 🔗

@@ -58,6 +58,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
 import eu.siacs.conversations.services.XmppConnectionService.OnCaptchaRequested;
 import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
 import eu.siacs.conversations.ui.adapter.PresenceTemplateAdapter;
+import eu.siacs.conversations.ui.util.AvatarWorkerTask;
 import eu.siacs.conversations.ui.util.MenuDoubleTabUtil;
 import eu.siacs.conversations.ui.util.PendingItem;
 import eu.siacs.conversations.ui.util.SoftKeyboardUtils;
@@ -604,7 +605,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
     }
 
     private void refreshAvatar() {
-        binding.avater.setImageBitmap(avatarService().get(mAccount, (int) getResources().getDimension(R.dimen.avatar_on_details_screen_size)));
+        AvatarWorkerTask.loadAvatar(mAccount,binding.avater,R.dimen.avatar_on_details_screen_size);
     }
 
     @Override
@@ -952,7 +953,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
 
         if (!mInitMode) {
             this.binding.avater.setVisibility(View.VISIBLE);
-            this.binding.avater.setImageBitmap(avatarService().get(this.mAccount, (int) getResources().getDimension(R.dimen.avatar_on_details_screen_size)));
+            AvatarWorkerTask.loadAvatar(mAccount,binding.avater,R.dimen.avatar_on_details_screen_size);
         } else {
             this.binding.avater.setVisibility(View.GONE);
         }

src/main/java/eu/siacs/conversations/ui/XmppActivity.java 🔗

@@ -36,6 +36,7 @@ import android.os.PowerManager;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.support.annotation.BoolRes;
+import android.support.annotation.NonNull;
 import android.support.annotation.StringRes;
 import android.support.v4.content.ContextCompat;
 import android.support.v7.app.AlertDialog;
@@ -993,11 +994,12 @@ public abstract class XmppActivity extends ActionBarActivity {
 		}
 	}
 
-	public static XmppActivity find(WeakReference<ImageView> viewWeakReference) {
+	public static XmppActivity find(@NonNull  WeakReference<ImageView> viewWeakReference) {
 		final View view = viewWeakReference.get();
-		if (view == null) {
-			return null;
-		}
+		return view == null ? null : find(view);
+	}
+
+	public static XmppActivity find(@NonNull final View view) {
 		final Context context = view.getContext();
 		if (context instanceof XmppActivity) {
 			return (XmppActivity) context;

src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java 🔗

@@ -22,6 +22,7 @@ import eu.siacs.conversations.R;
 import eu.siacs.conversations.databinding.AccountRowBinding;
 import eu.siacs.conversations.entities.Account;
 import eu.siacs.conversations.ui.XmppActivity;
+import eu.siacs.conversations.ui.util.AvatarWorkerTask;
 import eu.siacs.conversations.ui.util.StyledAttributes;
 import eu.siacs.conversations.utils.UIHelper;
 
@@ -59,7 +60,7 @@ public class AccountAdapter extends ArrayAdapter<Account> {
         } else {
             viewHolder.binding.accountJid.setText(account.getJid().asBareJid().toString());
         }
-        loadAvatar(account, viewHolder.binding.accountImage);
+        AvatarWorkerTask.loadAvatar(account, viewHolder.binding.accountImage, R.dimen.avatar);
         viewHolder.binding.accountStatus.setText(getContext().getString(account.getStatus().getReadableId()));
         switch (account.getStatus()) {
             case ONLINE:
@@ -97,97 +98,10 @@ public class AccountAdapter extends ArrayAdapter<Account> {
         }
     }
 
-    private static class BitmapWorkerTask extends AsyncTask<Account, Void, Bitmap> {
-        private final WeakReference<ImageView> imageViewReference;
-        private Account account = null;
-
-        BitmapWorkerTask(ImageView imageView) {
-            imageViewReference = new WeakReference<>(imageView);
-        }
-
-        @Override
-        protected Bitmap doInBackground(Account... params) {
-            this.account = params[0];
-            final XmppActivity activity = XmppActivity.find(imageViewReference);
-            if (activity == null) {
-                return null;
-            }
-            return activity.avatarService().get(this.account, activity.getPixel(48), isCancelled());
-        }
-
-        @Override
-        protected void onPostExecute(Bitmap bitmap) {
-            if (bitmap != null && !isCancelled()) {
-                final ImageView imageView = imageViewReference.get();
-                if (imageView != null) {
-                    imageView.setImageBitmap(bitmap);
-                    imageView.setBackgroundColor(0x00000000);
-                }
-            }
-        }
-    }
-
-    private void loadAvatar(Account account, ImageView imageView) {
-        if (cancelPotentialWork(account, imageView)) {
-            final Bitmap bm = activity.avatarService().get(account, activity.getPixel(48), true);
-            if (bm != null) {
-                cancelPotentialWork(account, imageView);
-                imageView.setImageBitmap(bm);
-                imageView.setBackgroundColor(0x00000000);
-            } else {
-                imageView.setBackgroundColor(UIHelper.getColorForName(account.getJid().asBareJid().toString()));
-                imageView.setImageDrawable(null);
-                final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
-                final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
-                imageView.setImageDrawable(asyncDrawable);
-                try {
-                    task.execute(account);
-                } catch (final RejectedExecutionException ignored) {
-                }
-            }
-        }
-    }
 
 
     public interface OnTglAccountState {
         void onClickTglAccountState(Account account, boolean state);
     }
 
-    private static boolean cancelPotentialWork(Account account, ImageView imageView) {
-        final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
-
-        if (bitmapWorkerTask != null) {
-            final Account oldAccount = bitmapWorkerTask.account;
-            if (oldAccount == null || account != oldAccount) {
-                bitmapWorkerTask.cancel(true);
-            } else {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
-        if (imageView != null) {
-            final Drawable drawable = imageView.getDrawable();
-            if (drawable instanceof AsyncDrawable) {
-                final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
-                return asyncDrawable.getBitmapWorkerTask();
-            }
-        }
-        return null;
-    }
-
-    static class AsyncDrawable extends BitmapDrawable {
-        private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
-
-        AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
-            super(res, bitmap);
-            bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
-        }
-
-        BitmapWorkerTask getBitmapWorkerTask() {
-            return bitmapWorkerTaskReference.get();
-        }
-    }
 }

src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java 🔗

@@ -1,36 +1,24 @@
 package eu.siacs.conversations.ui.adapter;
 
-import android.content.Context;
-import android.content.res.Resources;
 import android.databinding.DataBindingUtil;
-import android.graphics.Bitmap;
 import android.graphics.Typeface;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.AsyncTask;
 import android.support.annotation.NonNull;
 import android.support.v7.widget.RecyclerView;
 import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.TextView;
 
-import java.lang.ref.WeakReference;
 import java.util.List;
-import java.util.concurrent.RejectedExecutionException;
 
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.databinding.ConversationListRowBinding;
 import eu.siacs.conversations.entities.Conversation;
 import eu.siacs.conversations.entities.Message;
-import eu.siacs.conversations.entities.Transferable;
 import eu.siacs.conversations.ui.ConversationFragment;
 import eu.siacs.conversations.ui.XmppActivity;
+import eu.siacs.conversations.ui.util.AvatarWorkerTask;
 import eu.siacs.conversations.ui.util.StyledAttributes;
-import eu.siacs.conversations.ui.widget.UnreadCountCustomView;
 import eu.siacs.conversations.utils.EmojiWrapper;
 import eu.siacs.conversations.utils.IrregularUnicodeDetector;
 import eu.siacs.conversations.utils.UIHelper;
@@ -47,30 +35,6 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
         this.conversations = conversations;
     }
 
-    private static boolean cancelPotentialWork(Conversation conversation, ImageView imageView) {
-        final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
-
-        if (bitmapWorkerTask != null) {
-            final Conversation oldConversation = bitmapWorkerTask.conversation;
-            if (oldConversation == null || conversation != oldConversation) {
-                bitmapWorkerTask.cancel(true);
-            } else {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
-        if (imageView != null) {
-            final Drawable drawable = imageView.getDrawable();
-            if (drawable instanceof AsyncDrawable) {
-                final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
-                return asyncDrawable.getBitmapWorkerTask();
-            }
-        }
-        return null;
-    }
 
     @NonNull
     @Override
@@ -219,7 +183,7 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
             timestamp = conversation.getLatestMessage().getTimeSent();
         }
         viewHolder.binding.conversationLastupdate.setText(UIHelper.readableTimeDifference(activity, timestamp));
-        loadAvatar(conversation, viewHolder.binding.conversationImage);
+        AvatarWorkerTask.loadAvatar(conversation, viewHolder.binding.conversationImage, R.dimen.avatar_on_conversation_overview);
         viewHolder.itemView.setOnClickListener(v -> listener.onConversationClick(v, conversation));
     }
 
@@ -232,26 +196,6 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
         this.listener = listener;
     }
 
-    private void loadAvatar(Conversation conversation, ImageView imageView) {
-        if (cancelPotentialWork(conversation, imageView)) {
-            final Bitmap bm = activity.avatarService().get(conversation, activity.getPixel(56), true);
-            if (bm != null) {
-                cancelPotentialWork(conversation, imageView);
-                imageView.setImageBitmap(bm);
-                imageView.setBackgroundColor(0x00000000);
-            } else {
-                imageView.setBackgroundColor(UIHelper.getColorForName(conversation.getName().toString()));
-                imageView.setImageDrawable(null);
-                final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
-                final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
-                imageView.setImageDrawable(asyncDrawable);
-                try {
-                    task.execute(conversation);
-                } catch (final RejectedExecutionException ignored) {
-                }
-            }
-        }
-    }
 
     public void insert(Conversation c, int position) {
         conversations.add(position, c);
@@ -277,47 +221,4 @@ public class ConversationAdapter extends RecyclerView.Adapter<ConversationAdapte
 
     }
 
-    static class AsyncDrawable extends BitmapDrawable {
-        private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
-
-        AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
-            super(res, bitmap);
-            bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
-        }
-
-        BitmapWorkerTask getBitmapWorkerTask() {
-            return bitmapWorkerTaskReference.get();
-        }
-    }
-
-    static class BitmapWorkerTask extends AsyncTask<Conversation, Void, Bitmap> {
-        private final WeakReference<ImageView> imageViewReference;
-        private Conversation conversation = null;
-
-        BitmapWorkerTask(ImageView imageView) {
-            imageViewReference = new WeakReference<>(imageView);
-        }
-
-
-        @Override
-        protected Bitmap doInBackground(Conversation... params) {
-            this.conversation = params[0];
-            final XmppActivity activity = XmppActivity.find(imageViewReference);
-            if (activity == null) {
-                return null;
-            }
-            return activity.avatarService().get(this.conversation, activity.getPixel(56), isCancelled());
-        }
-
-        @Override
-        protected void onPostExecute(Bitmap bitmap) {
-            if (bitmap != null && !isCancelled()) {
-                final ImageView imageView = imageViewReference.get();
-                if (imageView != null) {
-                    imageView.setImageBitmap(bitmap);
-                    imageView.setBackgroundColor(0x00000000);
-                }
-            }
-        }
-    }
 }

src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java 🔗

@@ -26,6 +26,7 @@ import eu.siacs.conversations.databinding.ContactBinding;
 import eu.siacs.conversations.entities.ListItem;
 import eu.siacs.conversations.ui.SettingsActivity;
 import eu.siacs.conversations.ui.XmppActivity;
+import eu.siacs.conversations.ui.util.AvatarWorkerTask;
 import eu.siacs.conversations.utils.EmojiWrapper;
 import eu.siacs.conversations.utils.IrregularUnicodeDetector;
 import eu.siacs.conversations.utils.UIHelper;
@@ -49,30 +50,6 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
 		this.activity = activity;
 	}
 
-	private static boolean cancelPotentialWork(ListItem item, ImageView imageView) {
-		final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
-
-		if (bitmapWorkerTask != null) {
-			final ListItem oldItem = bitmapWorkerTask.item;
-			if (oldItem == null || item != oldItem) {
-				bitmapWorkerTask.cancel(true);
-			} else {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
-		if (imageView != null) {
-			final Drawable drawable = imageView.getDrawable();
-			if (drawable instanceof AsyncDrawable) {
-				final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
-				return asyncDrawable.getBitmapWorkerTask();
-			}
-		}
-		return null;
-	}
 
 	public void refreshSettings() {
 		SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity);
@@ -114,7 +91,7 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
 			viewHolder.jid.setVisibility(View.GONE);
 		}
 		viewHolder.name.setText(EmojiWrapper.transform(item.getDisplayName()));
-		loadAvatar(item, viewHolder.avatar);
+		AvatarWorkerTask.loadAvatar(item, viewHolder.avatar, R.dimen.avatar);
 		return view;
 	}
 
@@ -122,27 +99,6 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
 		this.mOnTagClickedListener = listener;
 	}
 
-	private void loadAvatar(ListItem item, ImageView imageView) {
-		if (cancelPotentialWork(item, imageView)) {
-			final Bitmap bm = activity.avatarService().get(item, activity.getPixel(48), true);
-			if (bm != null) {
-				cancelPotentialWork(item, imageView);
-				imageView.setImageBitmap(bm);
-				imageView.setBackgroundColor(0x00000000);
-			} else {
-				String seed = item.getJid() != null ? item.getJid().asBareJid().toString() : item.getDisplayName();
-				imageView.setBackgroundColor(UIHelper.getColorForName(seed));
-				imageView.setImageDrawable(null);
-				final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
-				final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
-				imageView.setImageDrawable(asyncDrawable);
-				try {
-					task.execute(item);
-				} catch (final RejectedExecutionException ignored) {
-				}
-			}
-		}
-	}
 
 	public interface OnTagClickedListener {
 		void onTagClicked(String tag);
@@ -169,47 +125,4 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
 		}
 	}
 
-	static class AsyncDrawable extends BitmapDrawable {
-		private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
-
-		AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
-			super(res, bitmap);
-			bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
-		}
-
-		BitmapWorkerTask getBitmapWorkerTask() {
-			return bitmapWorkerTaskReference.get();
-		}
-	}
-
-	private static class BitmapWorkerTask extends AsyncTask<ListItem, Void, Bitmap> {
-		private final WeakReference<ImageView> imageViewReference;
-		private ListItem item = null;
-
-		BitmapWorkerTask(ImageView imageView) {
-			imageViewReference = new WeakReference<>(imageView);
-		}
-
-		@Override
-		protected Bitmap doInBackground(ListItem... params) {
-			this.item = params[0];
-			final XmppActivity activity = XmppActivity.find(imageViewReference);
-			if (activity == null) {
-				return null;
-			}
-			return activity.avatarService().get(this.item, activity.getPixel(48), isCancelled());
-		}
-
-		@Override
-		protected void onPostExecute(Bitmap bitmap) {
-			if (bitmap != null && !isCancelled()) {
-				final ImageView imageView = imageViewReference.get();
-				if (imageView != null) {
-					imageView.setImageBitmap(bitmap);
-					imageView.setBackgroundColor(0x00000000);
-				}
-			}
-		}
-	}
-
 }

src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java 🔗

@@ -2,21 +2,11 @@ package eu.siacs.conversations.ui.adapter;
 
 import android.Manifest;
 import android.app.Activity;
-import android.content.ActivityNotFoundException;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Color;
 import android.graphics.Typeface;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.AsyncTask;
 import android.preference.PreferenceManager;
-import android.support.annotation.ColorInt;
 import android.support.v4.app.ActivityCompat;
 import android.support.v4.content.ContextCompat;
 import android.text.Spannable;
@@ -28,7 +18,6 @@ import android.text.style.ForegroundColorSpan;
 import android.text.style.RelativeSizeSpan;
 import android.text.style.StyleSpan;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.view.ActionMode;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -43,10 +32,8 @@ import android.widget.RelativeLayout;
 import android.widget.TextView;
 import android.widget.Toast;
 
-import java.lang.ref.WeakReference;
 import java.net.URL;
 import java.util.List;
-import java.util.concurrent.RejectedExecutionException;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -64,12 +51,13 @@ import eu.siacs.conversations.http.P1S3UrlStreamHandler;
 import eu.siacs.conversations.persistance.FileBackend;
 import eu.siacs.conversations.services.MessageArchiveService;
 import eu.siacs.conversations.services.NotificationService;
-import eu.siacs.conversations.ui.ConversationsActivity;
 import eu.siacs.conversations.ui.ConversationFragment;
+import eu.siacs.conversations.ui.ConversationsActivity;
 import eu.siacs.conversations.ui.XmppActivity;
 import eu.siacs.conversations.ui.service.AudioPlayer;
 import eu.siacs.conversations.ui.text.DividerSpan;
 import eu.siacs.conversations.ui.text.QuoteSpan;
+import eu.siacs.conversations.ui.util.AvatarWorkerTask;
 import eu.siacs.conversations.ui.util.MyLinkify;
 import eu.siacs.conversations.ui.util.ViewUtil;
 import eu.siacs.conversations.ui.widget.ClickableMovementMethod;
@@ -109,30 +97,6 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 	}
 
 
-	public static boolean cancelPotentialWork(Message message, ImageView imageView) {
-		final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
-
-		if (bitmapWorkerTask != null) {
-			final Message oldMessage = bitmapWorkerTask.message;
-			if (oldMessage == null || message != oldMessage) {
-				bitmapWorkerTask.cancel(true);
-			} else {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
-		if (imageView != null) {
-			final Drawable drawable = imageView.getDrawable();
-			if (drawable instanceof AsyncDrawable) {
-				final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
-				return asyncDrawable.getBitmapWorkerTask();
-			}
-		}
-		return null;
-	}
 
 	private static void resetClickListener(View... views) {
 		for (View view : views) {
@@ -704,10 +668,10 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 				boolean showAvatar;
 				if (conversation.getMode() == Conversation.MODE_SINGLE) {
 					showAvatar = true;
-					loadAvatar(message, viewHolder.contact_picture, activity.getPixel(32));
+					AvatarWorkerTask.loadAvatar(message, viewHolder.contact_picture, R.dimen.avatar_on_status_message);
 				} else if (message.getCounterpart() != null || message.getTrueCounterpart() != null || (message.getCounterparts() != null && message.getCounterparts().size() > 0)) {
 					showAvatar = true;
-					loadAvatar(message, viewHolder.contact_picture, activity.getPixel(32));
+					AvatarWorkerTask.loadAvatar(message, viewHolder.contact_picture, R.dimen.avatar_on_status_message);
 				} else {
 					showAvatar = false;
 				}
@@ -720,7 +684,7 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 			}
 			return view;
 		} else {
-			loadAvatar(message, viewHolder.contact_picture, activity.getPixel(48));
+			AvatarWorkerTask.loadAvatar(message, viewHolder.contact_picture, R.dimen.avatar);
 		}
 
 		resetClickListener(viewHolder.message_box, viewHolder.messageBody);
@@ -918,32 +882,6 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 		this.mUseGreenBackground = p.getBoolean("use_green_background", activity.getResources().getBoolean(R.bool.use_green_background));
 	}
 
-	private void loadAvatar(Message message, ImageView imageView, int size) {
-		if (cancelPotentialWork(message, imageView)) {
-			final Bitmap bm = activity.avatarService().get(message, size, true);
-			if (bm != null) {
-				cancelPotentialWork(message, imageView);
-				imageView.setImageBitmap(bm);
-				imageView.setBackgroundColor(Color.TRANSPARENT);
-			} else {
-				@ColorInt int bg;
-				if (message.getType() == Message.TYPE_STATUS && message.getCounterparts() != null && message.getCounterparts().size() > 1) {
-					bg = Color.TRANSPARENT;
-				} else {
-					bg = UIHelper.getColorForName(UIHelper.getMessageDisplayName(message));
-				}
-				imageView.setBackgroundColor(bg);
-				imageView.setImageDrawable(null);
-				final BitmapWorkerTask task = new BitmapWorkerTask(imageView, size);
-				final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
-				imageView.setImageDrawable(asyncDrawable);
-				try {
-					task.execute(message);
-				} catch (final RejectedExecutionException ignored) {
-				}
-			}
-		}
-	}
 
 	public void setHighlightedTerm(List<String> terms) {
 		this.highlightedTerm = terms == null ? null : StylingHelper.filterHighlightedWords(terms);
@@ -978,18 +916,6 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 		protected TextView encryption;
 	}
 
-	static class AsyncDrawable extends BitmapDrawable {
-		private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
-
-		public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) {
-			super(res, bitmap);
-			bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
-		}
-
-		public BitmapWorkerTask getBitmapWorkerTask() {
-			return bitmapWorkerTaskReference.get();
-		}
-	}
 
 	private class MessageBodyActionModeCallback implements ActionMode.Callback {
 
@@ -1036,36 +962,4 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 		public void onDestroyActionMode(ActionMode mode) {
 		}
 	}
-
-	private static class BitmapWorkerTask extends AsyncTask<Message, Void, Bitmap> {
-		private final WeakReference<ImageView> imageViewReference;
-		private final int size;
-		private Message message = null;
-
-		BitmapWorkerTask(ImageView imageView, int size) {
-			imageViewReference = new WeakReference<>(imageView);
-			this.size = size;
-		}
-
-		@Override
-		protected Bitmap doInBackground(Message... params) {
-			this.message = params[0];
-			final XmppActivity activity = XmppActivity.find(imageViewReference);
-			if (activity == null) {
-				return null;
-			}
-			return activity.avatarService().get(this.message, size, isCancelled());
-		}
-
-		@Override
-		protected void onPostExecute(Bitmap bitmap) {
-			if (bitmap != null && !isCancelled()) {
-				final ImageView imageView = imageViewReference.get();
-				if (imageView != null) {
-					imageView.setImageBitmap(bitmap);
-					imageView.setBackgroundColor(0x00000000);
-				}
-			}
-		}
-	}
 }

src/main/java/eu/siacs/conversations/ui/util/AvatarWorkerTask.java 🔗

@@ -0,0 +1,113 @@
+package eu.siacs.conversations.ui.util;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
+import android.support.annotation.DimenRes;
+import android.widget.ImageView;
+
+import java.lang.ref.WeakReference;
+import java.util.concurrent.RejectedExecutionException;
+
+import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.services.AvatarService;
+import eu.siacs.conversations.ui.XmppActivity;
+import eu.siacs.conversations.ui.adapter.AccountAdapter;
+import eu.siacs.conversations.utils.UIHelper;
+
+public class AvatarWorkerTask extends AsyncTask<AvatarService.Avatarable, Void, Bitmap> {
+    private final WeakReference<ImageView> imageViewReference;
+    private AvatarService.Avatarable avatarable = null;
+    private @DimenRes int size;
+
+    public AvatarWorkerTask(ImageView imageView, @DimenRes int size) {
+        imageViewReference = new WeakReference<>(imageView);
+        this.size = size;
+    }
+
+    @Override
+    protected Bitmap doInBackground(AvatarService.Avatarable... params) {
+        this.avatarable = params[0];
+        final XmppActivity activity = XmppActivity.find(imageViewReference);
+        if (activity == null) {
+            return null;
+        }
+        return activity.avatarService().get(avatarable, (int) activity.getResources().getDimension(size), isCancelled());
+    }
+
+    @Override
+    protected void onPostExecute(Bitmap bitmap) {
+        if (bitmap != null && !isCancelled()) {
+            final ImageView imageView = imageViewReference.get();
+            if (imageView != null) {
+                imageView.setImageBitmap(bitmap);
+                imageView.setBackgroundColor(0x00000000);
+            }
+        }
+    }
+
+    public static boolean cancelPotentialWork(AvatarService.Avatarable avatarable, ImageView imageView) {
+        final AvatarWorkerTask workerTask = getBitmapWorkerTask(imageView);
+
+        if (workerTask != null) {
+            final AvatarService.Avatarable old= workerTask.avatarable;
+            if (old == null || avatarable != old) {
+                workerTask.cancel(true);
+            } else {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static AvatarWorkerTask getBitmapWorkerTask(ImageView imageView) {
+        if (imageView != null) {
+            final Drawable drawable = imageView.getDrawable();
+            if (drawable instanceof AsyncDrawable) {
+                final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
+                return asyncDrawable.getAvatarWorkerTask();
+            }
+        }
+        return null;
+    }
+
+    public static void loadAvatar(final AvatarService.Avatarable avatarable, final ImageView imageView, final @DimenRes int size) {
+        if (cancelPotentialWork(avatarable, imageView)) {
+            final XmppActivity activity = XmppActivity.find(imageView);
+            if (activity == null) {
+                return;
+            }
+            final Bitmap bm = activity.avatarService().get(avatarable, (int) activity.getResources().getDimension(size), true);
+            if (bm != null) {
+                cancelPotentialWork(avatarable, imageView);
+                imageView.setImageBitmap(bm);
+                imageView.setBackgroundColor(0x00000000);
+            } else {
+                imageView.setBackgroundColor(avatarable.getAvatarBackgroundColor());
+                imageView.setImageDrawable(null);
+                final AvatarWorkerTask task = new AvatarWorkerTask(imageView, size);
+                final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task);
+                imageView.setImageDrawable(asyncDrawable);
+                try {
+                    task.execute(avatarable);
+                } catch (final RejectedExecutionException ignored) {
+                }
+            }
+        }
+    }
+
+    static class AsyncDrawable extends BitmapDrawable {
+        private final WeakReference<AvatarWorkerTask> avatarWorkerTaskReference;
+
+        AsyncDrawable(Resources res, Bitmap bitmap, AvatarWorkerTask workerTask) {
+            super(res, bitmap);
+            avatarWorkerTaskReference = new WeakReference<>(workerTask);
+        }
+
+        AvatarWorkerTask getAvatarWorkerTask() {
+            return avatarWorkerTaskReference.get();
+        }
+    }
+}

src/main/res/values/dimens.xml 🔗

@@ -18,7 +18,10 @@
 
 	<dimen name="publish_avatar_top_margin">8dp</dimen>
 	<dimen name="publish_avatar_size">96dp</dimen>
+	<dimen name="avatar_on_status_message">32dp</dimen>
+	<dimen name="avatar">48dp</dimen>
 	<dimen name="avatar_on_details_screen_size">56dp</dimen>
+	<dimen name="avatar_on_conversation_overview">56dp</dimen>
 
 	<dimen name="input_label_vertical_spacing">4dp</dimen>
 	<dimen name="input_label_horizontal_spacing">4dp</dimen>