~singpolyma/cheogram-android

85df7b7c242c51ce14e6bfc3693f2a9a4ad490a1 — Stephen Paul Weber 11 months ago 65744ae
Move whole avatar stack from Bitmap to Drawable
M src/cheogram/java/com/cheogram/android/ConnectionService.java => src/cheogram/java/com/cheogram/android/ConnectionService.java +3 -2
@@ 44,6 44,7 @@ import io.michaelrocks.libphonenumber.android.NumberParseException;

import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.services.AppRTCAudioManager;
import eu.siacs.conversations.services.AvatarService;
import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder;


@@ 215,11 216,11 @@ public class ConnectionService extends android.telecom.ConnectionService {
			this.account = account;
			this.with = with;

			gatewayIcon = Icon.createWithBitmap(xmppConnectionService.getAvatarService().get(
			gatewayIcon = Icon.createWithBitmap(FileBackend.drawDrawable(xmppConnectionService.getAvatarService().get(
				account.getRoster().getContact(Jid.of(with.getDomain())),
				AvatarService.getSystemUiAvatarSize(xmppConnectionService),
				false
			));
			)));

			if (postDialString != null) {
				for (int i = postDialString.length() - 1; i >= 0; i--) {

M src/cheogram/java/eu/siacs/conversations/ui/adapter/BackupFileAdapter.java => src/cheogram/java/eu/siacs/conversations/ui/adapter/BackupFileAdapter.java +5 -5
@@ 86,7 86,7 @@ public class BackupFileAdapter extends RecyclerView.Adapter<BackupFileAdapter.Ba
        void onClick(ImportBackupService.BackupFile backupFile);
    }

    static class BitmapWorkerTask extends AsyncTask<Jid, Void, Bitmap> {
    static class BitmapWorkerTask extends AsyncTask<Jid, Void, Drawable> {
        private final WeakReference<ImageView> imageViewReference;
        private Jid jid  = null;
        private final int size;


@@ 98,17 98,17 @@ public class BackupFileAdapter extends RecyclerView.Adapter<BackupFileAdapter.Ba
        }

        @Override
        protected Bitmap doInBackground(Jid... params) {
        protected Drawable doInBackground(Jid... params) {
            this.jid = params[0];
            return AvatarService.get(this.jid, size);
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
        protected void onPostExecute(Drawable bitmap) {
            if (bitmap != null && !isCancelled()) {
                final ImageView imageView = imageViewReference.get();
                if (imageView != null) {
                    imageView.setImageBitmap(bitmap);
                    imageView.setImageDrawable(bitmap);
                    imageView.setBackgroundColor(0x00000000);
                }
            }


@@ 167,4 167,4 @@ public class BackupFileAdapter extends RecyclerView.Adapter<BackupFileAdapter.Ba
        }
    }

}
\ No newline at end of file
}

M src/main/java/eu/siacs/conversations/entities/Contact.java => src/main/java/eu/siacs/conversations/entities/Contact.java +2 -1
@@ 35,6 35,7 @@ import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.android.AbstractPhoneContact;
import eu.siacs.conversations.android.JabberIdContact;
import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.services.AvatarService;
import eu.siacs.conversations.services.QuickConversationsService;
import eu.siacs.conversations.services.XmppConnectionService;


@@ 680,7 681,7 @@ public class Contact implements ListItem, Blockable {
        ).setAddress(
            Uri.fromParts("xmpp", account.getJid().asBareJid().toString(), null)
        ).setIcon(
            Icon.createWithBitmap(ctx.getAvatarService().get(this, AvatarService.getSystemUiAvatarSize(ctx) / 2, false))
            Icon.createWithBitmap(FileBackend.drawDrawable(ctx.getAvatarService().get(this, AvatarService.getSystemUiAvatarSize(ctx) / 2, false)))
        ).setHighlightColor(
            0x7401CF
        ).setShortDescription(

M src/main/java/eu/siacs/conversations/persistance/FileBackend.java => src/main/java/eu/siacs/conversations/persistance/FileBackend.java +5 -3
@@ 1293,7 1293,9 @@ public class FileBackend {
        }
    }

    protected Bitmap drawDrawable(Drawable drawable) {
    public static Bitmap drawDrawable(Drawable drawable) {
        if (drawable == null) return null;

        Bitmap bitmap = null;

        if (drawable instanceof BitmapDrawable) {


@@ 2001,12 2003,12 @@ public class FileBackend {
        return new Dimensions(h, w);
    }

    public Bitmap getAvatar(String avatar, int size) {
    public Drawable getAvatar(String avatar, int size) {
        if (avatar == null) {
            return null;
        }
        Bitmap bm = cropCenter(getAvatarUri(avatar), size, size);
        return bm;
        return new BitmapDrawable(bm);
    }

    private static class Dimensions {

M src/main/java/eu/siacs/conversations/services/AvatarService.java => src/main/java/eu/siacs/conversations/services/AvatarService.java +40 -39
@@ 39,6 39,7 @@ import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.entities.MucOptions;
import eu.siacs.conversations.entities.RawBlockable;
import eu.siacs.conversations.entities.Room;
import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.Jid;
import eu.siacs.conversations.xmpp.OnAdvancedStreamFeaturesLoaded;


@@ 72,7 73,7 @@ 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) {
	public Drawable 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) {


@@ 90,7 91,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {

	}

	private Bitmap get(final Room result, final int size, boolean cacheOnly) {
	private Drawable get(final Room result, final int size, boolean cacheOnly) {
		final Jid room = result.getRoom();
		Conversation conversation = room != null ? mXmppConnectionService.findFirstMuc(room) : null;
		if (conversation != null) {


@@ 99,12 100,12 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
		return get(CHANNEL_SYMBOL, room != null ? room.asBareJid().toEscapedString() : result.getName(), size, cacheOnly);
	}

	private Bitmap get(final Contact contact, final int size, boolean cachedOnly) {
	private Drawable get(final Contact contact, final int size, boolean cachedOnly) {
		if (contact.isSelf()) {
			return get(contact.getAccount(), size, cachedOnly);
		}
		final String KEY = key(contact, size);
		Bitmap avatar = this.mXmppConnectionService.getBitmapCache().get(KEY);
		Drawable avatar = this.mXmppConnectionService.getDrawableCache().get(KEY);
		if (avatar != null || cachedOnly) {
			return avatar;
		}


@@ 112,7 113,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
			avatar = mXmppConnectionService.getFileBackend().getAvatar(contact.getAvatarFilename(), size);
		}
		if (avatar == null && contact.getProfilePhoto() != null) {
			avatar = mXmppConnectionService.getFileBackend().cropCenterSquare(Uri.parse(contact.getProfilePhoto()), size);
			avatar = new BitmapDrawable(mXmppConnectionService.getFileBackend().cropCenterSquare(Uri.parse(contact.getProfilePhoto()), size));
		}
		if (avatar == null && contact.getAvatarFilename() != null) {
			avatar = mXmppConnectionService.getFileBackend().getAvatar(contact.getAvatarFilename(), size);


@@ 120,7 121,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
		if (avatar == null) {
			avatar = get(contact.getDisplayName(), contact.getJid().asBareJid().toString(), size, false);
		}
		this.mXmppConnectionService.getBitmapCache().put(KEY, avatar);
		this.mXmppConnectionService.getDrawableCache().put(KEY, avatar);
		return avatar;
	}



@@ 135,7 136,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
	private Bitmap getRoundedShortcut(final Contact contact, boolean withIcon) {
		DisplayMetrics metrics = mXmppConnectionService.getResources().getDisplayMetrics();
		int size = Math.round(metrics.density * 48);
		Bitmap bitmap = get(contact, size);
		Bitmap bitmap = FileBackend.drawDrawable(get(contact, size));
		Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(output);
		final Paint paint = new Paint();


@@ 191,7 192,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
		return bitmap;
	}

	public Bitmap get(final MucOptions.User user, final int size, boolean cachedOnly) {
	public Drawable get(final MucOptions.User user, final int size, boolean cachedOnly) {
		Contact c = user.getContact();
		if (c != null && (c.getProfilePhoto() != null || c.getAvatarFilename() != null || user.getAvatar() == null)) {
			return get(c, size, cachedOnly);


@@ 200,9 201,9 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
		}
	}

	private Bitmap getImpl(final MucOptions.User user, final int size, boolean cachedOnly) {
	private Drawable getImpl(final MucOptions.User user, final int size, boolean cachedOnly) {
		final String KEY = key(user, size);
		Bitmap avatar = this.mXmppConnectionService.getBitmapCache().get(KEY);
		Drawable avatar = this.mXmppConnectionService.getDrawableCache().get(KEY);
		if (avatar != null || cachedOnly) {
			return avatar;
		}


@@ 218,14 219,14 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
				avatar = get(user.getName(), seed, size, false);
			}
		}
		this.mXmppConnectionService.getBitmapCache().put(KEY, avatar);
		this.mXmppConnectionService.getDrawableCache().put(KEY, avatar);
		return avatar;
	}

	public void clear(Contact contact) {
		synchronized (this.sizes) {
			for (final Integer size : sizes) {
				this.mXmppConnectionService.getBitmapCache().remove(key(contact, size));
				this.mXmppConnectionService.getDrawableCache().remove(key(contact, size));
			}
		}
		for (Conversation conversation : mXmppConnectionService.findAllConferencesWith(contact)) {


@@ 265,11 266,11 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
				size;
	}

	public Bitmap get(ListItem item, int size) {
	public Drawable get(ListItem item, int size) {
		return get(item, size, false);
	}

	public Bitmap get(ListItem item, int size, boolean cachedOnly) {
	public Drawable get(ListItem item, int size, boolean cachedOnly) {
		if (item instanceof RawBlockable) {
			return get(item.getDisplayName(), item.getJid().toEscapedString(), size, cachedOnly);
		} else if (item instanceof Contact) {


@@ 294,11 295,11 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
		}
	}

	public Bitmap get(Conversation conversation, int size) {
	public Drawable get(Conversation conversation, int size) {
		return get(conversation, size, false);
	}

	public Bitmap get(Conversation conversation, int size, boolean cachedOnly) {
	public Drawable get(Conversation conversation, int size, boolean cachedOnly) {
		if (conversation.getMode() == Conversation.MODE_SINGLE) {
			return get(conversation.getContact(), size, cachedOnly);
		} else {


@@ 316,7 317,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
				if (keys == null) {
					return;
				}
				LruCache<String, Bitmap> cache = this.mXmppConnectionService.getBitmapCache();
				LruCache<String, Drawable> cache = this.mXmppConnectionService.getDrawableCache();
				for (String key : keys) {
					cache.remove(key);
				}


@@ 325,9 326,9 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
		}
	}

	private Bitmap get(MucOptions mucOptions, int size, boolean cachedOnly) {
	private Drawable get(MucOptions mucOptions, int size, boolean cachedOnly) {
		final String KEY = key(mucOptions, size);
		Bitmap bitmap = this.mXmppConnectionService.getBitmapCache().get(KEY);
		Drawable bitmap = this.mXmppConnectionService.getDrawableCache().get(KEY);
		if (bitmap != null || cachedOnly) {
			return bitmap;
		}


@@ 348,23 349,23 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
			}
		}

		this.mXmppConnectionService.getBitmapCache().put(KEY, bitmap);
		this.mXmppConnectionService.getDrawableCache().put(KEY, bitmap);

		return bitmap;
	}

	private Bitmap get(List<MucOptions.User> users, int size, boolean cachedOnly) {
	private Drawable get(List<MucOptions.User> users, int size, boolean cachedOnly) {
		final String KEY = key(users, size);
		Bitmap bitmap = this.mXmppConnectionService.getBitmapCache().get(KEY);
		Drawable bitmap = this.mXmppConnectionService.getDrawableCache().get(KEY);
		if (bitmap != null || cachedOnly) {
			return bitmap;
		}
		bitmap = getImpl(users, size);
		this.mXmppConnectionService.getBitmapCache().put(KEY, bitmap);
		this.mXmppConnectionService.getDrawableCache().put(KEY, bitmap);
		return bitmap;
	}

	private Bitmap getImpl(List<MucOptions.User> users, int size) {
	private Drawable getImpl(List<MucOptions.User> users, int size) {
		int count = users.size();
		Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(bitmap);


@@ 395,7 396,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
			drawTile(canvas, "\u2026", PLACEHOLDER_COLOR, size / 2 + 1, size / 2 + 1,
					size, size);
		}
		return bitmap;
		return new BitmapDrawable(bitmap);
	}

	public void clear(final MucOptions options) {


@@ 404,7 405,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
		}
		synchronized (this.sizes) {
			for (Integer size : sizes) {
				this.mXmppConnectionService.getBitmapCache().remove(key(options, size));
				this.mXmppConnectionService.getDrawableCache().remove(key(options, size));
			}
		}
	}


@@ 443,13 444,13 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
		return key;
	}

	public Bitmap get(Account account, int size) {
	public Drawable get(Account account, int size) {
		return get(account, size, false);
	}

	public Bitmap get(Account account, int size, boolean cachedOnly) {
	public Drawable get(Account account, int size, boolean cachedOnly) {
		final String KEY = key(account, size);
		Bitmap avatar = mXmppConnectionService.getBitmapCache().get(KEY);
		Drawable avatar = mXmppConnectionService.getDrawableCache().get(KEY);
		if (avatar != null || cachedOnly) {
			return avatar;
		}


@@ 463,11 464,11 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
				avatar = get(jid, null, size, false);
			}
		}
		mXmppConnectionService.getBitmapCache().put(KEY, avatar);
		mXmppConnectionService.getDrawableCache().put(KEY, avatar);
		return avatar;
	}

	public Bitmap get(Message message, int size, boolean cachedOnly) {
	public Drawable get(Message message, int size, boolean cachedOnly) {
		final Conversational conversation = message.getConversation();
		if (message.getType() == Message.TYPE_STATUS && message.getCounterparts() != null && message.getCounterparts().size() > 1) {
			return get(message.getCounterparts(), size, cachedOnly);


@@ 503,7 504,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
	public void clear(Account account) {
		synchronized (this.sizes) {
			for (Integer size : sizes) {
				this.mXmppConnectionService.getBitmapCache().remove(key(account, size));
				this.mXmppConnectionService.getDrawableCache().remove(key(account, size));
			}
		}
	}


@@ 511,7 512,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
	public void clear(MucOptions.User user) {
		synchronized (this.sizes) {
			for (Integer size : sizes) {
				this.mXmppConnectionService.getBitmapCache().remove(key(user, size));
				this.mXmppConnectionService.getDrawableCache().remove(key(user, size));
			}
		}
	}


@@ 528,27 529,27 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
		return get(name,null, size,false);
	}*/

	public Bitmap get(final String name, String seed, final int size, boolean cachedOnly) {
	public Drawable get(final String name, String seed, final int size, boolean cachedOnly) {
		final String KEY = key(seed == null ? name : name+"\0"+seed, size);
		Bitmap bitmap = mXmppConnectionService.getBitmapCache().get(KEY);
		Drawable bitmap = mXmppConnectionService.getDrawableCache().get(KEY);
		if (bitmap != null || cachedOnly) {
			return bitmap;
		}
		bitmap = getImpl(name, seed, size);
		mXmppConnectionService.getBitmapCache().put(KEY, bitmap);
		mXmppConnectionService.getDrawableCache().put(KEY, bitmap);
		return bitmap;
	}

	public static Bitmap get(final Jid jid, final int size) {
	public static Drawable get(final Jid jid, final int size) {
		return getImpl(jid.asBareJid().toEscapedString(), null, size);
	}

	private static Bitmap getImpl(final String name, final String seed, final int size) {
	private static Drawable getImpl(final String name, final String seed, final int size) {
		Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(bitmap);
		final String trimmedName = name == null ? "" : name.trim();
		drawTile(canvas, trimmedName, seed, 0, 0, size, size);
		return bitmap;
		return new BitmapDrawable(bitmap);
	}

	private String key(String name, int size) {

M src/main/java/eu/siacs/conversations/services/ContactChooserTargetService.java => src/main/java/eu/siacs/conversations/services/ContactChooserTargetService.java +3 -2
@@ 21,6 21,7 @@ import java.util.List;

import eu.siacs.conversations.Config;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.ui.ConversationsActivity;
import eu.siacs.conversations.utils.Compatibility;



@@ 69,8 70,8 @@ public class ContactChooserTargetService extends ChooserTargetService implements
                }
                final String name = conversation.getName().toString();
                final Icon icon =
                        Icon.createWithBitmap(
                                mXmppConnectionService.getAvatarService().get(conversation, pixel));
                        Icon.createWithBitmap(FileBackend.drawDrawable(
                                mXmppConnectionService.getAvatarService().get(conversation, pixel)));
                final float score = 1 - (1.0f / MAX_TARGETS) * chooserTargets.size();
                final Bundle extras = new Bundle();
                extras.putString(ConversationsActivity.EXTRA_CONVERSATION, conversation.getUuid());

M src/main/java/eu/siacs/conversations/services/NotificationService.java => src/main/java/eu/siacs/conversations/services/NotificationService.java +12 -12
@@ 660,10 660,10 @@ public class NotificationService {
                    mXmppConnectionService.getString(R.string.rtp_state_incoming_call));
        }
        builder.setStyle(style);
        builder.setLargeIcon(
        builder.setLargeIcon(FileBackend.drawDrawable(
                mXmppConnectionService
                        .getAvatarService()
                        .get(contact, AvatarService.getSystemUiAvatarSize(mXmppConnectionService)));
                        .get(contact, AvatarService.getSystemUiAvatarSize(mXmppConnectionService))));
        final Uri systemAccount = contact.getSystemAccount();
        if (systemAccount != null) {
            builder.addPerson(systemAccount.toString());


@@ 1150,12 1150,12 @@ public class NotificationService {
        builder.setContentIntent(createContentIntent(conversation));
        builder.setDeleteIntent(createMissedCallsDeleteIntent(conversation));
        if (!publicVersion && conversation instanceof Conversation) {
            builder.setLargeIcon(
            builder.setLargeIcon(FileBackend.drawDrawable(
                    mXmppConnectionService
                            .getAvatarService()
                            .get(
                                    (Conversation) conversation,
                                    AvatarService.getSystemUiAvatarSize(mXmppConnectionService)));
                                    AvatarService.getSystemUiAvatarSize(mXmppConnectionService))));
        }
        modifyMissedCall(builder, conversation.getAccount());
        return builder;


@@ 1250,12 1250,12 @@ public class NotificationService {
                        quietHours ? "quiet_hours" : (notify ? "messages" : "silent_messages"));
        if (messages.size() >= 1) {
            final Conversation conversation = (Conversation) messages.get(0).getConversation();
            mBuilder.setLargeIcon(
            mBuilder.setLargeIcon(FileBackend.drawDrawable(
                    mXmppConnectionService
                            .getAvatarService()
                            .get(
                                    conversation,
                                    AvatarService.getSystemUiAvatarSize(mXmppConnectionService)));
                                    AvatarService.getSystemUiAvatarSize(mXmppConnectionService))));
            mBuilder.setContentTitle(conversation.getName());
            if (Config.HIDE_MESSAGE_TEXT_IN_NOTIFICATION) {
                int count = messages.size();


@@ 1446,14 1446,14 @@ public class NotificationService {
                builder.setImportant(c.getBooleanAttribute(Conversation.ATTRIBUTE_PINNED_ON_TOP, false));
            }
            builder.setIcon(
                    IconCompat.createWithBitmap(
                    IconCompat.createWithBitmap(FileBackend.drawDrawable(
                            mXmppConnectionService
                                    .getAvatarService()
                                    .get(
                                            message,
                                            AvatarService.getSystemUiAvatarSize(
                                                    mXmppConnectionService),
                                            false)));
                                            false))));
        }
        return builder.build();
    }


@@ 1473,14 1473,14 @@ public class NotificationService {
                builder.setImportant(c.getBooleanAttribute(Conversation.ATTRIBUTE_PINNED_ON_TOP, false));
            }
            builder.setIcon(
                    IconCompat.createWithBitmap(
                    IconCompat.createWithBitmap(FileBackend.drawDrawable(
                            mXmppConnectionService
                                    .getAvatarService()
                                    .get(
                                            contact,
                                            AvatarService.getSystemUiAvatarSize(
                                                    mXmppConnectionService),
                                            false)));
                                            false))));
        }
        return builder.build();
    }


@@ 1492,13 1492,13 @@ public class NotificationService {
                    new Person.Builder().setName(mXmppConnectionService.getString(R.string.me));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                meBuilder.setIcon(
                        IconCompat.createWithBitmap(
                        IconCompat.createWithBitmap(FileBackend.drawDrawable(
                                mXmppConnectionService
                                        .getAvatarService()
                                        .get(
                                                conversation.getAccount(),
                                                AvatarService.getSystemUiAvatarSize(
                                                        mXmppConnectionService))));
                                                        mXmppConnectionService)))));
            }
            final Person me = meBuilder.build();
            NotificationCompat.MessagingStyle messagingStyle =

M src/main/java/eu/siacs/conversations/ui/PublishGroupChatProfilePictureActivity.java => src/main/java/eu/siacs/conversations/ui/PublishGroupChatProfilePictureActivity.java +5 -3
@@ 31,6 31,8 @@ package eu.siacs.conversations.ui;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;


@@ 76,14 78,14 @@ public class PublishGroupChatProfilePictureActivity extends XmppActivity impleme

    private void reloadAvatar() {
        final int size = (int) getResources().getDimension(R.dimen.publish_avatar_size);
        Bitmap bitmap;
        Drawable bitmap;
        if (uri == null) {
            bitmap = xmppConnectionService.getAvatarService().get(conversation, size);
        } else {
            Log.d(Config.LOGTAG, "loading " + uri.toString() + " into preview");
            bitmap = xmppConnectionService.getFileBackend().cropCenterSquare(uri, size);
            bitmap = new BitmapDrawable(xmppConnectionService.getFileBackend().cropCenterSquare(uri, size));
        }
        this.binding.accountImage.setImageBitmap(bitmap);
        this.binding.accountImage.setImageDrawable(bitmap);
        this.binding.publishButton.setEnabled(uri != null);
    }


M src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java => src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java +5 -3
@@ 2,6 2,8 @@ package eu.siacs.conversations.ui;

import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;


@@ 244,12 246,12 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC

    protected void loadImageIntoPreview(Uri uri) {

        Bitmap bm = null;
        Drawable bm = null;
        if (uri == null) {
            bm = avatarService().get(account, (int) getResources().getDimension(R.dimen.publish_avatar_size));
        } else {
            try {
                bm = xmppConnectionService.getFileBackend().cropCenterSquare(uri, (int) getResources().getDimension(R.dimen.publish_avatar_size));
                bm = new BitmapDrawable(xmppConnectionService.getFileBackend().cropCenterSquare(uri, (int) getResources().getDimension(R.dimen.publish_avatar_size)));
            } catch (Exception e) {
                Log.d(Config.LOGTAG, "unable to load bitmap into image view", e);
            }


@@ 262,7 264,7 @@ public class PublishProfilePictureActivity extends XmppActivity implements XmppC
            this.hintOrWarning.setText(R.string.error_publish_avatar_converting);
            return;
        }
        this.avatar.setImageBitmap(bm);
        this.avatar.setImageDrawable(bm);
        if (support) {
            togglePublishButton(uri != null, R.string.publish);
            this.hintOrWarning.setVisibility(View.INVISIBLE);

M src/main/java/eu/siacs/conversations/ui/util/AvatarWorkerTask.java => src/main/java/eu/siacs/conversations/ui/util/AvatarWorkerTask.java +14 -6
@@ 3,9 3,11 @@ package eu.siacs.conversations.ui.util;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.AnimatedImageDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.widget.ImageView;

import androidx.annotation.DimenRes;


@@ 18,7 20,7 @@ import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.services.AvatarService;
import eu.siacs.conversations.ui.XmppActivity;

public class AvatarWorkerTask extends AsyncTask<AvatarService.Avatarable, Void, Bitmap> {
public class AvatarWorkerTask extends AsyncTask<AvatarService.Avatarable, Void, Drawable> {
    private final WeakReference<ImageView> imageViewReference;
    private AvatarService.Avatarable avatarable = null;
    private @DimenRes


@@ 30,7 32,7 @@ public class AvatarWorkerTask extends AsyncTask<AvatarService.Avatarable, Void, 
    }

    @Override
    protected Bitmap doInBackground(AvatarService.Avatarable... params) {
    protected Drawable doInBackground(AvatarService.Avatarable... params) {
        this.avatarable = params[0];
        final XmppActivity activity = XmppActivity.find(imageViewReference);
        if (activity == null) {


@@ 40,12 42,15 @@ public class AvatarWorkerTask extends AsyncTask<AvatarService.Avatarable, Void, 
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
    protected void onPostExecute(Drawable bitmap) {
        if (bitmap != null && !isCancelled()) {
            final ImageView imageView = imageViewReference.get();
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
                imageView.setImageDrawable(bitmap);
                imageView.setBackgroundColor(0x00000000);
                if (Build.VERSION.SDK_INT >= 28 && bitmap instanceof AnimatedImageDrawable) {
                    ((AnimatedImageDrawable) bitmap).start();
                }
            }
        }
    }


@@ 81,12 86,15 @@ public class AvatarWorkerTask extends AsyncTask<AvatarService.Avatarable, Void, 
            if (activity == null) {
                return;
            }
            final Bitmap bm = activity.avatarService().get(avatarable, (int) activity.getResources().getDimension(size), true);
            final Drawable bm = activity.avatarService().get(avatarable, (int) activity.getResources().getDimension(size), true);
            setContentDescription(avatarable, imageView);
            if (bm != null) {
                cancelPotentialWork(avatarable, imageView);
                imageView.setImageBitmap(bm);
                imageView.setImageDrawable(bm);
                imageView.setBackgroundColor(0x00000000);
                if (Build.VERSION.SDK_INT >= 28 && bm instanceof AnimatedImageDrawable) {
                    ((AnimatedImageDrawable) bm).start();
                }
            } else {
                imageView.setBackgroundColor(avatarable.getAvatarBackgroundColor());
                imageView.setImageDrawable(null);

M src/main/res/layout/message_sent.xml => src/main/res/layout/message_sent.xml +7 -25
@@ 10,34 10,16 @@
    android:paddingRight="8dp"
    android:paddingBottom="3dp">

    <RelativeLayout
        android:id="@+id/message_photo_box"
    <com.google.android.material.imageview.ShapeableImageView
        android:id="@+id/message_photo"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <com.google.android.material.imageview.ShapeableImageView
                android:id="@+id/message_photo"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="fitXY"
                app:strokeColor="@color/custom_theme_accent"
                app:shapeAppearance="@style/ShapeAppearanceOverlay.Photo" />

            <View
                android:id="@+id/placeholder"
                android:layout_width="match_parent"
                android:layout_height="3dp" />
        </LinearLayout>

    </RelativeLayout>
        android:layout_alignParentBottom="true"
        android:scaleType="fitXY"
        app:strokeColor="@color/custom_theme_accent"
        app:shapeAppearance="@style/ShapeAppearanceOverlay.Photo" />

    <LinearLayout
        android:id="@+id/message_box"


@@ 48,7 30,7 @@
        android:paddingRight="20dp"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"
        android:layout_toLeftOf="@+id/message_photo_box"
        android:layout_toLeftOf="@+id/message_photo"
        android:elevation="3dp"
        android:background="@drawable/message_bubble_sent"
        android:longClickable="true"