store avatars in cache folder

This commit is contained in:
Daniel Gultsch 2020-12-10 19:05:04 +01:00
parent 07e965f8f3
commit f584179f2f
6 changed files with 619 additions and 615 deletions

View file

@ -137,7 +137,7 @@ public class Contact implements ListItem, Blockable {
return this.systemName; return this.systemName;
} else if (!TextUtils.isEmpty(this.serverName)) { } else if (!TextUtils.isEmpty(this.serverName)) {
return this.serverName; return this.serverName;
} else if (!TextUtils.isEmpty(this.presenceName) && ((QuickConversationsService.isQuicksy() && JidHelper.isQuicksyDomain(jid.getDomain())) ||mutualPresenceSubscription())) { } else if (!TextUtils.isEmpty(this.presenceName) && ((QuickConversationsService.isQuicksy() && JidHelper.isQuicksyDomain(jid.getDomain())) || mutualPresenceSubscription())) {
return this.presenceName; return this.presenceName;
} else if (jid.getLocal() != null) { } else if (jid.getLocal() != null) {
return JidHelper.localPartOrFallback(jid); return JidHelper.localPartOrFallback(jid);
@ -430,20 +430,18 @@ public class Contact implements ListItem, Blockable {
return getJid().getDomain().toEscapedString(); return getJid().getDomain().toEscapedString();
} }
public boolean setAvatar(Avatar avatar) { public void setAvatar(Avatar avatar) {
return setAvatar(avatar, false); setAvatar(avatar, false);
} }
public boolean setAvatar(Avatar avatar, boolean previouslyOmittedPepFetch) { public void setAvatar(Avatar avatar, boolean previouslyOmittedPepFetch) {
if (this.avatar != null && this.avatar.equals(avatar)) { if (this.avatar != null && this.avatar.equals(avatar)) {
return false; return;
} else { }
if (!previouslyOmittedPepFetch && this.avatar != null && this.avatar.origin == Avatar.Origin.PEP && avatar.origin == Avatar.Origin.VCARD) { if (!previouslyOmittedPepFetch && this.avatar != null && this.avatar.origin == Avatar.Origin.PEP && avatar.origin == Avatar.Origin.VCARD) {
return false; return;
} }
this.avatar = avatar; this.avatar = avatar;
return true;
}
} }
public String getAvatarFilename() { public String getAvatarFilename() {
@ -534,7 +532,7 @@ public class Contact implements ListItem, Blockable {
return changed; return changed;
} }
public synchronized boolean unsetPhoneContact(Class<?extends AbstractPhoneContact> clazz) { public synchronized boolean unsetPhoneContact(Class<? extends AbstractPhoneContact> clazz) {
resetOption(getOption(clazz)); resetOption(getOption(clazz));
boolean changed = false; boolean changed = false;
if (!getOption(Options.SYNCED_VIA_ADDRESSBOOK) && !getOption(Options.SYNCED_VIA_OTHER)) { if (!getOption(Options.SYNCED_VIA_ADDRESSBOOK) && !getOption(Options.SYNCED_VIA_OTHER)) {

View file

@ -214,14 +214,13 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateConversationUi();
mXmppConnectionService.updateAccountUi(); mXmppConnectionService.updateAccountUi();
} else { } else {
Contact contact = account.getRoster().getContact(from); final Contact contact = account.getRoster().getContact(from);
if (contact.setAvatar(avatar)) { contact.setAvatar(avatar);
mXmppConnectionService.syncRoster(account); mXmppConnectionService.syncRoster(account);
mXmppConnectionService.getAvatarService().clear(contact); mXmppConnectionService.getAvatarService().clear(contact);
mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateConversationUi();
mXmppConnectionService.updateRosterUi(); mXmppConnectionService.updateRosterUi();
} }
}
} else if (mXmppConnectionService.isDataSaverDisabled()) { } else if (mXmppConnectionService.isDataSaverDisabled()) {
mXmppConnectionService.fetchAvatar(account, avatar); mXmppConnectionService.fetchAvatar(account, avatar);
} }

View file

@ -118,13 +118,12 @@ public class PresenceParser extends AbstractParser implements
mXmppConnectionService.getAvatarService().clear(user); mXmppConnectionService.getAvatarService().clear(user);
} }
if (user.getRealJid() != null) { if (user.getRealJid() != null) {
Contact c = conversation.getAccount().getRoster().getContact(user.getRealJid()); final Contact c = conversation.getAccount().getRoster().getContact(user.getRealJid());
if (c.setAvatar(avatar)) { c.setAvatar(avatar);
mXmppConnectionService.syncRoster(conversation.getAccount()); mXmppConnectionService.syncRoster(conversation.getAccount());
mXmppConnectionService.getAvatarService().clear(c); mXmppConnectionService.getAvatarService().clear(c);
mXmppConnectionService.updateRosterUi(); mXmppConnectionService.updateRosterUi();
} }
}
} else if (mXmppConnectionService.isDataSaverDisabled()) { } else if (mXmppConnectionService.isDataSaverDisabled()) {
mXmppConnectionService.fetchAvatar(mucOptions.getAccount(), avatar); mXmppConnectionService.fetchAvatar(mucOptions.getAccount(), avatar);
} }
@ -268,7 +267,8 @@ public class PresenceParser extends AbstractParser implements
mXmppConnectionService.getAvatarService().clear(account); mXmppConnectionService.getAvatarService().clear(account);
mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateConversationUi();
mXmppConnectionService.updateAccountUi(); mXmppConnectionService.updateAccountUi();
} else if (contact.setAvatar(avatar)) { } else {
contact.setAvatar(avatar);
mXmppConnectionService.syncRoster(account); mXmppConnectionService.syncRoster(account);
mXmppConnectionService.getAvatarService().clear(contact); mXmppConnectionService.getAvatarService().clear(contact);
mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateConversationUi();

View file

@ -1071,7 +1071,7 @@ public class FileBackend {
return null; return null;
} }
Avatar avatar = new Avatar(); Avatar avatar = new Avatar();
File file = new File(getAvatarPath(hash)); final File file = getAvatarFile(hash);
FileInputStream is = null; FileInputStream is = null;
try { try {
avatar.size = file.length(); avatar.size = file.length();
@ -1104,14 +1104,14 @@ public class FileBackend {
} }
public boolean isAvatarCached(Avatar avatar) { public boolean isAvatarCached(Avatar avatar) {
File file = new File(getAvatarPath(avatar.getFilename())); final File file = getAvatarFile(avatar.getFilename());
return file.exists(); return file.exists();
} }
public boolean save(final Avatar avatar) { public boolean save(final Avatar avatar) {
File file; File file;
if (isAvatarCached(avatar)) { if (isAvatarCached(avatar)) {
file = new File(getAvatarPath(avatar.getFilename())); file = getAvatarFile(avatar.getFilename());
avatar.size = file.length(); avatar.size = file.length();
} else { } else {
file = new File(mXmppConnectionService.getCacheDir().getAbsolutePath() + "/" + UUID.randomUUID().toString()); file = new File(mXmppConnectionService.getCacheDir().getAbsolutePath() + "/" + UUID.randomUUID().toString());
@ -1133,12 +1133,12 @@ public class FileBackend {
mDigestOutputStream.close(); mDigestOutputStream.close();
String sha1sum = CryptoHelper.bytesToHex(digest.digest()); String sha1sum = CryptoHelper.bytesToHex(digest.digest());
if (sha1sum.equals(avatar.sha1sum)) { if (sha1sum.equals(avatar.sha1sum)) {
File outputFile = new File(getAvatarPath(avatar.getFilename())); final File outputFile = getAvatarFile(avatar.getFilename());
if (outputFile.getParentFile().mkdirs()) { if (outputFile.getParentFile().mkdirs()) {
Log.d(Config.LOGTAG, "created avatar directory"); Log.d(Config.LOGTAG, "created avatar directory");
} }
String filename = getAvatarPath(avatar.getFilename()); final File avatarFile = getAvatarFile(avatar.getFilename());
if (!file.renameTo(new File(filename))) { if (!file.renameTo(avatarFile)) {
Log.d(Config.LOGTAG, "unable to rename " + file.getAbsolutePath() + " to " + outputFile); Log.d(Config.LOGTAG, "unable to rename " + file.getAbsolutePath() + " to " + outputFile);
return false; return false;
} }
@ -1159,12 +1159,34 @@ public class FileBackend {
return true; return true;
} }
private String getAvatarPath(String avatar) { public void deleteHistoricAvatarPath() {
return mXmppConnectionService.getFilesDir().getAbsolutePath() + "/avatars/" + avatar; delete(getHistoricAvatarPath());
}
private void delete(final File file) {
if (file.isDirectory()) {
final File[] files = file.listFiles();
if (files != null) {
for (final File f : files) {
delete(f);
}
}
}
if (file.delete()) {
Log.d(Config.LOGTAG,"deleted "+file.getAbsolutePath());
}
}
private File getHistoricAvatarPath() {
return new File(mXmppConnectionService.getFilesDir(), "/avatars/");
}
private File getAvatarFile(String avatar) {
return new File(mXmppConnectionService.getCacheDir(), "/avatars/" + avatar);
} }
public Uri getAvatarUri(String avatar) { public Uri getAvatarUri(String avatar) {
return Uri.parse("file:" + getAvatarPath(avatar)); return Uri.fromFile(getAvatarFile(avatar));
} }
public Bitmap cropCenterSquare(Uri image, int size) { public Bitmap cropCenterSquare(Uri image, int size) {

View file

@ -59,7 +59,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
private static final String CHANNEL_SYMBOL = "#"; private static final String CHANNEL_SYMBOL = "#";
final private ArrayList<Integer> sizes = new ArrayList<>(); final private Set<Integer> sizes = new HashSet<>();
final private HashMap<String, Set<String>> conversationDependentKeys = new HashMap<>(); final private HashMap<String, Set<String>> conversationDependentKeys = new HashMap<>();
protected XmppConnectionService mXmppConnectionService = null; protected XmppConnectionService mXmppConnectionService = null;
@ -224,9 +224,8 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
public void clear(Contact contact) { public void clear(Contact contact) {
synchronized (this.sizes) { synchronized (this.sizes) {
for (Integer size : sizes) { for (final Integer size : sizes) {
this.mXmppConnectionService.getBitmapCache().remove( this.mXmppConnectionService.getBitmapCache().remove(key(contact, size));
key(contact, size));
} }
} }
for (Conversation conversation : mXmppConnectionService.findAllConferencesWith(contact)) { for (Conversation conversation : mXmppConnectionService.findAllConferencesWith(contact)) {
@ -240,10 +239,8 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
private String key(Contact contact, int size) { private String key(Contact contact, int size) {
synchronized (this.sizes) { synchronized (this.sizes) {
if (!this.sizes.contains(size)) {
this.sizes.add(size); this.sizes.add(size);
} }
}
return PREFIX_CONTACT + return PREFIX_CONTACT +
'\0' + '\0' +
contact.getAccount().getJid().asBareJid() + contact.getAccount().getJid().asBareJid() +
@ -255,10 +252,8 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
private String key(MucOptions.User user, int size) { private String key(MucOptions.User user, int size) {
synchronized (this.sizes) { synchronized (this.sizes) {
if (!this.sizes.contains(size)) {
this.sizes.add(size); this.sizes.add(size);
} }
}
return PREFIX_CONTACT + return PREFIX_CONTACT +
'\0' + '\0' +
user.getAccount().getJid().asBareJid() + user.getAccount().getJid().asBareJid() +
@ -416,12 +411,9 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
private String key(final MucOptions options, int size) { private String key(final MucOptions options, int size) {
synchronized (this.sizes) { synchronized (this.sizes) {
if (!this.sizes.contains(size)) {
this.sizes.add(size); this.sizes.add(size);
} }
} return PREFIX_CONVERSATION + "_" + options.getConversation().getUuid() + "_" + size;
return PREFIX_CONVERSATION + "_" + options.getConversation().getUuid()
+ "_" + String.valueOf(size);
} }
private String key(List<MucOptions.User> users, int size) { private String key(List<MucOptions.User> users, int size) {
@ -524,10 +516,8 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
private String key(Account account, int size) { private String key(Account account, int size) {
synchronized (this.sizes) { synchronized (this.sizes) {
if (!this.sizes.contains(size)) {
this.sizes.add(size); this.sizes.add(size);
} }
}
return PREFIX_ACCOUNT + "_" + account.getUuid() + "_" return PREFIX_ACCOUNT + "_" + account.getUuid() + "_"
+ String.valueOf(size); + String.valueOf(size);
} }
@ -561,11 +551,9 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
private String key(String name, int size) { private String key(String name, int size) {
synchronized (this.sizes) { synchronized (this.sizes) {
if (!this.sizes.contains(size)) {
this.sizes.add(size); this.sizes.add(size);
} }
} return PREFIX_GENERIC + "_" + name + "_" + size;
return PREFIX_GENERIC + "_" + name + "_" + String.valueOf(size);
} }
private static boolean drawTile(Canvas canvas, String letter, int tileColor, int left, int top, int right, int bottom) { private static boolean drawTile(Canvas canvas, String letter, int tileColor, int left, int top, int right, int bottom) {

View file

@ -1127,6 +1127,7 @@ public class XmppConnectionService extends Service {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
startContactObserver(); startContactObserver();
} }
mFileAddingExecutor.execute(fileBackend::deleteHistoricAvatarPath);
if (Compatibility.hasStoragePermission(this)) { if (Compatibility.hasStoragePermission(this)) {
Log.d(Config.LOGTAG, "starting file observer"); Log.d(Config.LOGTAG, "starting file observer");
mFileAddingExecutor.execute(this.fileObserver::startWatching); mFileAddingExecutor.execute(this.fileObserver::startWatching);
@ -3696,19 +3697,17 @@ public class XmppConnectionService extends Service {
updateConversationUi(); updateConversationUi();
updateAccountUi(); updateAccountUi();
} else { } else {
Contact contact = a.getRoster().getContact(avatar.owner); final Contact contact = a.getRoster().getContact(avatar.owner);
if (contact.setAvatar(avatar)) { contact.setAvatar(avatar);
syncRoster(account); syncRoster(account);
getAvatarService().clear(contact); getAvatarService().clear(contact);
updateConversationUi(); updateConversationUi();
updateRosterUi(); updateRosterUi();
} }
}
if (callback != null) { if (callback != null) {
callback.success(avatar); callback.success(avatar);
} }
Log.d(Config.LOGTAG, a.getJid().asBareJid() Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": successfully fetched pep avatar for " + avatar.owner);
+ ": successfully fetched pep avatar for " + avatar.owner);
return; return;
} }
} else { } else {
@ -3758,13 +3757,12 @@ public class XmppConnectionService extends Service {
getAvatarService().clear(account); getAvatarService().clear(account);
updateAccountUi(); updateAccountUi();
} else { } else {
Contact contact = account.getRoster().getContact(avatar.owner); final Contact contact = account.getRoster().getContact(avatar.owner);
if (contact.setAvatar(avatar, previouslyOmittedPepFetch)) { contact.setAvatar(avatar, previouslyOmittedPepFetch);
syncRoster(account); syncRoster(account);
getAvatarService().clear(contact); getAvatarService().clear(contact);
updateRosterUi(); updateRosterUi();
} }
}
updateConversationUi(); updateConversationUi();
} else { } else {
Conversation conversation = find(account, avatar.owner.asBareJid()); Conversation conversation = find(account, avatar.owner.asBareJid());
@ -3778,7 +3776,7 @@ public class XmppConnectionService extends Service {
} }
if (user.getRealJid() != null) { if (user.getRealJid() != null) {
Contact contact = account.getRoster().getContact(user.getRealJid()); Contact contact = account.getRoster().getContact(user.getRealJid());
if (contact.setAvatar(avatar)) { contact.setAvatar(avatar);
syncRoster(account); syncRoster(account);
getAvatarService().clear(contact); getAvatarService().clear(contact);
updateRosterUi(); updateRosterUi();
@ -3790,7 +3788,6 @@ public class XmppConnectionService extends Service {
} }
} }
} }
}
}); });
} }