proper avatar caching
This commit is contained in:
		
							parent
							
								
									21961673cb
								
							
						
					
					
						commit
						0d767c3971
					
				| @ -348,10 +348,14 @@ public class MessageParser extends AbstractParser implements | ||||
| 								mXmppConnectionService.databaseBackend | ||||
| 										.updateAccount(account); | ||||
| 							} | ||||
| 							mXmppConnectionService.getAvatarService().clear( | ||||
| 									account); | ||||
| 						} else { | ||||
| 							Contact contact = account.getRoster().getContact( | ||||
| 									from); | ||||
| 							contact.setAvatar(avatar.getFilename()); | ||||
| 							mXmppConnectionService.getAvatarService().clear( | ||||
| 									contact); | ||||
| 						} | ||||
| 					} else { | ||||
| 						mXmppConnectionService.fetchAvatar(account, avatar); | ||||
|  | ||||
| @ -29,6 +29,7 @@ public class PresenceParser extends AbstractParser implements | ||||
| 				if (before != muc.getMucOptions().online()) { | ||||
| 					mXmppConnectionService.updateConversationUi(); | ||||
| 				} | ||||
| 				mXmppConnectionService.getAvatarService().clear(muc); | ||||
| 			} | ||||
| 		} else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) { | ||||
| 			Conversation muc = mXmppConnectionService.find(account, packet | ||||
| @ -39,6 +40,7 @@ public class PresenceParser extends AbstractParser implements | ||||
| 				if (before != muc.getMucOptions().online()) { | ||||
| 					mXmppConnectionService.updateConversationUi(); | ||||
| 				} | ||||
| 				mXmppConnectionService.getAvatarService().clear(muc); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -14,7 +14,6 @@ import java.text.SimpleDateFormat; | ||||
| import java.util.Date; | ||||
| import java.util.Locale; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| import android.database.Cursor; | ||||
| import android.graphics.Bitmap; | ||||
| import android.graphics.BitmapFactory; | ||||
| @ -28,12 +27,12 @@ import android.provider.MediaStore; | ||||
| import android.util.Base64; | ||||
| import android.util.Base64OutputStream; | ||||
| import android.util.Log; | ||||
| import android.util.LruCache; | ||||
| import eu.siacs.conversations.Config; | ||||
| import eu.siacs.conversations.R; | ||||
| import eu.siacs.conversations.entities.Conversation; | ||||
| import eu.siacs.conversations.entities.DownloadableFile; | ||||
| import eu.siacs.conversations.entities.Message; | ||||
| import eu.siacs.conversations.services.XmppConnectionService; | ||||
| import eu.siacs.conversations.utils.CryptoHelper; | ||||
| import eu.siacs.conversations.xmpp.pep.Avatar; | ||||
| 
 | ||||
| @ -41,27 +40,13 @@ public class FileBackend { | ||||
| 
 | ||||
| 	private static int IMAGE_SIZE = 1920; | ||||
| 
 | ||||
| 	private Context context; | ||||
| 	private LruCache<String, Bitmap> thumbnailCache; | ||||
| 
 | ||||
| 	private SimpleDateFormat imageDateFormat = new SimpleDateFormat( | ||||
| 			"yyyyMMdd_HHmmssSSS", Locale.US); | ||||
| 
 | ||||
| 	public FileBackend(Context context) { | ||||
| 		this.context = context; | ||||
| 		int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); | ||||
| 		int cacheSize = maxMemory / 8; | ||||
| 		thumbnailCache = new LruCache<String, Bitmap>(cacheSize) { | ||||
| 			@Override | ||||
| 			protected int sizeOf(String key, Bitmap bitmap) { | ||||
| 				return bitmap.getByteCount() / 1024; | ||||
| 			} | ||||
| 		}; | ||||
| 	private XmppConnectionService mXmppConnectionService; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public LruCache<String, Bitmap> getThumbnailCache() { | ||||
| 		return thumbnailCache; | ||||
| 	public FileBackend(XmppConnectionService service) { | ||||
| 		this.mXmppConnectionService = service; | ||||
| 	} | ||||
| 
 | ||||
| 	public DownloadableFile getFile(Message message) { | ||||
| @ -127,7 +112,7 @@ public class FileBackend { | ||||
| 	private DownloadableFile copyImageToPrivateStorage(Message message, | ||||
| 			Uri image, int sampleSize) throws ImageCopyException { | ||||
| 		try { | ||||
| 			InputStream is = context.getContentResolver() | ||||
| 			InputStream is = mXmppConnectionService.getContentResolver() | ||||
| 					.openInputStream(image); | ||||
| 			DownloadableFile file = getFile(message); | ||||
| 			file.getParentFile().mkdirs(); | ||||
| @ -182,7 +167,7 @@ public class FileBackend { | ||||
| 	private int getRotation(Uri image) { | ||||
| 		if ("content".equals(image.getScheme())) { | ||||
| 			try { | ||||
| 				Cursor cursor = context | ||||
| 				Cursor cursor = mXmppConnectionService | ||||
| 						.getContentResolver() | ||||
| 						.query(image, | ||||
| 								new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, | ||||
| @ -223,7 +208,8 @@ public class FileBackend { | ||||
| 
 | ||||
| 	public Bitmap getThumbnail(Message message, int size, boolean cacheOnly) | ||||
| 			throws FileNotFoundException { | ||||
| 		Bitmap thumbnail = thumbnailCache.get(message.getUuid()); | ||||
| 		Bitmap thumbnail = mXmppConnectionService.getBitmapCache().get( | ||||
| 				message.getUuid()); | ||||
| 		if ((thumbnail == null) && (!cacheOnly)) { | ||||
| 			File file = getFile(message); | ||||
| 			BitmapFactory.Options options = new BitmapFactory.Options(); | ||||
| @ -234,13 +220,14 @@ public class FileBackend { | ||||
| 				throw new FileNotFoundException(); | ||||
| 			} | ||||
| 			thumbnail = resize(fullsize, size); | ||||
| 			this.thumbnailCache.put(message.getUuid(), thumbnail); | ||||
| 			this.mXmppConnectionService.getBitmapCache().put(message.getUuid(), | ||||
| 					thumbnail); | ||||
| 		} | ||||
| 		return thumbnail; | ||||
| 	} | ||||
| 
 | ||||
| 	public void removeFiles(Conversation conversation) { | ||||
| 		String prefix = context.getFilesDir().getAbsolutePath(); | ||||
| 		String prefix = mXmppConnectionService.getFilesDir().getAbsolutePath(); | ||||
| 		String path = prefix + "/" + conversation.getAccount().getJid() + "/" | ||||
| 				+ conversation.getContactJid(); | ||||
| 		File file = new File(path); | ||||
| @ -345,7 +332,8 @@ public class FileBackend { | ||||
| 	} | ||||
| 
 | ||||
| 	public String getAvatarPath(String avatar) { | ||||
| 		return context.getFilesDir().getAbsolutePath() + "/avatars/" + avatar; | ||||
| 		return mXmppConnectionService.getFilesDir().getAbsolutePath() | ||||
| 				+ "/avatars/" + avatar; | ||||
| 	} | ||||
| 
 | ||||
| 	public Uri getAvatarUri(String avatar) { | ||||
| @ -356,7 +344,7 @@ public class FileBackend { | ||||
| 		try { | ||||
| 			BitmapFactory.Options options = new BitmapFactory.Options(); | ||||
| 			options.inSampleSize = calcSampleSize(image, size); | ||||
| 			InputStream is = context.getContentResolver() | ||||
| 			InputStream is = mXmppConnectionService.getContentResolver() | ||||
| 					.openInputStream(image); | ||||
| 			Bitmap input = BitmapFactory.decodeStream(is, null, options); | ||||
| 			if (input == null) { | ||||
| @ -378,7 +366,7 @@ public class FileBackend { | ||||
| 			BitmapFactory.Options options = new BitmapFactory.Options(); | ||||
| 			options.inSampleSize = calcSampleSize(image, | ||||
| 					Math.max(newHeight, newWidth)); | ||||
| 			InputStream is = context.getContentResolver() | ||||
| 			InputStream is = mXmppConnectionService.getContentResolver() | ||||
| 					.openInputStream(image); | ||||
| 			Bitmap source = BitmapFactory.decodeStream(is, null, options); | ||||
| 
 | ||||
| @ -428,7 +416,7 @@ public class FileBackend { | ||||
| 			throws FileNotFoundException { | ||||
| 		BitmapFactory.Options options = new BitmapFactory.Options(); | ||||
| 		options.inJustDecodeBounds = true; | ||||
| 		BitmapFactory.decodeStream(context.getContentResolver() | ||||
| 		BitmapFactory.decodeStream(mXmppConnectionService.getContentResolver() | ||||
| 				.openInputStream(image), null, options); | ||||
| 		return calcSampleSize(options, size); | ||||
| 	} | ||||
|  | ||||
| @ -1,8 +1,10 @@ | ||||
| package eu.siacs.conversations.services; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Locale; | ||||
| 
 | ||||
| import eu.siacs.conversations.Config; | ||||
| import eu.siacs.conversations.entities.Account; | ||||
| import eu.siacs.conversations.entities.Bookmark; | ||||
| import eu.siacs.conversations.entities.Contact; | ||||
| @ -15,20 +17,34 @@ import android.graphics.Paint; | ||||
| import android.graphics.Rect; | ||||
| import android.graphics.Typeface; | ||||
| import android.net.Uri; | ||||
| import android.util.Log; | ||||
| 
 | ||||
| public class AvatarService { | ||||
| 
 | ||||
| 	private static final int FG_COLOR = 0xFFFAFAFA; | ||||
| 	private static final int TRANSPARENT = 0x00000000; | ||||
| 
 | ||||
| 	private static final String PREFIX_CONTACT = "contact"; | ||||
| 	private static final String PREFIX_CONVERSATION = "conversation"; | ||||
| 	private static final String PREFIX_ACCOUNT = "account"; | ||||
| 	private static final String PREFIX_GENERIC = "generic"; | ||||
| 
 | ||||
| 	private ArrayList<Integer> sizes = new ArrayList<Integer>(); | ||||
| 
 | ||||
| 	protected XmppConnectionService mXmppConnectionService = null; | ||||
| 
 | ||||
| 	public AvatarService(XmppConnectionService service) { | ||||
| 		this.mXmppConnectionService = service; | ||||
| 	} | ||||
| 
 | ||||
| 	public Bitmap getAvatar(Contact contact, int size) { | ||||
| 		Bitmap avatar = mXmppConnectionService.getFileBackend().getAvatar( | ||||
| 	public Bitmap get(Contact contact, int size) { | ||||
| 		final String KEY = key(contact, size); | ||||
| 		Bitmap avatar = this.mXmppConnectionService.getBitmapCache().get(KEY); | ||||
| 		if (avatar != null) { | ||||
| 			return avatar; | ||||
| 		} | ||||
| 		Log.d(Config.LOGTAG, "no cache hit for " + KEY); | ||||
| 		avatar = mXmppConnectionService.getFileBackend().getAvatar( | ||||
| 				contact.getAvatar(), size); | ||||
| 		if (avatar == null) { | ||||
| 			if (contact.getProfilePhoto() != null) { | ||||
| @ -36,43 +52,74 @@ public class AvatarService { | ||||
| 						.cropCenterSquare(Uri.parse(contact.getProfilePhoto()), | ||||
| 								size); | ||||
| 				if (avatar == null) { | ||||
| 					avatar = getAvatar(contact.getDisplayName(), size); | ||||
| 					avatar = get(contact.getDisplayName(), size); | ||||
| 				} | ||||
| 			} else { | ||||
| 				avatar = getAvatar(contact.getDisplayName(), size); | ||||
| 				avatar = get(contact.getDisplayName(), size); | ||||
| 			} | ||||
| 		} | ||||
| 		this.mXmppConnectionService.getBitmapCache().put(KEY, avatar); | ||||
| 		return avatar; | ||||
| 	} | ||||
| 
 | ||||
| 	public Bitmap getAvatar(ListItem item, int size) { | ||||
| 	public void clear(Contact contact) { | ||||
| 		for (Integer size : sizes) { | ||||
| 			this.mXmppConnectionService.getBitmapCache().remove( | ||||
| 					key(contact, size)); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private String key(Contact contact, int size) { | ||||
| 		synchronized (this.sizes) { | ||||
| 			if (!this.sizes.contains(size)) { | ||||
| 				this.sizes.add(size); | ||||
| 			} | ||||
| 		} | ||||
| 		return PREFIX_CONTACT + "_" + contact.getAccount().getJid() + "_" | ||||
| 				+ contact.getJid() + "_" + String.valueOf(size); | ||||
| 	} | ||||
| 
 | ||||
| 	public Bitmap get(ListItem item, int size) { | ||||
| 		if (item instanceof Contact) { | ||||
| 			return getAvatar((Contact) item, size); | ||||
| 			return get((Contact) item, size); | ||||
| 		} else if (item instanceof Bookmark) { | ||||
| 			Bookmark bookmark = (Bookmark) item; | ||||
| 			if (bookmark.getConversation() != null) { | ||||
| 				return getAvatar(bookmark.getConversation(), size); | ||||
| 				return get(bookmark.getConversation(), size); | ||||
| 			} else { | ||||
| 				return getAvatar(bookmark.getDisplayName(), size); | ||||
| 				return get(bookmark.getDisplayName(), size); | ||||
| 			} | ||||
| 		} else { | ||||
| 			return getAvatar(item.getDisplayName(), size); | ||||
| 			return get(item.getDisplayName(), size); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public Bitmap getAvatar(Conversation conversation, int size) { | ||||
| 	public Bitmap get(Conversation conversation, int size) { | ||||
| 		if (conversation.getMode() == Conversation.MODE_SINGLE) { | ||||
| 			return getAvatar(conversation.getContact(), size); | ||||
| 			return get(conversation.getContact(), size); | ||||
| 		} else { | ||||
| 			return getAvatar(conversation.getMucOptions(), size); | ||||
| 			return get(conversation.getMucOptions(), size); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public Bitmap getAvatar(MucOptions mucOptions, int size) { | ||||
| 	public void clear(Conversation conversation) { | ||||
| 		if (conversation.getMode() == Conversation.MODE_SINGLE) { | ||||
| 			clear(conversation.getContact()); | ||||
| 		} else { | ||||
| 			clear(conversation.getMucOptions()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public Bitmap get(MucOptions mucOptions, int size) { | ||||
| 		final String KEY = key(mucOptions, size); | ||||
| 		Bitmap bitmap = this.mXmppConnectionService.getBitmapCache().get(KEY); | ||||
| 		if (bitmap != null) { | ||||
| 			return bitmap; | ||||
| 		} | ||||
| 		Log.d(Config.LOGTAG, "no cache hit for " + KEY); | ||||
| 		List<MucOptions.User> users = mucOptions.getUsers(); | ||||
| 		int count = users.size(); | ||||
| 		Bitmap bitmap = Bitmap | ||||
| 				.createBitmap(size, size, Bitmap.Config.ARGB_8888); | ||||
| 		bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); | ||||
| 		Canvas canvas = new Canvas(bitmap); | ||||
| 		bitmap.eraseColor(TRANSPARENT); | ||||
| 
 | ||||
| @ -104,28 +151,85 @@ public class AvatarService { | ||||
| 			drawTile(canvas, "\u2026", 0xFF202020, size / 2 + 1, size / 2 + 1, | ||||
| 					size, size); | ||||
| 		} | ||||
| 		this.mXmppConnectionService.getBitmapCache().put(KEY, bitmap); | ||||
| 		return bitmap; | ||||
| 	} | ||||
| 
 | ||||
| 	public Bitmap getAvatar(Account account, int size) { | ||||
| 		Bitmap avatar = mXmppConnectionService.getFileBackend().getAvatar( | ||||
| 	public void clear(MucOptions options) { | ||||
| 		for (Integer size : sizes) { | ||||
| 			this.mXmppConnectionService.getBitmapCache().remove( | ||||
| 					key(options, size)); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private String key(MucOptions options, int size) { | ||||
| 		synchronized (this.sizes) { | ||||
| 			if (!this.sizes.contains(size)) { | ||||
| 				this.sizes.add(size); | ||||
| 			} | ||||
| 		} | ||||
| 		return PREFIX_CONVERSATION + "_" + options.getConversation().getUuid() | ||||
| 				+ "_" + String.valueOf(size); | ||||
| 	} | ||||
| 
 | ||||
| 	public Bitmap get(Account account, int size) { | ||||
| 		final String KEY = key(account, size); | ||||
| 		Bitmap avatar = mXmppConnectionService.getBitmapCache().get(KEY); | ||||
| 		if (avatar != null) { | ||||
| 			return avatar; | ||||
| 		} | ||||
| 		Log.d(Config.LOGTAG, "no cache hit for " + KEY); | ||||
| 		avatar = mXmppConnectionService.getFileBackend().getAvatar( | ||||
| 				account.getAvatar(), size); | ||||
| 		if (avatar == null) { | ||||
| 			avatar = getAvatar(account.getJid(), size); | ||||
| 			avatar = get(account.getJid(), size); | ||||
| 		} | ||||
| 		mXmppConnectionService.getBitmapCache().put(KEY, avatar); | ||||
| 		return avatar; | ||||
| 	} | ||||
| 
 | ||||
| 	public Bitmap getAvatar(String name, int size) { | ||||
| 		Bitmap bitmap = Bitmap | ||||
| 				.createBitmap(size, size, Bitmap.Config.ARGB_8888); | ||||
| 	public void clear(Account account) { | ||||
| 		for (Integer size : sizes) { | ||||
| 			this.mXmppConnectionService.getBitmapCache().remove( | ||||
| 					key(account, size)); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private String key(Account account, int size) { | ||||
| 		synchronized (this.sizes) { | ||||
| 			if (!this.sizes.contains(size)) { | ||||
| 				this.sizes.add(size); | ||||
| 			} | ||||
| 		} | ||||
| 		return PREFIX_ACCOUNT + "_" + account.getUuid() + "_" | ||||
| 				+ String.valueOf(size); | ||||
| 	} | ||||
| 
 | ||||
| 	public Bitmap get(String name, int size) { | ||||
| 		final String KEY = key(name, size); | ||||
| 		Bitmap bitmap = mXmppConnectionService.getBitmapCache().get(KEY); | ||||
| 		if (bitmap != null) { | ||||
| 			return bitmap; | ||||
| 		} | ||||
| 		Log.d(Config.LOGTAG, "no cache hit for " + KEY); | ||||
| 		bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); | ||||
| 		Canvas canvas = new Canvas(bitmap); | ||||
| 		String letter = name.substring(0, 1); | ||||
| 		int color = this.getColorForName(name); | ||||
| 		drawTile(canvas, letter, color, 0, 0, size, size); | ||||
| 		mXmppConnectionService.getBitmapCache().put(KEY, bitmap); | ||||
| 		return bitmap; | ||||
| 	} | ||||
| 
 | ||||
| 	private String key(String name, int size) { | ||||
| 		synchronized (this.sizes) { | ||||
| 			if (!this.sizes.contains(size)) { | ||||
| 				this.sizes.add(size); | ||||
| 			} | ||||
| 		} | ||||
| 		return PREFIX_GENERIC + "_" + name + "_" + String.valueOf(size); | ||||
| 	} | ||||
| 
 | ||||
| 	private void drawTile(Canvas canvas, String letter, int tileColor, | ||||
| 			int left, int top, int right, int bottom) { | ||||
| 		letter = letter.toUpperCase(Locale.getDefault()); | ||||
|  | ||||
| @ -16,6 +16,7 @@ import android.os.PowerManager; | ||||
| import android.support.v4.app.NotificationCompat; | ||||
| import android.support.v4.app.TaskStackBuilder; | ||||
| import android.text.Html; | ||||
| import android.util.DisplayMetrics; | ||||
| 
 | ||||
| import eu.siacs.conversations.R; | ||||
| import eu.siacs.conversations.entities.Account; | ||||
| @ -26,7 +27,6 @@ import eu.siacs.conversations.ui.ConversationActivity; | ||||
| public class NotificationService { | ||||
| 
 | ||||
| 	private XmppConnectionService mXmppConnectionService; | ||||
| 	private NotificationManager mNotificationManager; | ||||
| 
 | ||||
| 	private LinkedHashMap<String, ArrayList<Message>> notifications = new LinkedHashMap<String, ArrayList<Message>>(); | ||||
| 
 | ||||
| @ -36,8 +36,6 @@ public class NotificationService { | ||||
| 
 | ||||
| 	public NotificationService(XmppConnectionService service) { | ||||
| 		this.mXmppConnectionService = service; | ||||
| 		this.mNotificationManager = (NotificationManager) service | ||||
| 				.getSystemService(Context.NOTIFICATION_SERVICE); | ||||
| 	} | ||||
| 
 | ||||
| 	public void push(Message message) { | ||||
| @ -79,6 +77,8 @@ public class NotificationService { | ||||
| 	} | ||||
| 
 | ||||
| 	private void updateNotification(boolean notify) { | ||||
| 		NotificationManager notificationManager = (NotificationManager) mXmppConnectionService | ||||
| 				.getSystemService(Context.NOTIFICATION_SERVICE); | ||||
| 		SharedPreferences preferences = mXmppConnectionService.getPreferences(); | ||||
| 
 | ||||
| 		String ringtone = preferences.getString("notification_ringtone", null); | ||||
| @ -86,7 +86,7 @@ public class NotificationService { | ||||
| 				true); | ||||
| 
 | ||||
| 		if (notifications.size() == 0) { | ||||
| 			mNotificationManager.cancel(NOTIFICATION_ID); | ||||
| 			notificationManager.cancel(NOTIFICATION_ID); | ||||
| 		} else { | ||||
| 			NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( | ||||
| 					mXmppConnectionService); | ||||
| @ -97,8 +97,8 @@ public class NotificationService { | ||||
| 				if (messages.size() >= 1) { | ||||
| 					Conversation conversation = messages.get(0) | ||||
| 							.getConversation(); | ||||
| 					// mBuilder.setLargeIcon(conversation.getImage(mXmppConnectionService, | ||||
| 					// 64)); | ||||
| 					mBuilder.setLargeIcon(mXmppConnectionService | ||||
| 							.getAvatarService().get(conversation, getPixel(64))); | ||||
| 					mBuilder.setContentTitle(conversation.getName()); | ||||
| 					StringBuilder text = new StringBuilder(); | ||||
| 					for (int i = 0; i < messages.size(); ++i) { | ||||
| @ -119,7 +119,7 @@ public class NotificationService { | ||||
| 					mBuilder.setContentIntent(createContentIntent(conversation | ||||
| 							.getUuid())); | ||||
| 				} else { | ||||
| 					mNotificationManager.cancel(NOTIFICATION_ID); | ||||
| 					notificationManager.cancel(NOTIFICATION_ID); | ||||
| 					return; | ||||
| 				} | ||||
| 			} else { | ||||
| @ -170,7 +170,7 @@ public class NotificationService { | ||||
| 			mBuilder.setDeleteIntent(createDeleteIntent()); | ||||
| 			mBuilder.setLights(0xffffffff, 2000, 4000); | ||||
| 			Notification notification = mBuilder.build(); | ||||
| 			mNotificationManager.notify(NOTIFICATION_ID, notification); | ||||
| 			notificationManager.notify(NOTIFICATION_ID, notification); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| @ -227,4 +227,10 @@ public class NotificationService { | ||||
| 	public void setIsInForeground(boolean foreground) { | ||||
| 		this.mIsInForeground = foreground; | ||||
| 	} | ||||
| 
 | ||||
| 	private int getPixel(int dp) { | ||||
| 		DisplayMetrics metrics = mXmppConnectionService.getResources() | ||||
| 				.getDisplayMetrics(); | ||||
| 		return ((int) (dp * metrics.density)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -84,11 +84,12 @@ import android.os.SystemClock; | ||||
| import android.preference.PreferenceManager; | ||||
| import android.provider.ContactsContract; | ||||
| import android.util.Log; | ||||
| import android.util.LruCache; | ||||
| 
 | ||||
| public class XmppConnectionService extends Service { | ||||
| 
 | ||||
| 	public DatabaseBackend databaseBackend; | ||||
| 	private FileBackend fileBackend; | ||||
| 	private FileBackend fileBackend = new FileBackend(this); | ||||
| 
 | ||||
| 	public long startDate; | ||||
| 
 | ||||
| @ -97,7 +98,8 @@ public class XmppConnectionService extends Service { | ||||
| 
 | ||||
| 	private MemorizingTrustManager mMemorizingTrustManager; | ||||
| 
 | ||||
| 	private NotificationService mNotificationService; | ||||
| 	private NotificationService mNotificationService = new NotificationService( | ||||
| 			this); | ||||
| 
 | ||||
| 	private MessageParser mMessageParser = new MessageParser(this); | ||||
| 	private PresenceParser mPresenceParser = new PresenceParser(this); | ||||
| @ -269,6 +271,7 @@ public class XmppConnectionService extends Service { | ||||
| 			} | ||||
| 		} | ||||
| 	}; | ||||
| 	private LruCache<String, Bitmap> mBitmapCache; | ||||
| 
 | ||||
| 	public PgpEngine getPgpEngine() { | ||||
| 		if (pgpServiceConnection.isBound()) { | ||||
| @ -429,10 +432,18 @@ public class XmppConnectionService extends Service { | ||||
| 		this.mRandom = new SecureRandom(); | ||||
| 		this.mMemorizingTrustManager = new MemorizingTrustManager( | ||||
| 				getApplicationContext()); | ||||
| 		this.mNotificationService = new NotificationService(this); | ||||
| 
 | ||||
| 		int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); | ||||
| 		int cacheSize = maxMemory / 8; | ||||
| 		this.mBitmapCache = new LruCache<String, Bitmap>(cacheSize) { | ||||
| 			@Override | ||||
| 			protected int sizeOf(String key, Bitmap bitmap) { | ||||
| 				return bitmap.getByteCount() / 1024; | ||||
| 			} | ||||
| 		}; | ||||
| 
 | ||||
| 		this.databaseBackend = DatabaseBackend | ||||
| 				.getInstance(getApplicationContext()); | ||||
| 		this.fileBackend = new FileBackend(getApplicationContext()); | ||||
| 		this.accounts = databaseBackend.getAccounts(); | ||||
| 
 | ||||
| 		for (Account account : this.accounts) { | ||||
| @ -801,6 +812,7 @@ public class XmppConnectionService extends Service { | ||||
| 										.getString("photouri")); | ||||
| 								contact.setSystemName(phoneContact | ||||
| 										.getString("displayname")); | ||||
| 								getAvatarService().clear(contact); | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| @ -1497,10 +1509,12 @@ public class XmppConnectionService extends Service { | ||||
| 								if (account.setAvatar(avatar.getFilename())) { | ||||
| 									databaseBackend.updateAccount(account); | ||||
| 								} | ||||
| 								getAvatarService().clear(account); | ||||
| 							} else { | ||||
| 								Contact contact = account.getRoster() | ||||
| 										.getContact(avatar.owner); | ||||
| 								contact.setAvatar(avatar.getFilename()); | ||||
| 								getAvatarService().clear(contact); | ||||
| 							} | ||||
| 							if (callback != null) { | ||||
| 								callback.success(avatar); | ||||
| @ -1550,6 +1564,7 @@ public class XmppConnectionService extends Service { | ||||
| 									if (account.setAvatar(avatar.getFilename())) { | ||||
| 										databaseBackend.updateAccount(account); | ||||
| 									} | ||||
| 									getAvatarService().clear(account); | ||||
| 									callback.success(avatar); | ||||
| 								} else { | ||||
| 									fetchAvatar(account, avatar, callback); | ||||
| @ -1762,6 +1777,10 @@ public class XmppConnectionService extends Service { | ||||
| 		return this.pm; | ||||
| 	} | ||||
| 
 | ||||
| 	public LruCache<String, Bitmap> getBitmapCache() { | ||||
| 		return this.mBitmapCache; | ||||
| 	} | ||||
| 
 | ||||
| 	public void replyWithNotAcceptable(Account account, MessagePacket packet) { | ||||
| 		if (account.getStatus() == Account.STATUS_ONLINE) { | ||||
| 			MessagePacket error = this.mMessageGenerator | ||||
|  | ||||
| @ -7,14 +7,12 @@ import org.openintents.openpgp.util.OpenPgpUtils; | ||||
| 
 | ||||
| import eu.siacs.conversations.R; | ||||
| import eu.siacs.conversations.crypto.PgpEngine; | ||||
| import eu.siacs.conversations.entities.Account; | ||||
| import eu.siacs.conversations.entities.Contact; | ||||
| import eu.siacs.conversations.entities.Conversation; | ||||
| import eu.siacs.conversations.entities.MucOptions; | ||||
| import eu.siacs.conversations.entities.MucOptions.OnRenameListener; | ||||
| import eu.siacs.conversations.entities.MucOptions.User; | ||||
| import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate; | ||||
| import eu.siacs.conversations.utils.UIHelper; | ||||
| import eu.siacs.conversations.xmpp.stanzas.MessagePacket; | ||||
| import android.app.PendingIntent; | ||||
| import android.content.Context; | ||||
| @ -201,8 +199,8 @@ public class ConferenceDetailsActivity extends XmppActivity { | ||||
| 	private void populateView() { | ||||
| 		mAccountJid.setText(getString(R.string.using_account, conversation | ||||
| 				.getAccount().getJid())); | ||||
| 		mYourPhoto.setImageBitmap(xmppConnectionService.getAvatarService() | ||||
| 				.getAvatar(conversation.getAccount(), getPixel(48))); | ||||
| 		mYourPhoto.setImageBitmap(avatarService().get( | ||||
| 				conversation.getAccount(), getPixel(48))); | ||||
| 		setTitle(conversation.getName()); | ||||
| 		mFullJid.setText(conversation.getContactJid().split("/", 2)[0]); | ||||
| 		mYourNick.setText(conversation.getMucOptions().getActualNick()); | ||||
| @ -228,7 +226,6 @@ public class ConferenceDetailsActivity extends XmppActivity { | ||||
| 		this.users.addAll(conversation.getMucOptions().getUsers()); | ||||
| 		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); | ||||
| 		membersView.removeAllViews(); | ||||
| 		Account account = conversation.getAccount(); | ||||
| 		for (final User user : conversation.getMucOptions().getUsers()) { | ||||
| 			View view = (View) inflater.inflate(R.layout.contact, membersView, | ||||
| 					false); | ||||
| @ -248,24 +245,14 @@ public class ConferenceDetailsActivity extends XmppActivity { | ||||
| 				key.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId())); | ||||
| 			} | ||||
| 			Bitmap bm; | ||||
| 			if (user.getJid() != null) { | ||||
| 				Contact contact = account.getRoster().getContactFromRoster( | ||||
| 						user.getJid()); | ||||
| 				if (contact != null) { | ||||
| 					bm = xmppConnectionService.getAvatarService().getAvatar( | ||||
| 							contact, getPixel(48)); | ||||
| 					name.setText(contact.getDisplayName()); | ||||
| 					role.setText(user.getName() + " \u2022 " | ||||
| 							+ getReadableRole(user.getRole())); | ||||
| 				} else { | ||||
| 					bm = xmppConnectionService.getAvatarService().getAvatar( | ||||
| 							user.getName(), getPixel(48)); | ||||
| 					name.setText(user.getName()); | ||||
| 					role.setText(getReadableRole(user.getRole())); | ||||
| 				} | ||||
| 			Contact contact = user.getContact(); | ||||
| 			if (contact != null) { | ||||
| 				bm = avatarService().get(contact, getPixel(48)); | ||||
| 				name.setText(contact.getDisplayName()); | ||||
| 				role.setText(user.getName() + " \u2022 " | ||||
| 						+ getReadableRole(user.getRole())); | ||||
| 			} else { | ||||
| 				bm = xmppConnectionService.getAvatarService().getAvatar( | ||||
| 						user.getName(), getPixel(48)); | ||||
| 				bm = avatarService().get(user.getName(), getPixel(48)); | ||||
| 				name.setText(user.getName()); | ||||
| 				role.setText(getReadableRole(user.getRole())); | ||||
| 			} | ||||
|  | ||||
| @ -386,8 +386,7 @@ public class ContactDetailsActivity extends XmppActivity { | ||||
| 			long id = Long.parseLong(systemAccount[0]); | ||||
| 			badge.assignContactUri(Contacts.getLookupUri(id, systemAccount[1])); | ||||
| 		} | ||||
| 		badge.setImageBitmap(xmppConnectionService.getAvatarService() | ||||
| 				.getAvatar(contact, getPixel(72))); | ||||
| 		badge.setImageBitmap(avatarService().get(contact, getPixel(72))); | ||||
| 	} | ||||
| 
 | ||||
| 	protected void confirmToDeleteFingerprint(final String fingerprint) { | ||||
|  | ||||
| @ -158,8 +158,8 @@ public class PublishProfilePictureActivity extends XmppActivity { | ||||
| 				if (this.avatarUri == null) { | ||||
| 					if (this.account.getAvatar() != null | ||||
| 							|| this.defaultUri == null) { | ||||
| 						// this.avatar.setImageBitmap(this.account.getImage(getApplicationContext(), | ||||
| 						// 384)); | ||||
| 						this.avatar.setImageBitmap(avatarService().get(account, | ||||
| 								getPixel(194))); | ||||
| 						if (this.defaultUri != null) { | ||||
| 							this.avatar | ||||
| 									.setOnLongClickListener(this.backToDefaultListener); | ||||
|  | ||||
| @ -12,6 +12,7 @@ import eu.siacs.conversations.entities.Contact; | ||||
| import eu.siacs.conversations.entities.Conversation; | ||||
| import eu.siacs.conversations.entities.Message; | ||||
| import eu.siacs.conversations.entities.Presences; | ||||
| import eu.siacs.conversations.services.AvatarService; | ||||
| import eu.siacs.conversations.services.XmppConnectionService; | ||||
| import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder; | ||||
| import eu.siacs.conversations.utils.ExceptionHelper; | ||||
| @ -531,6 +532,10 @@ public abstract class XmppActivity extends Activity { | ||||
| 		return ((int) (dp * metrics.density)); | ||||
| 	} | ||||
| 
 | ||||
| 	public AvatarService avatarService() { | ||||
| 		return xmppConnectionService.getAvatarService(); | ||||
| 	} | ||||
| 
 | ||||
| 	class BitmapWorkerTask extends AsyncTask<Message, Void, Bitmap> { | ||||
| 		private final WeakReference<ImageView> imageViewReference; | ||||
| 		private Message message = null; | ||||
|  | ||||
| @ -34,8 +34,8 @@ public class AccountAdapter extends ArrayAdapter<Account> { | ||||
| 		jid.setText(account.getJid()); | ||||
| 		TextView statusView = (TextView) view.findViewById(R.id.account_status); | ||||
| 		ImageView imageView = (ImageView) view.findViewById(R.id.account_image); | ||||
| 		imageView.setImageBitmap(activity.xmppConnectionService | ||||
| 				.getAvatarService().getAvatar(account, activity.getPixel(48))); | ||||
| 		imageView.setImageBitmap(activity.avatarService().get(account, | ||||
| 				activity.getPixel(48))); | ||||
| 		switch (account.getStatus()) { | ||||
| 		case Account.STATUS_DISABLED: | ||||
| 			statusView.setText(getContext().getString( | ||||
|  | ||||
| @ -127,9 +127,8 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> { | ||||
| 
 | ||||
| 		ImageView profilePicture = (ImageView) view | ||||
| 				.findViewById(R.id.conversation_image); | ||||
| 		profilePicture.setImageBitmap(activity.xmppConnectionService | ||||
| 				.getAvatarService().getAvatar(conversation, | ||||
| 						activity.getPixel(56))); | ||||
| 		profilePicture.setImageBitmap(activity.avatarService().get( | ||||
| 				conversation, activity.getPixel(56))); | ||||
| 
 | ||||
| 		return view; | ||||
| 	} | ||||
|  | ||||
| @ -36,8 +36,8 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> { | ||||
| 
 | ||||
| 		jid.setText(item.getJid()); | ||||
| 		name.setText(item.getDisplayName()); | ||||
| 		picture.setImageBitmap(activity.xmppConnectionService | ||||
| 				.getAvatarService().getAvatar(item, activity.getPixel(48))); | ||||
| 		picture.setImageBitmap(activity.avatarService().get(item, | ||||
| 				activity.getPixel(48))); | ||||
| 		return view; | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| package eu.siacs.conversations.ui.adapter; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import eu.siacs.conversations.Config; | ||||
| @ -12,9 +11,7 @@ import eu.siacs.conversations.entities.Message; | ||||
| import eu.siacs.conversations.entities.Message.ImageParams; | ||||
| import eu.siacs.conversations.ui.ConversationActivity; | ||||
| import eu.siacs.conversations.utils.UIHelper; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.graphics.Bitmap; | ||||
| import android.graphics.Typeface; | ||||
| import android.text.Spannable; | ||||
| import android.text.SpannableString; | ||||
| @ -41,9 +38,6 @@ public class MessageAdapter extends ArrayAdapter<Message> { | ||||
| 
 | ||||
| 	private ConversationActivity activity; | ||||
| 
 | ||||
| 	private Bitmap accountBitmap; | ||||
| 
 | ||||
| 	private BitmapCache mBitmapCache = new BitmapCache(); | ||||
| 	private DisplayMetrics metrics; | ||||
| 
 | ||||
| 	private OnContactPictureClicked mOnContactPictureClickedListener; | ||||
| @ -55,19 +49,6 @@ public class MessageAdapter extends ArrayAdapter<Message> { | ||||
| 		metrics = getContext().getResources().getDisplayMetrics(); | ||||
| 	} | ||||
| 
 | ||||
| 	private Bitmap getSelfBitmap() { | ||||
| 		if (this.accountBitmap == null) { | ||||
| 
 | ||||
| 			if (getCount() > 0) { | ||||
| 				this.accountBitmap = activity.xmppConnectionService | ||||
| 						.getAvatarService().getAvatar( | ||||
| 								getItem(0).getConversation().getAccount(), | ||||
| 								activity.getPixel(48)); | ||||
| 			} | ||||
| 		} | ||||
| 		return this.accountBitmap; | ||||
| 	} | ||||
| 
 | ||||
| 	public void setOnContactPictureClicked(OnContactPictureClicked listener) { | ||||
| 		this.mOnContactPictureClickedListener = listener; | ||||
| 	} | ||||
| @ -349,7 +330,10 @@ public class MessageAdapter extends ArrayAdapter<Message> { | ||||
| 						.findViewById(R.id.message_box); | ||||
| 				viewHolder.contact_picture = (ImageView) view | ||||
| 						.findViewById(R.id.message_photo); | ||||
| 				viewHolder.contact_picture.setImageBitmap(getSelfBitmap()); | ||||
| 				viewHolder.contact_picture.setImageBitmap(activity | ||||
| 						.avatarService().get( | ||||
| 								item.getConversation().getAccount(), | ||||
| 								activity.getPixel(48))); | ||||
| 				viewHolder.download_button = (Button) view | ||||
| 						.findViewById(R.id.download_button); | ||||
| 				viewHolder.indicator = (ImageView) view | ||||
| @ -374,8 +358,9 @@ public class MessageAdapter extends ArrayAdapter<Message> { | ||||
| 				viewHolder.download_button = (Button) view | ||||
| 						.findViewById(R.id.download_button); | ||||
| 				if (item.getConversation().getMode() == Conversation.MODE_SINGLE) { | ||||
| 					viewHolder.contact_picture.setImageBitmap(mBitmapCache.get( | ||||
| 							item.getConversation().getContact(), getContext())); | ||||
| 					viewHolder.contact_picture.setImageBitmap(activity | ||||
| 							.avatarService().get(item.getContact(), | ||||
| 									activity.getPixel(48))); | ||||
| 				} | ||||
| 				viewHolder.indicator = (ImageView) view | ||||
| 						.findViewById(R.id.security_indicator); | ||||
| @ -394,8 +379,10 @@ public class MessageAdapter extends ArrayAdapter<Message> { | ||||
| 						.findViewById(R.id.message_photo); | ||||
| 				if (item.getConversation().getMode() == Conversation.MODE_SINGLE) { | ||||
| 
 | ||||
| 					viewHolder.contact_picture.setImageBitmap(mBitmapCache.get( | ||||
| 							item.getConversation().getContact(), getContext())); | ||||
| 					viewHolder.contact_picture.setImageBitmap(activity | ||||
| 							.avatarService().get( | ||||
| 									item.getConversation().getContact(), | ||||
| 									activity.getPixel(32))); | ||||
| 					viewHolder.contact_picture.setAlpha(0.5f); | ||||
| 					viewHolder.contact_picture | ||||
| 							.setOnClickListener(new OnClickListener() { | ||||
| @ -471,15 +458,16 @@ public class MessageAdapter extends ArrayAdapter<Message> { | ||||
| 			if (item.getConversation().getMode() == Conversation.MODE_MULTI) { | ||||
| 				Contact contact = item.getContact(); | ||||
| 				if (contact != null) { | ||||
| 					viewHolder.contact_picture.setImageBitmap(mBitmapCache.get( | ||||
| 							contact, getContext())); | ||||
| 					viewHolder.contact_picture.setImageBitmap(activity | ||||
| 							.avatarService() | ||||
| 							.get(contact, activity.getPixel(48))); | ||||
| 				} else { | ||||
| 					String name = item.getPresence(); | ||||
| 					if (name == null) { | ||||
| 						name = item.getCounterpart(); | ||||
| 					} | ||||
| 					viewHolder.contact_picture.setImageBitmap(mBitmapCache.get( | ||||
| 							name, getContext())); | ||||
| 					viewHolder.contact_picture.setImageBitmap(activity | ||||
| 							.avatarService().get(name, activity.getPixel(48))); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @ -562,31 +550,6 @@ public class MessageAdapter extends ArrayAdapter<Message> { | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	private class BitmapCache { | ||||
| 		private HashMap<String, Bitmap> contactBitmaps = new HashMap<String, Bitmap>(); | ||||
| 		private HashMap<String, Bitmap> unknownBitmaps = new HashMap<String, Bitmap>(); | ||||
| 
 | ||||
| 		public Bitmap get(Contact contact, Context context) { | ||||
| 			if (!contactBitmaps.containsKey(contact.getJid())) { | ||||
| 				contactBitmaps.put(contact.getJid(), | ||||
| 						activity.xmppConnectionService.getAvatarService() | ||||
| 								.getAvatar(contact, activity.getPixel(48))); | ||||
| 			} | ||||
| 			return contactBitmaps.get(contact.getJid()); | ||||
| 		} | ||||
| 
 | ||||
| 		public Bitmap get(String name, Context context) { | ||||
| 			if (unknownBitmaps.containsKey(name)) { | ||||
| 				return unknownBitmaps.get(name); | ||||
| 			} else { | ||||
| 				Bitmap bm = activity.xmppConnectionService.getAvatarService() | ||||
| 						.getAvatar(name, activity.getPixel(48)); | ||||
| 				unknownBitmaps.put(name, bm); | ||||
| 				return bm; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public interface OnContactPictureClicked { | ||||
| 		public void onContactPictureClicked(Message message); | ||||
| 	} | ||||
|  | ||||
| @ -1,22 +1,18 @@ | ||||
| package eu.siacs.conversations.utils; | ||||
| 
 | ||||
| import java.io.FileNotFoundException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Calendar; | ||||
| import java.util.Date; | ||||
| import java.util.List; | ||||
| import java.util.Locale; | ||||
| import java.util.regex.Pattern; | ||||
| 
 | ||||
| import eu.siacs.conversations.R; | ||||
| import eu.siacs.conversations.entities.Account; | ||||
| import eu.siacs.conversations.entities.Contact; | ||||
| import eu.siacs.conversations.entities.Conversation; | ||||
| import eu.siacs.conversations.entities.MucOptions.User; | ||||
| import eu.siacs.conversations.ui.ConversationActivity; | ||||
| import eu.siacs.conversations.ui.ManageAccountActivity; | ||||
| import android.annotation.SuppressLint; | ||||
| import android.app.Activity; | ||||
| import android.app.AlertDialog; | ||||
| import android.app.Notification; | ||||
| import android.app.NotificationManager; | ||||
| @ -25,28 +21,15 @@ import android.content.Context; | ||||
| import android.content.DialogInterface; | ||||
| import android.content.DialogInterface.OnClickListener; | ||||
| import android.content.Intent; | ||||
| import android.graphics.Bitmap; | ||||
| import android.graphics.BitmapFactory; | ||||
| import android.graphics.Canvas; | ||||
| import android.graphics.Paint; | ||||
| import android.graphics.Rect; | ||||
| import android.graphics.Typeface; | ||||
| import android.net.Uri; | ||||
| import android.provider.ContactsContract.Contacts; | ||||
| import android.support.v4.app.NotificationCompat; | ||||
| import android.support.v4.app.TaskStackBuilder; | ||||
| import android.text.format.DateFormat; | ||||
| import android.text.format.DateUtils; | ||||
| import android.util.DisplayMetrics; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.widget.QuickContactBadge; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| public class UIHelper { | ||||
| 	private static final int BG_COLOR = 0xFF181818; | ||||
| 	private static final int FG_COLOR = 0xFFFAFAFA; | ||||
| 	private static final int TRANSPARENT = 0x00000000; | ||||
| 	private static final int SHORT_DATE_FLAGS = DateUtils.FORMAT_SHOW_DATE | ||||
| 			| DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL; | ||||
| 	private static final int FULL_DATE_FLAGS = DateUtils.FORMAT_SHOW_TIME | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 iNPUTmice
						iNPUTmice