From 1985f6bdec7852eee549ffff3d82092aac447129 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 21 Sep 2018 12:27:58 +0200 Subject: [PATCH] store avatars received over muc presence in contact --- .../siacs/conversations/entities/Contact.java | 6 +- .../conversations/entities/MucOptions.java | 1525 ++++++++--------- .../conversations/parser/PresenceParser.java | 8 + .../persistance/DatabaseBackend.java | 2 +- .../conversations/services/AvatarService.java | 20 +- .../services/XmppConnectionService.java | 8 + .../ui/ConversationFragment.java | 10 +- 7 files changed, 797 insertions(+), 782 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Contact.java b/src/main/java/eu/siacs/conversations/entities/Contact.java index eeab0e999..f8bc21c7d 100644 --- a/src/main/java/eu/siacs/conversations/entities/Contact.java +++ b/src/main/java/eu/siacs/conversations/entities/Contact.java @@ -431,10 +431,14 @@ public class Contact implements ListItem, Blockable { } } - public String getAvatar() { + public String getAvatarFilename() { return avatar == null ? null : avatar.getFilename(); } + public Avatar getAvatar() { + return avatar; + } + public boolean mutualPresenceSubscription() { return getOption(Options.FROM) && getOption(Options.TO); } diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index c078419c2..ef2e7243c 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -23,819 +23,810 @@ import rocks.xmpp.addr.Jid; public class MucOptions { - private boolean mAutoPushConfiguration = true; - - public Account getAccount() { - return this.conversation.getAccount(); - } - - public boolean setSelf(User user) { - this.self = user; - final boolean roleChanged = this.conversation.setAttribute("role",user.role.toString()); - final boolean affiliationChanged = this.conversation.setAttribute("affiliation",user.affiliation.toString()); - return roleChanged || affiliationChanged; - } - - public void changeAffiliation(Jid jid, Affiliation affiliation) { - User user = findUserByRealJid(jid); - synchronized (users) { - if (user != null && user.getRole() == Role.NONE) { - users.remove(user); - if (affiliation.ranks(Affiliation.MEMBER)) { - user.affiliation = affiliation; - users.add(user); - } - } - } - } - - public void flagNoAutoPushConfiguration() { - mAutoPushConfiguration = false; - } - - public boolean autoPushConfiguration() { - return mAutoPushConfiguration; - } - - public boolean isSelf(Jid counterpart) { - return counterpart.equals(self.getFullJid()); - } - - public void resetChatState() { - synchronized (users) { - for (User user : users) { - user.chatState = Config.DEFAULT_CHATSTATE; - } - } - } - - public boolean mamSupport() { - return MessageArchiveService.Version.has(getFeatures()); - } - - public enum Affiliation { - OWNER(4, R.string.owner), - ADMIN(3, R.string.admin), - MEMBER(2, R.string.member), - OUTCAST(0, R.string.outcast), - NONE(1, R.string.no_affiliation); - - Affiliation(int rank, int resId) { - this.resId = resId; - this.rank = rank; - } - - private int resId; - private int rank; - - public int getResId() { - return resId; - } - - @Override - public String toString() { - return name().toLowerCase(Locale.US); - } - - public boolean outranks(Affiliation affiliation) { - return rank > affiliation.rank; - } - - public boolean ranks(Affiliation affiliation) { - return rank >= affiliation.rank; - } - - public static Affiliation of(@Nullable String value) { - if (value == null) { - return NONE; - } - try { - return Affiliation.valueOf(value.toUpperCase(Locale.US)); - } catch (IllegalArgumentException e) { - return NONE; - } - } - } - - public enum Role { - MODERATOR(R.string.moderator, 3), - VISITOR(R.string.visitor, 1), - PARTICIPANT(R.string.participant, 2), - NONE(R.string.no_role, 0); - - Role(int resId, int rank) { - this.resId = resId; - this.rank = rank; - } - - private int resId; - private int rank; - - public int getResId() { - return resId; - } - - @Override - public String toString() { - return name().toLowerCase(Locale.US); - } - - public boolean ranks(Role role) { - return rank >= role.rank; - } - - public static Role of(@Nullable String value) { - if (value == null) { - return NONE; - } - try { - return Role.valueOf(value.toUpperCase(Locale.US)); - } catch (IllegalArgumentException e) { - return NONE; - } - } - } - - public enum Error { - NO_RESPONSE, - SERVER_NOT_FOUND, - NONE, - NICK_IN_USE, - PASSWORD_REQUIRED, - BANNED, - MEMBERS_ONLY, - RESOURCE_CONSTRAINT, - KICKED, - SHUTDOWN, - DESTROYED, - INVALID_NICK, - UNKNOWN - } - - public static final String STATUS_CODE_SELF_PRESENCE = "110"; - public static final String STATUS_CODE_ROOM_CREATED = "201"; - public static final String STATUS_CODE_BANNED = "301"; - public static final String STATUS_CODE_CHANGED_NICK = "303"; - public static final String STATUS_CODE_KICKED = "307"; - public static final String STATUS_CODE_AFFILIATION_CHANGE = "321"; - public static final String STATUS_CODE_LOST_MEMBERSHIP = "322"; - public static final String STATUS_CODE_SHUTDOWN = "332"; - - private interface OnEventListener { - void onSuccess(); - - void onFailure(); - } - - public interface OnRenameListener extends OnEventListener { - - } - - public static class User implements Comparable { - private Role role = Role.NONE; - private Affiliation affiliation = Affiliation.NONE; - private Jid realJid; - private Jid fullJid; - private long pgpKeyId = 0; - private Avatar avatar; - private MucOptions options; - private ChatState chatState = Config.DEFAULT_CHATSTATE; - - public User(MucOptions options, Jid from) { - this.options = options; - this.fullJid = from; - } - - public String getName() { - return fullJid == null ? null : fullJid.getResource(); - } - - public void setRealJid(Jid jid) { - this.realJid = jid != null ? jid.asBareJid() : null; - } - - public Role getRole() { - return this.role; - } - - public void setRole(String role) { - this.role = Role.of(role); - } - - public Affiliation getAffiliation() { - return this.affiliation; - } - - public void setAffiliation(String affiliation) { - this.affiliation = Affiliation.of(affiliation); - } - - public void setPgpKeyId(long id) { - this.pgpKeyId = id; - } - - public long getPgpKeyId() { - if (this.pgpKeyId != 0) { - return this.pgpKeyId; - } else if (realJid != null) { - return getAccount().getRoster().getContact(realJid).getPgpKeyId(); - } else { - return 0; - } - } - - public Contact getContact() { - if (fullJid != null) { - return getAccount().getRoster().getContactFromRoster(realJid); - } else if (realJid != null) { - return getAccount().getRoster().getContact(realJid); - } else { - return null; - } - } - - public boolean setAvatar(Avatar avatar) { - if (this.avatar != null && this.avatar.equals(avatar)) { - return false; - } else { - this.avatar = avatar; - return true; - } - } - - public String getAvatar() { - return avatar == null ? null : avatar.getFilename(); - } - - public Account getAccount() { - return options.getAccount(); - } - - public Conversation getConversation() { - return options.getConversation(); - } - - public Jid getFullJid() { - return fullJid; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - User user = (User) o; - - if (role != user.role) return false; - if (affiliation != user.affiliation) return false; - if (realJid != null ? !realJid.equals(user.realJid) : user.realJid != null) - return false; - return fullJid != null ? fullJid.equals(user.fullJid) : user.fullJid == null; - - } - - public boolean isDomain() { - return realJid != null && realJid.getLocal() == null && role == Role.NONE; - } - - @Override - public int hashCode() { - int result = role != null ? role.hashCode() : 0; - result = 31 * result + (affiliation != null ? affiliation.hashCode() : 0); - result = 31 * result + (realJid != null ? realJid.hashCode() : 0); - result = 31 * result + (fullJid != null ? fullJid.hashCode() : 0); - return result; - } - - @Override - public String toString() { - return "[fulljid:" + String.valueOf(fullJid) + ",realjid:" + String.valueOf(realJid) + ",affiliation" + affiliation.toString() + "]"; - } - - public boolean realJidMatchesAccount() { - return realJid != null && realJid.equals(options.account.getJid().asBareJid()); - } - - @Override - public int compareTo(@NonNull User another) { - if (another.getAffiliation().outranks(getAffiliation())) { - return 1; - } else if (getAffiliation().outranks(another.getAffiliation())) { - return -1; - } else { - return getComparableName().compareToIgnoreCase(another.getComparableName()); - } - } - - - private String getComparableName() { - Contact contact = getContact(); - if (contact != null) { - return contact.getDisplayName(); - } else { - String name = getName(); - return name == null ? "" : name; - } - } - - public Jid getRealJid() { - return realJid; - } - - public boolean setChatState(ChatState chatState) { - if (this.chatState == chatState) { - return false; - } - this.chatState = chatState; - return true; - } - } - - private Account account; - private final Set users = new HashSet<>(); - private ServiceDiscoveryResult serviceDiscoveryResult; - private final Conversation conversation; - private boolean isOnline = false; - private Error error = Error.NONE; - public OnRenameListener onRenameListener = null; - private User self; - private String password = null; - - public MucOptions(Conversation conversation) { - this.account = conversation.getAccount(); - this.conversation = conversation; - this.self = new User(this, createJoinJid(getProposedNick())); - this.self.affiliation = Affiliation.of(conversation.getAttribute("affiliation")); - this.self.role = Role.of(conversation.getAttribute("role")); - } - - public boolean updateConfiguration(ServiceDiscoveryResult serviceDiscoveryResult) { - this.serviceDiscoveryResult = serviceDiscoveryResult; - String name; - Field roomConfigName = getRoomInfoForm().getFieldByName("muc#roomconfig_roomname"); - if (roomConfigName != null) { - name = roomConfigName.getValue(); - } else { - List identities = serviceDiscoveryResult.getIdentities(); - String identityName = identities.size() > 0 ? identities.get(0).getName() : null; - final Jid jid = conversation.getJid(); - if (identityName != null && !identityName.equals(jid == null ? null : jid.getEscapedLocal())) { - name = identityName; - } else { - name = null; - } - } - boolean changed = conversation.setAttribute("muc_name", name); - changed |= conversation.setAttribute(Conversation.ATTRIBUTE_MEMBERS_ONLY, this.hasFeature("muc_membersonly")); - changed |= conversation.setAttribute(Conversation.ATTRIBUTE_MODERATED, this.hasFeature("muc_moderated")); - changed |= conversation.setAttribute(Conversation.ATTRIBUTE_NON_ANONYMOUS, this.hasFeature("muc_nonanonymous")); - return changed; - } - - - private Data getRoomInfoForm() { - final List forms = serviceDiscoveryResult == null ? Collections.emptyList() : serviceDiscoveryResult.forms; - return forms.size() == 0 ? new Data() : forms.get(0); - } - - public String getAvatar() { - return account.getRoster().getContact(conversation.getJid()).getAvatar(); - } - - public boolean hasFeature(String feature) { - return this.serviceDiscoveryResult != null && this.serviceDiscoveryResult.features.contains(feature); - } - - public boolean hasVCards() { - return hasFeature("vcard-temp"); + public static final String STATUS_CODE_SELF_PRESENCE = "110"; + public static final String STATUS_CODE_ROOM_CREATED = "201"; + public static final String STATUS_CODE_BANNED = "301"; + public static final String STATUS_CODE_CHANGED_NICK = "303"; + public static final String STATUS_CODE_KICKED = "307"; + public static final String STATUS_CODE_AFFILIATION_CHANGE = "321"; + public static final String STATUS_CODE_LOST_MEMBERSHIP = "322"; + public static final String STATUS_CODE_SHUTDOWN = "332"; + private final Set users = new HashSet<>(); + private final Conversation conversation; + public OnRenameListener onRenameListener = null; + private boolean mAutoPushConfiguration = true; + private Account account; + private ServiceDiscoveryResult serviceDiscoveryResult; + private boolean isOnline = false; + private Error error = Error.NONE; + private User self; + private String password = null; + public MucOptions(Conversation conversation) { + this.account = conversation.getAccount(); + this.conversation = conversation; + this.self = new User(this, createJoinJid(getProposedNick())); + this.self.affiliation = Affiliation.of(conversation.getAttribute("affiliation")); + this.self.role = Role.of(conversation.getAttribute("role")); } - public boolean canInvite() { - Field field = getRoomInfoForm().getFieldByName("muc#roomconfig_allowinvites"); - return !membersOnly() || self.getRole().ranks(Role.MODERATOR) || (field != null && "1".equals(field.getValue())); - } + public Account getAccount() { + return this.conversation.getAccount(); + } - public boolean canChangeSubject() { - Field field = getRoomInfoForm().getFieldByName("muc#roominfo_changesubject"); - return self.getRole().ranks(Role.MODERATOR) || (field != null && "1".equals(field.getValue())); - } + public boolean setSelf(User user) { + this.self = user; + final boolean roleChanged = this.conversation.setAttribute("role", user.role.toString()); + final boolean affiliationChanged = this.conversation.setAttribute("affiliation", user.affiliation.toString()); + return roleChanged || affiliationChanged; + } - public boolean allowPm() { - final Field field = getRoomInfoForm().getFieldByName("muc#roomconfig_allowpm"); - if (field == null) { - return true; //fall back if field does not exists - } - if ("anyone".equals(field.getValue())) { - return true; - } else if ("participants".equals(field.getValue())) { - return self.getRole().ranks(Role.PARTICIPANT); - } else if ("moderators".equals(field.getValue())) { - return self.getRole().ranks(Role.MODERATOR); - } else { - return false; - } - } + public void changeAffiliation(Jid jid, Affiliation affiliation) { + User user = findUserByRealJid(jid); + synchronized (users) { + if (user != null && user.getRole() == Role.NONE) { + users.remove(user); + if (affiliation.ranks(Affiliation.MEMBER)) { + user.affiliation = affiliation; + users.add(user); + } + } + } + } - public boolean participating() { - return self.getRole().ranks(Role.PARTICIPANT) || !moderated(); - } + public void flagNoAutoPushConfiguration() { + mAutoPushConfiguration = false; + } - public boolean membersOnly() { - return conversation.getBooleanAttribute(Conversation.ATTRIBUTE_MEMBERS_ONLY, false); - } + public boolean autoPushConfiguration() { + return mAutoPushConfiguration; + } + public boolean isSelf(Jid counterpart) { + return counterpart.equals(self.getFullJid()); + } - public List getFeatures() { - return this.serviceDiscoveryResult != null ? this.serviceDiscoveryResult.features : Collections.emptyList(); - } + public void resetChatState() { + synchronized (users) { + for (User user : users) { + user.chatState = Config.DEFAULT_CHATSTATE; + } + } + } - public boolean nonanonymous() { - return conversation.getBooleanAttribute(Conversation.ATTRIBUTE_NON_ANONYMOUS, false); - } + public boolean mamSupport() { + return MessageArchiveService.Version.has(getFeatures()); + } - public boolean isPrivateAndNonAnonymous() { - return membersOnly() && nonanonymous(); - } + public boolean updateConfiguration(ServiceDiscoveryResult serviceDiscoveryResult) { + this.serviceDiscoveryResult = serviceDiscoveryResult; + String name; + Field roomConfigName = getRoomInfoForm().getFieldByName("muc#roomconfig_roomname"); + if (roomConfigName != null) { + name = roomConfigName.getValue(); + } else { + List identities = serviceDiscoveryResult.getIdentities(); + String identityName = identities.size() > 0 ? identities.get(0).getName() : null; + final Jid jid = conversation.getJid(); + if (identityName != null && !identityName.equals(jid == null ? null : jid.getEscapedLocal())) { + name = identityName; + } else { + name = null; + } + } + boolean changed = conversation.setAttribute("muc_name", name); + changed |= conversation.setAttribute(Conversation.ATTRIBUTE_MEMBERS_ONLY, this.hasFeature("muc_membersonly")); + changed |= conversation.setAttribute(Conversation.ATTRIBUTE_MODERATED, this.hasFeature("muc_moderated")); + changed |= conversation.setAttribute(Conversation.ATTRIBUTE_NON_ANONYMOUS, this.hasFeature("muc_nonanonymous")); + return changed; + } - public boolean moderated() { - return conversation.getBooleanAttribute(Conversation.ATTRIBUTE_MODERATED, false); - } + private Data getRoomInfoForm() { + final List forms = serviceDiscoveryResult == null ? Collections.emptyList() : serviceDiscoveryResult.forms; + return forms.size() == 0 ? new Data() : forms.get(0); + } - public User deleteUser(Jid jid) { - User user = findUserByFullJid(jid); - if (user != null) { - synchronized (users) { - users.remove(user); - boolean realJidInMuc = false; - for (User u : users) { - if (user.realJid != null && user.realJid.equals(u.realJid)) { - realJidInMuc = true; - break; - } - } - boolean self = user.realJid != null && user.realJid.equals(account.getJid().asBareJid()); - if (membersOnly() - && nonanonymous() - && user.affiliation.ranks(Affiliation.MEMBER) - && user.realJid != null - && !realJidInMuc - && !self) { - user.role = Role.NONE; - user.avatar = null; - user.fullJid = null; - users.add(user); - } - } - } - return user; - } + public String getAvatar() { + return account.getRoster().getContact(conversation.getJid()).getAvatarFilename(); + } - //returns true if real jid was new; - public boolean updateUser(User user) { - User old; - boolean realJidFound = false; - if (user.fullJid == null && user.realJid != null) { - old = findUserByRealJid(user.realJid); - realJidFound = old != null; - if (old != null) { - if (old.fullJid != null) { - return false; //don't add. user already exists - } else { - synchronized (users) { - users.remove(old); - } - } - } - } else if (user.realJid != null) { - old = findUserByRealJid(user.realJid); - realJidFound = old != null; - synchronized (users) { - if (old != null && old.fullJid == null) { - users.remove(old); - } - } - } - old = findUserByFullJid(user.getFullJid()); - synchronized (this.users) { - if (old != null) { - users.remove(old); - } - boolean fullJidIsSelf = isOnline && user.getFullJid() != null && user.getFullJid().equals(self.getFullJid()); - if ((!membersOnly() || user.getAffiliation().ranks(Affiliation.MEMBER)) - && user.getAffiliation().outranks(Affiliation.OUTCAST) - && !fullJidIsSelf) { - this.users.add(user); - return !realJidFound && user.realJid != null; - } - } - return false; - } + public boolean hasFeature(String feature) { + return this.serviceDiscoveryResult != null && this.serviceDiscoveryResult.features.contains(feature); + } - public User findUserByFullJid(Jid jid) { - if (jid == null) { - return null; - } - synchronized (users) { - for (User user : users) { - if (jid.equals(user.getFullJid())) { - return user; - } - } - } - return null; - } + public boolean hasVCards() { + return hasFeature("vcard-temp"); + } - public User findUserByRealJid(Jid jid) { - if (jid == null) { - return null; - } - synchronized (users) { - for (User user : users) { - if (jid.equals(user.realJid)) { - return user; - } - } - } - return null; - } + public boolean canInvite() { + Field field = getRoomInfoForm().getFieldByName("muc#roomconfig_allowinvites"); + return !membersOnly() || self.getRole().ranks(Role.MODERATOR) || (field != null && "1".equals(field.getValue())); + } - public User findOrCreateUserByRealJid(Jid jid) { - User user = findUserByRealJid(jid); - if (user == null) { - user = new User(this, null); - user.setRealJid(jid); - } - return user; - } + public boolean canChangeSubject() { + Field field = getRoomInfoForm().getFieldByName("muc#roominfo_changesubject"); + return self.getRole().ranks(Role.MODERATOR) || (field != null && "1".equals(field.getValue())); + } - public User findUser(ReadByMarker readByMarker) { - if (readByMarker.getRealJid() != null) { - User user = findUserByRealJid(readByMarker.getRealJid().asBareJid()); - if (user == null) { - user = new User(this, readByMarker.getFullJid()); - user.setRealJid(readByMarker.getRealJid()); - } - return user; - } else if (readByMarker.getFullJid() != null) { - return findUserByFullJid(readByMarker.getFullJid()); - } else { - return null; - } - } + public boolean allowPm() { + final Field field = getRoomInfoForm().getFieldByName("muc#roomconfig_allowpm"); + if (field == null) { + return true; //fall back if field does not exists + } + if ("anyone".equals(field.getValue())) { + return true; + } else if ("participants".equals(field.getValue())) { + return self.getRole().ranks(Role.PARTICIPANT); + } else if ("moderators".equals(field.getValue())) { + return self.getRole().ranks(Role.MODERATOR); + } else { + return false; + } + } - public boolean isContactInRoom(Contact contact) { - return findUserByRealJid(contact.getJid().asBareJid()) != null; - } + public boolean participating() { + return self.getRole().ranks(Role.PARTICIPANT) || !moderated(); + } - public boolean isUserInRoom(Jid jid) { - return findUserByFullJid(jid) != null; - } + public boolean membersOnly() { + return conversation.getBooleanAttribute(Conversation.ATTRIBUTE_MEMBERS_ONLY, false); + } - public void setError(Error error) { - this.isOnline = isOnline && error == Error.NONE; - this.error = error; - } + public List getFeatures() { + return this.serviceDiscoveryResult != null ? this.serviceDiscoveryResult.features : Collections.emptyList(); + } - public boolean setOnline() { - boolean before = this.isOnline; - this.isOnline = true; - return !before; - } + public boolean nonanonymous() { + return conversation.getBooleanAttribute(Conversation.ATTRIBUTE_NON_ANONYMOUS, false); + } - public ArrayList getUsers() { - return getUsers(true); - } + public boolean isPrivateAndNonAnonymous() { + return membersOnly() && nonanonymous(); + } - public ArrayList getUsers(boolean includeOffline) { - synchronized (users) { - ArrayList users = new ArrayList<>(); - for (User user : this.users) { - if (!user.isDomain() && (includeOffline || user.getRole().ranks(Role.PARTICIPANT))) { - users.add(user); - } - } - return users; - } - } + public boolean moderated() { + return conversation.getBooleanAttribute(Conversation.ATTRIBUTE_MODERATED, false); + } - public ArrayList getUsersWithChatState(ChatState state, int max) { - synchronized (users) { - ArrayList list = new ArrayList<>(); - for (User user : users) { - if (user.chatState == state) { - list.add(user); - if (list.size() >= max) { - break; - } - } - } - return list; - } - } + public User deleteUser(Jid jid) { + User user = findUserByFullJid(jid); + if (user != null) { + synchronized (users) { + users.remove(user); + boolean realJidInMuc = false; + for (User u : users) { + if (user.realJid != null && user.realJid.equals(u.realJid)) { + realJidInMuc = true; + break; + } + } + boolean self = user.realJid != null && user.realJid.equals(account.getJid().asBareJid()); + if (membersOnly() + && nonanonymous() + && user.affiliation.ranks(Affiliation.MEMBER) + && user.realJid != null + && !realJidInMuc + && !self) { + user.role = Role.NONE; + user.avatar = null; + user.fullJid = null; + users.add(user); + } + } + } + return user; + } - public List getUsers(int max) { - ArrayList subset = new ArrayList<>(); - HashSet jids = new HashSet<>(); - jids.add(account.getJid().asBareJid()); - synchronized (users) { - for (User user : users) { - if (user.getRealJid() == null || (user.getRealJid().getLocal() != null && jids.add(user.getRealJid()))) { - subset.add(user); - } - if (subset.size() >= max) { - break; - } - } - } - return subset; - } + //returns true if real jid was new; + public boolean updateUser(User user) { + User old; + boolean realJidFound = false; + if (user.fullJid == null && user.realJid != null) { + old = findUserByRealJid(user.realJid); + realJidFound = old != null; + if (old != null) { + if (old.fullJid != null) { + return false; //don't add. user already exists + } else { + synchronized (users) { + users.remove(old); + } + } + } + } else if (user.realJid != null) { + old = findUserByRealJid(user.realJid); + realJidFound = old != null; + synchronized (users) { + if (old != null && old.fullJid == null) { + users.remove(old); + } + } + } + old = findUserByFullJid(user.getFullJid()); + synchronized (this.users) { + if (old != null) { + users.remove(old); + } + boolean fullJidIsSelf = isOnline && user.getFullJid() != null && user.getFullJid().equals(self.getFullJid()); + if ((!membersOnly() || user.getAffiliation().ranks(Affiliation.MEMBER)) + && user.getAffiliation().outranks(Affiliation.OUTCAST) + && !fullJidIsSelf) { + this.users.add(user); + return !realJidFound && user.realJid != null; + } + } + return false; + } - public int getUserCount() { - synchronized (users) { - return users.size(); - } - } + public User findUserByFullJid(Jid jid) { + if (jid == null) { + return null; + } + synchronized (users) { + for (User user : users) { + if (jid.equals(user.getFullJid())) { + return user; + } + } + } + return null; + } - private String getProposedNick() { - if (conversation.getBookmark() != null - && conversation.getBookmark().getNick() != null - && !conversation.getBookmark().getNick().trim().isEmpty()) { - return conversation.getBookmark().getNick().trim(); - } else if (!conversation.getJid().isBareJid()) { - return conversation.getJid().getResource(); - } else { - return JidHelper.localPartOrFallback(account.getJid()); - } - } + public User findUserByRealJid(Jid jid) { + if (jid == null) { + return null; + } + synchronized (users) { + for (User user : users) { + if (jid.equals(user.realJid)) { + return user; + } + } + } + return null; + } - public String getActualNick() { - if (this.self.getName() != null) { - return this.self.getName(); - } else { - return this.getProposedNick(); - } - } + public User findOrCreateUserByRealJid(Jid jid, Jid fullJid) { + User user = findUserByRealJid(jid); + if (user == null) { + user = new User(this, fullJid); + user.setRealJid(jid); + } + return user; + } - public boolean online() { - return this.isOnline; - } + public User findUser(ReadByMarker readByMarker) { + if (readByMarker.getRealJid() != null) { + return findOrCreateUserByRealJid(readByMarker.getRealJid().asBareJid(), readByMarker.getFullJid()); + } else if (readByMarker.getFullJid() != null) { + return findUserByFullJid(readByMarker.getFullJid()); + } else { + return null; + } + } - public Error getError() { - return this.error; - } + public boolean isContactInRoom(Contact contact) { + return findUserByRealJid(contact.getJid().asBareJid()) != null; + } - public void setOnRenameListener(OnRenameListener listener) { - this.onRenameListener = listener; - } + public boolean isUserInRoom(Jid jid) { + return findUserByFullJid(jid) != null; + } - public void setOffline() { - synchronized (users) { - this.users.clear(); - } - this.error = Error.NO_RESPONSE; - this.isOnline = false; - } + public boolean setOnline() { + boolean before = this.isOnline; + this.isOnline = true; + return !before; + } - public User getSelf() { - return self; - } + public ArrayList getUsers() { + return getUsers(true); + } - public boolean setSubject(String subject) { - return this.conversation.setAttribute("subject", subject); - } + public ArrayList getUsers(boolean includeOffline) { + synchronized (users) { + ArrayList users = new ArrayList<>(); + for (User user : this.users) { + if (!user.isDomain() && (includeOffline || user.getRole().ranks(Role.PARTICIPANT))) { + users.add(user); + } + } + return users; + } + } - public String getSubject() { - return this.conversation.getAttribute("subject"); - } + public ArrayList getUsersWithChatState(ChatState state, int max) { + synchronized (users) { + ArrayList list = new ArrayList<>(); + for (User user : users) { + if (user.chatState == state) { + list.add(user); + if (list.size() >= max) { + break; + } + } + } + return list; + } + } - public String getName() { - return this.conversation.getAttribute("muc_name"); - } + public List getUsers(int max) { + ArrayList subset = new ArrayList<>(); + HashSet jids = new HashSet<>(); + jids.add(account.getJid().asBareJid()); + synchronized (users) { + for (User user : users) { + if (user.getRealJid() == null || (user.getRealJid().getLocal() != null && jids.add(user.getRealJid()))) { + subset.add(user); + } + if (subset.size() >= max) { + break; + } + } + } + return subset; + } - private List getFallbackUsersFromCryptoTargets() { - List users = new ArrayList<>(); - for (Jid jid : conversation.getAcceptedCryptoTargets()) { - User user = new User(this, null); - user.setRealJid(jid); - users.add(user); - } - return users; - } + public int getUserCount() { + synchronized (users) { + return users.size(); + } + } - public List getUsersRelevantForNameAndAvatar() { - final List users; - if (isOnline) { - users = getUsers(5); - } else { - users = getFallbackUsersFromCryptoTargets(); - } - return users; - } + private String getProposedNick() { + if (conversation.getBookmark() != null + && conversation.getBookmark().getNick() != null + && !conversation.getBookmark().getNick().trim().isEmpty()) { + return conversation.getBookmark().getNick().trim(); + } else if (!conversation.getJid().isBareJid()) { + return conversation.getJid().getResource(); + } else { + return JidHelper.localPartOrFallback(account.getJid()); + } + } - public String createNameFromParticipants() { - List users = getUsersRelevantForNameAndAvatar(); - if (users.size() >= 2) { - StringBuilder builder = new StringBuilder(); - for (User user : users) { - if (builder.length() != 0) { - builder.append(", "); - } - String name = UIHelper.getDisplayName(user); - if (name != null) { - builder.append(name.split("\\s+")[0]); - } - } - return builder.toString(); - } else { - return null; - } - } + public String getActualNick() { + if (this.self.getName() != null) { + return this.self.getName(); + } else { + return this.getProposedNick(); + } + } - public long[] getPgpKeyIds() { - List ids = new ArrayList<>(); - for (User user : this.users) { - if (user.getPgpKeyId() != 0) { - ids.add(user.getPgpKeyId()); - } - } - ids.add(account.getPgpId()); - long[] primitiveLongArray = new long[ids.size()]; - for (int i = 0; i < ids.size(); ++i) { - primitiveLongArray[i] = ids.get(i); - } - return primitiveLongArray; - } + public boolean online() { + return this.isOnline; + } - public boolean pgpKeysInUse() { - synchronized (users) { - for (User user : users) { - if (user.getPgpKeyId() != 0) { - return true; - } - } - } - return false; - } + public Error getError() { + return this.error; + } - public boolean everybodyHasKeys() { - synchronized (users) { - for (User user : users) { - if (user.getPgpKeyId() == 0) { - return false; - } - } - } - return true; - } + public void setError(Error error) { + this.isOnline = isOnline && error == Error.NONE; + this.error = error; + } - public Jid createJoinJid(String nick) { - try { - return Jid.of(this.conversation.getJid().asBareJid().toString() + "/" + nick); - } catch (final IllegalArgumentException e) { - return null; - } - } + public void setOnRenameListener(OnRenameListener listener) { + this.onRenameListener = listener; + } - public Jid getTrueCounterpart(Jid jid) { - if (jid.equals(getSelf().getFullJid())) { - return account.getJid().asBareJid(); - } - User user = findUserByFullJid(jid); - return user == null ? null : user.realJid; - } + public void setOffline() { + synchronized (users) { + this.users.clear(); + } + this.error = Error.NO_RESPONSE; + this.isOnline = false; + } - public String getPassword() { - this.password = conversation.getAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD); - if (this.password == null && conversation.getBookmark() != null - && conversation.getBookmark().getPassword() != null) { - return conversation.getBookmark().getPassword(); - } else { - return this.password; - } - } + public User getSelf() { + return self; + } - public void setPassword(String password) { - if (conversation.getBookmark() != null) { - conversation.getBookmark().setPassword(password); - } else { - this.password = password; - } - conversation.setAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD, password); - } + public boolean setSubject(String subject) { + return this.conversation.setAttribute("subject", subject); + } - public Conversation getConversation() { - return this.conversation; - } + public String getSubject() { + return this.conversation.getAttribute("subject"); + } - public List getMembers(final boolean includeDomains) { - ArrayList members = new ArrayList<>(); - synchronized (users) { - for (User user : users) { - if (user.affiliation.ranks(Affiliation.MEMBER) && user.realJid != null && (!user.isDomain() || includeDomains)) { - members.add(user.realJid); - } - } - } - return members; - } + public String getName() { + return this.conversation.getAttribute("muc_name"); + } + + private List getFallbackUsersFromCryptoTargets() { + List users = new ArrayList<>(); + for (Jid jid : conversation.getAcceptedCryptoTargets()) { + User user = new User(this, null); + user.setRealJid(jid); + users.add(user); + } + return users; + } + + public List getUsersRelevantForNameAndAvatar() { + final List users; + if (isOnline) { + users = getUsers(5); + } else { + users = getFallbackUsersFromCryptoTargets(); + } + return users; + } + + public String createNameFromParticipants() { + List users = getUsersRelevantForNameAndAvatar(); + if (users.size() >= 2) { + StringBuilder builder = new StringBuilder(); + for (User user : users) { + if (builder.length() != 0) { + builder.append(", "); + } + String name = UIHelper.getDisplayName(user); + if (name != null) { + builder.append(name.split("\\s+")[0]); + } + } + return builder.toString(); + } else { + return null; + } + } + + public long[] getPgpKeyIds() { + List ids = new ArrayList<>(); + for (User user : this.users) { + if (user.getPgpKeyId() != 0) { + ids.add(user.getPgpKeyId()); + } + } + ids.add(account.getPgpId()); + long[] primitiveLongArray = new long[ids.size()]; + for (int i = 0; i < ids.size(); ++i) { + primitiveLongArray[i] = ids.get(i); + } + return primitiveLongArray; + } + + public boolean pgpKeysInUse() { + synchronized (users) { + for (User user : users) { + if (user.getPgpKeyId() != 0) { + return true; + } + } + } + return false; + } + + public boolean everybodyHasKeys() { + synchronized (users) { + for (User user : users) { + if (user.getPgpKeyId() == 0) { + return false; + } + } + } + return true; + } + + public Jid createJoinJid(String nick) { + try { + return Jid.of(this.conversation.getJid().asBareJid().toString() + "/" + nick); + } catch (final IllegalArgumentException e) { + return null; + } + } + + public Jid getTrueCounterpart(Jid jid) { + if (jid.equals(getSelf().getFullJid())) { + return account.getJid().asBareJid(); + } + User user = findUserByFullJid(jid); + return user == null ? null : user.realJid; + } + + public String getPassword() { + this.password = conversation.getAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD); + if (this.password == null && conversation.getBookmark() != null + && conversation.getBookmark().getPassword() != null) { + return conversation.getBookmark().getPassword(); + } else { + return this.password; + } + } + + public void setPassword(String password) { + if (conversation.getBookmark() != null) { + conversation.getBookmark().setPassword(password); + } else { + this.password = password; + } + conversation.setAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD, password); + } + + public Conversation getConversation() { + return this.conversation; + } + + public List getMembers(final boolean includeDomains) { + ArrayList members = new ArrayList<>(); + synchronized (users) { + for (User user : users) { + if (user.affiliation.ranks(Affiliation.MEMBER) && user.realJid != null && (!user.isDomain() || includeDomains)) { + members.add(user.realJid); + } + } + } + return members; + } + + public enum Affiliation { + OWNER(4, R.string.owner), + ADMIN(3, R.string.admin), + MEMBER(2, R.string.member), + OUTCAST(0, R.string.outcast), + NONE(1, R.string.no_affiliation); + + private int resId; + private int rank; + Affiliation(int rank, int resId) { + this.resId = resId; + this.rank = rank; + } + + public static Affiliation of(@Nullable String value) { + if (value == null) { + return NONE; + } + try { + return Affiliation.valueOf(value.toUpperCase(Locale.US)); + } catch (IllegalArgumentException e) { + return NONE; + } + } + + public int getResId() { + return resId; + } + + @Override + public String toString() { + return name().toLowerCase(Locale.US); + } + + public boolean outranks(Affiliation affiliation) { + return rank > affiliation.rank; + } + + public boolean ranks(Affiliation affiliation) { + return rank >= affiliation.rank; + } + } + + public enum Role { + MODERATOR(R.string.moderator, 3), + VISITOR(R.string.visitor, 1), + PARTICIPANT(R.string.participant, 2), + NONE(R.string.no_role, 0); + + private int resId; + private int rank; + Role(int resId, int rank) { + this.resId = resId; + this.rank = rank; + } + + public static Role of(@Nullable String value) { + if (value == null) { + return NONE; + } + try { + return Role.valueOf(value.toUpperCase(Locale.US)); + } catch (IllegalArgumentException e) { + return NONE; + } + } + + public int getResId() { + return resId; + } + + @Override + public String toString() { + return name().toLowerCase(Locale.US); + } + + public boolean ranks(Role role) { + return rank >= role.rank; + } + } + + public enum Error { + NO_RESPONSE, + SERVER_NOT_FOUND, + NONE, + NICK_IN_USE, + PASSWORD_REQUIRED, + BANNED, + MEMBERS_ONLY, + RESOURCE_CONSTRAINT, + KICKED, + SHUTDOWN, + DESTROYED, + INVALID_NICK, + UNKNOWN + } + + private interface OnEventListener { + void onSuccess(); + + void onFailure(); + } + + public interface OnRenameListener extends OnEventListener { + + } + + public static class User implements Comparable { + private Role role = Role.NONE; + private Affiliation affiliation = Affiliation.NONE; + private Jid realJid; + private Jid fullJid; + private long pgpKeyId = 0; + private Avatar avatar; + private MucOptions options; + private ChatState chatState = Config.DEFAULT_CHATSTATE; + + public User(MucOptions options, Jid fullJid) { + this.options = options; + this.fullJid = fullJid; + } + + public String getName() { + return fullJid == null ? null : fullJid.getResource(); + } + + public Role getRole() { + return this.role; + } + + public void setRole(String role) { + this.role = Role.of(role); + } + + public Affiliation getAffiliation() { + return this.affiliation; + } + + public void setAffiliation(String affiliation) { + this.affiliation = Affiliation.of(affiliation); + } + + public long getPgpKeyId() { + if (this.pgpKeyId != 0) { + return this.pgpKeyId; + } else if (realJid != null) { + return getAccount().getRoster().getContact(realJid).getPgpKeyId(); + } else { + return 0; + } + } + + public void setPgpKeyId(long id) { + this.pgpKeyId = id; + } + + public Contact getContact() { + if (fullJid != null) { + return getAccount().getRoster().getContactFromRoster(realJid); + } else if (realJid != null) { + return getAccount().getRoster().getContact(realJid); + } else { + return null; + } + } + + public boolean setAvatar(Avatar avatar) { + if (this.avatar != null && this.avatar.equals(avatar)) { + return false; + } else { + this.avatar = avatar; + return true; + } + } + + public String getAvatar() { + if (avatar != null) { + return avatar.getFilename(); + } + Avatar avatar = realJid != null ? getAccount().getRoster().getContact(realJid).getAvatar() : null; + return avatar == null ? null : avatar.getFilename(); + } + + public Account getAccount() { + return options.getAccount(); + } + + public Conversation getConversation() { + return options.getConversation(); + } + + public Jid getFullJid() { + return fullJid; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + User user = (User) o; + + if (role != user.role) return false; + if (affiliation != user.affiliation) return false; + if (realJid != null ? !realJid.equals(user.realJid) : user.realJid != null) + return false; + return fullJid != null ? fullJid.equals(user.fullJid) : user.fullJid == null; + + } + + public boolean isDomain() { + return realJid != null && realJid.getLocal() == null && role == Role.NONE; + } + + @Override + public int hashCode() { + int result = role != null ? role.hashCode() : 0; + result = 31 * result + (affiliation != null ? affiliation.hashCode() : 0); + result = 31 * result + (realJid != null ? realJid.hashCode() : 0); + result = 31 * result + (fullJid != null ? fullJid.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "[fulljid:" + String.valueOf(fullJid) + ",realjid:" + String.valueOf(realJid) + ",affiliation" + affiliation.toString() + "]"; + } + + public boolean realJidMatchesAccount() { + return realJid != null && realJid.equals(options.account.getJid().asBareJid()); + } + + @Override + public int compareTo(@NonNull User another) { + if (another.getAffiliation().outranks(getAffiliation())) { + return 1; + } else if (getAffiliation().outranks(another.getAffiliation())) { + return -1; + } else { + return getComparableName().compareToIgnoreCase(another.getComparableName()); + } + } + + private String getComparableName() { + Contact contact = getContact(); + if (contact != null) { + return contact.getDisplayName(); + } else { + String name = getName(); + return name == null ? "" : name; + } + } + + public Jid getRealJid() { + return realJid; + } + + public void setRealJid(Jid jid) { + this.realJid = jid != null ? jid.asBareJid() : null; + } + + public boolean setChatState(ChatState chatState) { + if (this.chatState == chatState) { + return false; + } + this.chatState = chatState; + return true; + } + } } diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index 064015cdc..1208c2113 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -119,6 +119,14 @@ public class PresenceParser extends AbstractParser implements if (user.setAvatar(avatar)) { mXmppConnectionService.getAvatarService().clear(user); } + if (user.getRealJid() != null) { + Contact c = conversation.getAccount().getRoster().getContact(user.getRealJid()); + if (c.setAvatar(avatar)) { + mXmppConnectionService.syncRoster(conversation.getAccount()); + mXmppConnectionService.getAvatarService().clear(c); + mXmppConnectionService.updateRosterUi(); + } + } } else if (mXmppConnectionService.isDataSaverDisabled()) { mXmppConnectionService.fetchAvatar(mucOptions.getAccount(), avatar); } diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 2ea77aac0..dd79e7c24 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -911,7 +911,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { final SQLiteDatabase db = this.getWritableDatabase(); db.beginTransaction(); for (Contact contact : roster.getContacts()) { - if (contact.getOption(Contact.Options.IN_ROSTER) || contact.getAvatar() != null) { + if (contact.getOption(Contact.Options.IN_ROSTER) || contact.getAvatarFilename() != null) { db.insert(Contact.TABLENAME, null, contact.getContentValues()); } else { String where = Contact.ACCOUNT + "=? AND " + Contact.JID + "=?"; diff --git a/src/main/java/eu/siacs/conversations/services/AvatarService.java b/src/main/java/eu/siacs/conversations/services/AvatarService.java index 0ae38edf5..f084a3a11 100644 --- a/src/main/java/eu/siacs/conversations/services/AvatarService.java +++ b/src/main/java/eu/siacs/conversations/services/AvatarService.java @@ -69,8 +69,8 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { if (contact.getProfilePhoto() != null) { avatar = mXmppConnectionService.getFileBackend().cropCenterSquare(Uri.parse(contact.getProfilePhoto()), size); } - if (avatar == null && contact.getAvatar() != null) { - avatar = mXmppConnectionService.getFileBackend().getAvatar(contact.getAvatar(), size); + if (avatar == null && contact.getAvatarFilename() != null) { + avatar = mXmppConnectionService.getFileBackend().getAvatar(contact.getAvatarFilename(), size); } if (avatar == null) { avatar = get(contact.getDisplayName(), contact.getJid().asBareJid().toString(), size, cachedOnly); @@ -128,7 +128,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { public Bitmap get(final MucOptions.User user, final int size, boolean cachedOnly) { Contact c = user.getContact(); - if (c != null && (c.getProfilePhoto() != null || c.getAvatar() != null || user.getAvatar() == null)) { + if (c != null && (c.getProfilePhoto() != null || c.getAvatarFilename() != null || user.getAvatar() == null)) { return get(c, size, cachedOnly); } else { return getImpl(user, size, cachedOnly); @@ -165,6 +165,10 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { } } for (Conversation conversation : mXmppConnectionService.findAllConferencesWith(contact)) { + MucOptions.User user = conversation.getMucOptions().findUserByRealJid(contact.getJid().asBareJid()); + if (user != null) { + clear(user); + } clear(conversation); } } @@ -216,7 +220,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { Jid jid = bookmark.getJid(); Account account = bookmark.getAccount(); Contact contact = jid == null ? null : account.getRoster().getContact(jid); - if (contact != null && contact.getAvatar() != null) { + if (contact != null && contact.getAvatarFilename() != null) { return get(contact, size, cachedOnly); } String seed = jid != null ? jid.asBareJid().toString() : null; @@ -400,14 +404,14 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { return get(message.getCounterparts(), size, cachedOnly); } else if (message.getStatus() == Message.STATUS_RECEIVED) { Contact c = message.getContact(); - if (c != null && (c.getProfilePhoto() != null || c.getAvatar() != null)) { + if (c != null && (c.getProfilePhoto() != null || c.getAvatarFilename() != null)) { return get(c, size, cachedOnly); } else if (conversation instanceof Conversation && message.getConversation().getMode() == Conversation.MODE_MULTI) { final Jid trueCounterpart = message.getTrueCounterpart(); final MucOptions mucOptions = ((Conversation) conversation).getMucOptions(); MucOptions.User user; if (trueCounterpart != null) { - user = mucOptions.findUserByRealJid(trueCounterpart); + user = mucOptions.findOrCreateUserByRealJid(trueCounterpart, message.getCounterpart()); } else { user = mucOptions.findUserByFullJid(message.getCounterpart()); } @@ -508,9 +512,9 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { Uri uri = null; if (contact.getProfilePhoto() != null) { uri = Uri.parse(contact.getProfilePhoto()); - } else if (contact.getAvatar() != null) { + } else if (contact.getAvatarFilename() != null) { uri = mXmppConnectionService.getFileBackend().getAvatarUri( - contact.getAvatar()); + contact.getAvatarFilename()); } if (drawTile(canvas, uri, left, top, right, bottom)) { return true; diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index e886c6b03..043991f07 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -3114,6 +3114,14 @@ public class XmppConnectionService extends Service { updateConversationUi(); updateMucRosterUi(); } + if (user.getRealJid() != null) { + Contact contact = account.getRoster().getContact(user.getRealJid()); + if (contact.setAvatar(avatar)) { + syncRoster(account); + getAvatarService().clear(contact); + updateRosterUi(); + } + } } } } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index a1112fda4..26c59003c 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -874,7 +874,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke attachLocationToConversation(conversation, attachment.getUri()); } else if (attachment.getType() == Attachment.Type.IMAGE) { Log.d(Config.LOGTAG, "ConversationsActivity.commitAttachments() - attaching image to conversations. CHOOSE_IMAGE"); - attachImageToConversation(conversation, attachment.getUri()); + attachImageToConversation(conversation, attachment.getUri()); } else { Log.d(Config.LOGTAG, "ConversationsActivity.commitAttachments() - attaching file to conversations. CHOOSE_FILE/RECORD_VOICE/RECORD_VIDEO"); attachFileToConversation(conversation, attachment.getUri(), attachment.getMime()); @@ -901,7 +901,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke switch (requestCode) { case ATTACHMENT_CHOICE_TAKE_PHOTO: if (pendingTakePhotoUri.clear()) { - Log.d(Config.LOGTAG,"cleared pending photo uri after negative activity result"); + Log.d(Config.LOGTAG, "cleared pending photo uri after negative activity result"); } break; } @@ -1033,7 +1033,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke Jid tcp = message.getTrueCounterpart(); Jid cp = message.getCounterpart(); if (cp != null && !cp.isBareJid()) { - User userByRealJid = tcp != null ? conversation.getMucOptions().findOrCreateUserByRealJid(tcp) : null; + User userByRealJid = tcp != null ? conversation.getMucOptions().findOrCreateUserByRealJid(tcp, cp) : null; final User user = userByRealJid != null ? userByRealJid : conversation.getMucOptions().findUserByFullJid(cp); final PopupMenu popupMenu = new PopupMenu(getActivity(), v); popupMenu.inflate(R.menu.muc_details_context); @@ -2670,7 +2670,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke setScrollPosition(scrollState, lastMessageUuid); } if (attachments != null && attachments.size() > 0) { - Log.d(Config.LOGTAG,"had attachments on restore"); + Log.d(Config.LOGTAG, "had attachments on restore"); mediaPreviewAdapter.addMediaPreviews(attachments); toggleInputMethod(); } @@ -2682,7 +2682,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke Log.e(Config.LOGTAG, "cleared pending intent with unhandled result left"); } if (pendingScrollState.clear()) { - Log.e(Config.LOGTAG,"cleared scroll state"); + Log.e(Config.LOGTAG, "cleared scroll state"); } if (pendingTakePhotoUri.clear()) { Log.e(Config.LOGTAG, "cleared pending photo uri");