parse vcard avatars from muc presences
This commit is contained in:
parent
f1c0b7372f
commit
6b592435cd
|
@ -4,20 +4,25 @@ import android.annotation.SuppressLint;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
|
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.crypto.PgpEngine;
|
|
||||||
import eu.siacs.conversations.xml.Element;
|
|
||||||
import eu.siacs.conversations.xmpp.forms.Data;
|
import eu.siacs.conversations.xmpp.forms.Data;
|
||||||
import eu.siacs.conversations.xmpp.forms.Field;
|
import eu.siacs.conversations.xmpp.forms.Field;
|
||||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||||
import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
|
import eu.siacs.conversations.xmpp.pep.Avatar;
|
||||||
|
|
||||||
@SuppressLint("DefaultLocale")
|
@SuppressLint("DefaultLocale")
|
||||||
public class MucOptions {
|
public class MucOptions {
|
||||||
|
|
||||||
|
public Account getAccount() {
|
||||||
|
return this.conversation.getAccount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelf(User user) {
|
||||||
|
this.self = user;
|
||||||
|
}
|
||||||
|
|
||||||
public enum Affiliation {
|
public enum Affiliation {
|
||||||
OWNER("owner", 4, R.string.owner),
|
OWNER("owner", 4, R.string.owner),
|
||||||
ADMIN("admin", 3, R.string.admin),
|
ADMIN("admin", 3, R.string.admin),
|
||||||
|
@ -100,28 +105,31 @@ public class MucOptions {
|
||||||
public static final String STATUS_CODE_LOST_MEMBERSHIP = "321";
|
public static final String STATUS_CODE_LOST_MEMBERSHIP = "321";
|
||||||
|
|
||||||
private interface OnEventListener {
|
private interface OnEventListener {
|
||||||
public void onSuccess();
|
void onSuccess();
|
||||||
|
|
||||||
public void onFailure();
|
void onFailure();
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface OnRenameListener extends OnEventListener {
|
public interface OnRenameListener extends OnEventListener {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class User {
|
public static class User {
|
||||||
private Role role = Role.NONE;
|
private Role role = Role.NONE;
|
||||||
private Affiliation affiliation = Affiliation.NONE;
|
private Affiliation affiliation = Affiliation.NONE;
|
||||||
private String name;
|
|
||||||
private Jid jid;
|
private Jid jid;
|
||||||
|
private Jid fullJid;
|
||||||
private long pgpKeyId = 0;
|
private long pgpKeyId = 0;
|
||||||
|
private Avatar avatar;
|
||||||
|
private MucOptions options;
|
||||||
|
|
||||||
public String getName() {
|
public User(MucOptions options, Jid from) {
|
||||||
return name;
|
this.options = options;
|
||||||
|
this.fullJid = from;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String user) {
|
public String getName() {
|
||||||
this.name = user;
|
return this.fullJid.getResourcepart();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setJid(Jid jid) {
|
public void setJid(Jid jid) {
|
||||||
|
@ -162,7 +170,7 @@ public class MucOptions {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
User o = (User) other;
|
User o = (User) other;
|
||||||
return name != null && name.equals(o.name)
|
return getName() != null && getName().equals(o.getName())
|
||||||
&& jid != null && jid.equals(o.jid)
|
&& jid != null && jid.equals(o.jid)
|
||||||
&& affiliation == o.affiliation
|
&& affiliation == o.affiliation
|
||||||
&& role == o.role;
|
&& role == o.role;
|
||||||
|
@ -202,26 +210,43 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Contact getContact() {
|
public Contact getContact() {
|
||||||
return account.getRoster().getContactFromRoster(getJid());
|
return getAccount().getRoster().getContactFromRoster(getJid());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvatar(Avatar avatar) {
|
||||||
|
this.avatar = avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAvatar() {
|
||||||
|
return avatar == null ? null : avatar.getFilename();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Account getAccount() {
|
||||||
|
return options.getAccount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Jid getFullJid() {
|
||||||
|
return fullJid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Account account;
|
private Account account;
|
||||||
private List<User> users = new CopyOnWriteArrayList<>();
|
private final List<User> users = new ArrayList<>();
|
||||||
private List<String> features = new ArrayList<>();
|
private List<String> features = new ArrayList<>();
|
||||||
private Data form = new Data();
|
private Data form = new Data();
|
||||||
private Conversation conversation;
|
private Conversation conversation;
|
||||||
private boolean isOnline = false;
|
private boolean isOnline = false;
|
||||||
private int error = ERROR_UNKNOWN;
|
private int error = ERROR_UNKNOWN;
|
||||||
private OnRenameListener onRenameListener = null;
|
public OnRenameListener onRenameListener = null;
|
||||||
private User self = new User();
|
private User self;
|
||||||
private String subject = null;
|
private String subject = null;
|
||||||
private String password = null;
|
private String password = null;
|
||||||
private boolean mNickChangingInProgress = false;
|
public boolean mNickChangingInProgress = false;
|
||||||
|
|
||||||
public MucOptions(Conversation conversation) {
|
public MucOptions(Conversation conversation) {
|
||||||
this.account = conversation.getAccount();
|
this.account = conversation.getAccount();
|
||||||
this.conversation = conversation;
|
this.conversation = conversation;
|
||||||
|
this.self = new User(this,conversation.getJid());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateFeatures(ArrayList<String> features) {
|
public void updateFeatures(ArrayList<String> features) {
|
||||||
|
@ -273,6 +298,7 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteUser(String name) {
|
public void deleteUser(String name) {
|
||||||
|
synchronized (this.users) {
|
||||||
for (int i = 0; i < users.size(); ++i) {
|
for (int i = 0; i < users.size(); ++i) {
|
||||||
if (users.get(i).getName().equals(name)) {
|
if (users.get(i).getName().equals(name)) {
|
||||||
users.remove(i);
|
users.remove(i);
|
||||||
|
@ -280,8 +306,10 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void addUser(User user) {
|
public void addUser(User user) {
|
||||||
|
synchronized (this.users) {
|
||||||
for (int i = 0; i < users.size(); ++i) {
|
for (int i = 0; i < users.size(); ++i) {
|
||||||
if (users.get(i).getName().equals(user.getName())) {
|
if (users.get(i).getName().equals(user.getName())) {
|
||||||
users.set(i, user);
|
users.set(i, user);
|
||||||
|
@ -290,118 +318,47 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
users.add(user);
|
users.add(user);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public User findUser(String name) {
|
||||||
|
if (name == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
synchronized (this.users) {
|
||||||
|
for (User user : users) {
|
||||||
|
if (user.getName().equals(name)) {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isUserInRoom(String name) {
|
public boolean isUserInRoom(String name) {
|
||||||
for (int i = 0; i < users.size(); ++i) {
|
return findUser(name) != null;
|
||||||
if (users.get(i).getName().equals(name)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processPacket(PresencePacket packet, PgpEngine pgp) {
|
public void setError(int error) {
|
||||||
final Jid from = packet.getFrom();
|
this.isOnline = error == ERROR_NO_ERROR;
|
||||||
if (!from.isBareJid()) {
|
|
||||||
final String name = from.getResourcepart();
|
|
||||||
final String type = packet.getAttribute("type");
|
|
||||||
final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user");
|
|
||||||
final List<String> codes = getStatusCodes(x);
|
|
||||||
if (type == null) {
|
|
||||||
User user = new User();
|
|
||||||
if (x != null) {
|
|
||||||
Element item = x.findChild("item");
|
|
||||||
if (item != null && name != null) {
|
|
||||||
user.setName(name);
|
|
||||||
user.setAffiliation(item.getAttribute("affiliation"));
|
|
||||||
user.setRole(item.getAttribute("role"));
|
|
||||||
user.setJid(item.getAttributeAsJid("jid"));
|
|
||||||
if (codes.contains(STATUS_CODE_SELF_PRESENCE) || packet.getFrom().equals(this.conversation.getJid())) {
|
|
||||||
this.isOnline = true;
|
|
||||||
this.error = ERROR_NO_ERROR;
|
|
||||||
self = user;
|
|
||||||
if (mNickChangingInProgress) {
|
|
||||||
if (onRenameListener != null) {
|
|
||||||
onRenameListener.onSuccess();
|
|
||||||
}
|
|
||||||
mNickChangingInProgress = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
addUser(user);
|
|
||||||
}
|
|
||||||
if (pgp != null) {
|
|
||||||
Element signed = packet.findChild("x", "jabber:x:signed");
|
|
||||||
if (signed != null) {
|
|
||||||
Element status = packet.findChild("status");
|
|
||||||
String msg = status == null ? "" : status.getContent();
|
|
||||||
long keyId = pgp.fetchKeyId(account, msg, signed.getContent());
|
|
||||||
if (keyId != 0) {
|
|
||||||
user.setPgpKeyId(keyId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (type.equals("unavailable")) {
|
|
||||||
if (codes.contains(STATUS_CODE_SELF_PRESENCE) ||
|
|
||||||
packet.getFrom().equals(this.conversation.getJid())) {
|
|
||||||
if (codes.contains(STATUS_CODE_CHANGED_NICK)) {
|
|
||||||
this.mNickChangingInProgress = true;
|
|
||||||
} else if (codes.contains(STATUS_CODE_KICKED)) {
|
|
||||||
setError(KICKED_FROM_ROOM);
|
|
||||||
} else if (codes.contains(STATUS_CODE_BANNED)) {
|
|
||||||
setError(ERROR_BANNED);
|
|
||||||
} else if (codes.contains(STATUS_CODE_LOST_MEMBERSHIP)) {
|
|
||||||
setError(ERROR_MEMBERS_ONLY);
|
|
||||||
} else {
|
|
||||||
setError(ERROR_UNKNOWN);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
deleteUser(name);
|
|
||||||
}
|
|
||||||
} else if (type.equals("error")) {
|
|
||||||
Element error = packet.findChild("error");
|
|
||||||
if (error != null && error.hasChild("conflict")) {
|
|
||||||
if (isOnline) {
|
|
||||||
if (onRenameListener != null) {
|
|
||||||
onRenameListener.onFailure();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setError(ERROR_NICK_IN_USE);
|
|
||||||
}
|
|
||||||
} else if (error != null && error.hasChild("not-authorized")) {
|
|
||||||
setError(ERROR_PASSWORD_REQUIRED);
|
|
||||||
} else if (error != null && error.hasChild("forbidden")) {
|
|
||||||
setError(ERROR_BANNED);
|
|
||||||
} else if (error != null && error.hasChild("registration-required")) {
|
|
||||||
setError(ERROR_MEMBERS_ONLY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setError(int error) {
|
|
||||||
this.isOnline = false;
|
|
||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getStatusCodes(Element x) {
|
public ArrayList<User> getUsers() {
|
||||||
List<String> codes = new ArrayList<>();
|
synchronized (this.users) {
|
||||||
if (x != null) {
|
return new ArrayList(this.users);
|
||||||
for (Element child : x.getChildren()) {
|
|
||||||
if (child.getName().equals("status")) {
|
|
||||||
String code = child.getAttribute("code");
|
|
||||||
if (code != null) {
|
|
||||||
codes.add(code);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return codes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<User> getUsers() {
|
public List<User> getUsers(int max) {
|
||||||
return this.users;
|
synchronized (this.users) {
|
||||||
|
return new ArrayList<>(users.subList(0,Math.min(users.size(),5)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserCount() {
|
||||||
|
synchronized (this.users) {
|
||||||
|
return this.users.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getProposedNick() {
|
public String getProposedNick() {
|
||||||
|
@ -455,6 +412,7 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String createNameFromParticipants() {
|
public String createNameFromParticipants() {
|
||||||
|
synchronized (this.users) {
|
||||||
if (users.size() >= 2) {
|
if (users.size() >= 2) {
|
||||||
List<String> names = new ArrayList<String>();
|
List<String> names = new ArrayList<String>();
|
||||||
for (User user : users) {
|
for (User user : users) {
|
||||||
|
@ -477,14 +435,17 @@ public class MucOptions {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public long[] getPgpKeyIds() {
|
public long[] getPgpKeyIds() {
|
||||||
List<Long> ids = new ArrayList<>();
|
List<Long> ids = new ArrayList<>();
|
||||||
for (User user : getUsers()) {
|
synchronized (this.users) {
|
||||||
|
for (User user : this.users) {
|
||||||
if (user.getPgpKeyId() != 0) {
|
if (user.getPgpKeyId() != 0) {
|
||||||
ids.add(user.getPgpKeyId());
|
ids.add(user.getPgpKeyId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ids.add(account.getPgpId());
|
ids.add(account.getPgpId());
|
||||||
long[] primitiveLongArray = new long[ids.size()];
|
long[] primitiveLongArray = new long[ids.size()];
|
||||||
for (int i = 0; i < ids.size(); ++i) {
|
for (int i = 0; i < ids.size(); ++i) {
|
||||||
|
@ -494,20 +455,24 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean pgpKeysInUse() {
|
public boolean pgpKeysInUse() {
|
||||||
for (User user : getUsers()) {
|
synchronized (this.users) {
|
||||||
|
for (User user : this.users) {
|
||||||
if (user.getPgpKeyId() != 0) {
|
if (user.getPgpKeyId() != 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean everybodyHasKeys() {
|
public boolean everybodyHasKeys() {
|
||||||
for (User user : getUsers()) {
|
synchronized (this.users) {
|
||||||
|
for (User user : this.users) {
|
||||||
if (user.getPgpKeyId() == 0) {
|
if (user.getPgpKeyId() == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,11 +485,13 @@ public class MucOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jid getTrueCounterpart(String counterpart) {
|
public Jid getTrueCounterpart(String counterpart) {
|
||||||
for (User user : this.getUsers()) {
|
synchronized (this.users) {
|
||||||
|
for (User user : this.users) {
|
||||||
if (user.getName().equals(counterpart)) {
|
if (user.getName().equals(counterpart)) {
|
||||||
return user.getJid();
|
return user.getJid();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ public class MessageParser extends AbstractParser implements
|
||||||
if ("urn:xmpp:avatar:metadata".equals(node)) {
|
if ("urn:xmpp:avatar:metadata".equals(node)) {
|
||||||
Avatar avatar = Avatar.parseMetadata(items);
|
Avatar avatar = Avatar.parseMetadata(items);
|
||||||
if (avatar != null) {
|
if (avatar != null) {
|
||||||
avatar.owner = from;
|
avatar.owner = from.toBareJid();
|
||||||
if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
|
if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
|
||||||
if (account.getJid().toBareJid().equals(from)) {
|
if (account.getJid().toBareJid().equals(from)) {
|
||||||
if (account.setAvatar(avatar.getFilename())) {
|
if (account.setAvatar(avatar.getFilename())) {
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
package eu.siacs.conversations.parser;
|
package eu.siacs.conversations.parser;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.crypto.PgpEngine;
|
import eu.siacs.conversations.crypto.PgpEngine;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.entities.Contact;
|
import eu.siacs.conversations.entities.Contact;
|
||||||
|
@ -25,19 +29,18 @@ public class PresenceParser extends AbstractParser implements
|
||||||
}
|
}
|
||||||
|
|
||||||
public void parseConferencePresence(PresencePacket packet, Account account) {
|
public void parseConferencePresence(PresencePacket packet, Account account) {
|
||||||
PgpEngine mPgpEngine = mXmppConnectionService.getPgpEngine();
|
|
||||||
final Conversation conversation = packet.getFrom() == null ? null : mXmppConnectionService.find(account, packet.getFrom().toBareJid());
|
final Conversation conversation = packet.getFrom() == null ? null : mXmppConnectionService.find(account, packet.getFrom().toBareJid());
|
||||||
if (conversation != null) {
|
if (conversation != null) {
|
||||||
final MucOptions mucOptions = conversation.getMucOptions();
|
final MucOptions mucOptions = conversation.getMucOptions();
|
||||||
boolean before = mucOptions.online();
|
boolean before = mucOptions.online();
|
||||||
int count = mucOptions.getUsers().size();
|
int count = mucOptions.getUserCount();
|
||||||
final ArrayList<MucOptions.User> tileUserBefore = new ArrayList<>(mucOptions.getUsers().subList(0,Math.min(mucOptions.getUsers().size(),5)));
|
final List<MucOptions.User> tileUserBefore = mucOptions.getUsers(5);
|
||||||
mucOptions.processPacket(packet, mPgpEngine);
|
processConferencePresence(packet, mucOptions);
|
||||||
final ArrayList<MucOptions.User> tileUserAfter = new ArrayList<>(mucOptions.getUsers().subList(0,Math.min(mucOptions.getUsers().size(),5)));
|
final List<MucOptions.User> tileUserAfter = mucOptions.getUsers(5);
|
||||||
if (!tileUserAfter.equals(tileUserBefore)) {
|
if (!tileUserAfter.equals(tileUserBefore)) {
|
||||||
mXmppConnectionService.getAvatarService().clear(conversation);
|
mXmppConnectionService.getAvatarService().clear(conversation);
|
||||||
}
|
}
|
||||||
if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUsers().size())) {
|
if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUserCount())) {
|
||||||
mXmppConnectionService.updateConversationUi();
|
mXmppConnectionService.updateConversationUi();
|
||||||
} else if (mucOptions.online()) {
|
} else if (mucOptions.online()) {
|
||||||
mXmppConnectionService.updateMucRosterUi();
|
mXmppConnectionService.updateMucRosterUi();
|
||||||
|
@ -45,6 +48,108 @@ public class PresenceParser extends AbstractParser implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void processConferencePresence(PresencePacket packet, MucOptions mucOptions) {
|
||||||
|
final Jid from = packet.getFrom();
|
||||||
|
if (!from.isBareJid()) {
|
||||||
|
final String type = packet.getAttribute("type");
|
||||||
|
final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user");
|
||||||
|
Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update"));
|
||||||
|
final List<String> codes = getStatusCodes(x);
|
||||||
|
if (type == null) {
|
||||||
|
if (x != null) {
|
||||||
|
Element item = x.findChild("item");
|
||||||
|
if (item != null && !from.isBareJid()) {
|
||||||
|
MucOptions.User user = new MucOptions.User(mucOptions,from);
|
||||||
|
user.setAffiliation(item.getAttribute("affiliation"));
|
||||||
|
user.setRole(item.getAttribute("role"));
|
||||||
|
user.setJid(item.getAttributeAsJid("jid"));
|
||||||
|
if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE) || packet.getFrom().equals(mucOptions.getConversation().getJid())) {
|
||||||
|
mucOptions.setError(MucOptions.ERROR_NO_ERROR);
|
||||||
|
mucOptions.setSelf(user);
|
||||||
|
if (mucOptions.mNickChangingInProgress) {
|
||||||
|
if (mucOptions.onRenameListener != null) {
|
||||||
|
mucOptions.onRenameListener.onSuccess();
|
||||||
|
}
|
||||||
|
mucOptions.mNickChangingInProgress = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mucOptions.addUser(user);
|
||||||
|
}
|
||||||
|
if (mXmppConnectionService.getPgpEngine() != null) {
|
||||||
|
Element signed = packet.findChild("x", "jabber:x:signed");
|
||||||
|
if (signed != null) {
|
||||||
|
Element status = packet.findChild("status");
|
||||||
|
String msg = status == null ? "" : status.getContent();
|
||||||
|
long keyId = mXmppConnectionService.getPgpEngine().fetchKeyId(mucOptions.getAccount(), msg, signed.getContent());
|
||||||
|
if (keyId != 0) {
|
||||||
|
user.setPgpKeyId(keyId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (avatar != null) {
|
||||||
|
avatar.owner = from;
|
||||||
|
if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
|
||||||
|
user.setAvatar(avatar);
|
||||||
|
} else {
|
||||||
|
mXmppConnectionService.fetchAvatar(mucOptions.getAccount(), avatar);
|
||||||
|
}
|
||||||
|
Log.d(Config.LOGTAG, "user " + avatar.owner + " has avatar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (type.equals("unavailable")) {
|
||||||
|
if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE) ||
|
||||||
|
packet.getFrom().equals(mucOptions.getConversation().getJid())) {
|
||||||
|
if (codes.contains(MucOptions.STATUS_CODE_CHANGED_NICK)) {
|
||||||
|
mucOptions.mNickChangingInProgress = true;
|
||||||
|
} else if (codes.contains(MucOptions.STATUS_CODE_KICKED)) {
|
||||||
|
mucOptions.setError(MucOptions.KICKED_FROM_ROOM);
|
||||||
|
} else if (codes.contains(MucOptions.STATUS_CODE_BANNED)) {
|
||||||
|
mucOptions.setError(MucOptions.ERROR_BANNED);
|
||||||
|
} else if (codes.contains(MucOptions.STATUS_CODE_LOST_MEMBERSHIP)) {
|
||||||
|
mucOptions.setError(MucOptions.ERROR_MEMBERS_ONLY);
|
||||||
|
} else {
|
||||||
|
mucOptions.setError(MucOptions.ERROR_UNKNOWN);
|
||||||
|
}
|
||||||
|
} else if (!from.isBareJid()){
|
||||||
|
mucOptions.deleteUser(from.getResourcepart());
|
||||||
|
}
|
||||||
|
} else if (type.equals("error")) {
|
||||||
|
Element error = packet.findChild("error");
|
||||||
|
if (error != null && error.hasChild("conflict")) {
|
||||||
|
if (mucOptions.online()) {
|
||||||
|
if (mucOptions.onRenameListener != null) {
|
||||||
|
mucOptions.onRenameListener.onFailure();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mucOptions.setError(MucOptions.ERROR_NICK_IN_USE);
|
||||||
|
}
|
||||||
|
} else if (error != null && error.hasChild("not-authorized")) {
|
||||||
|
mucOptions.setError(MucOptions.ERROR_PASSWORD_REQUIRED);
|
||||||
|
} else if (error != null && error.hasChild("forbidden")) {
|
||||||
|
mucOptions.setError(MucOptions.ERROR_BANNED);
|
||||||
|
} else if (error != null && error.hasChild("registration-required")) {
|
||||||
|
mucOptions.setError(MucOptions.ERROR_MEMBERS_ONLY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> getStatusCodes(Element x) {
|
||||||
|
List<String> codes = new ArrayList<>();
|
||||||
|
if (x != null) {
|
||||||
|
for (Element child : x.getChildren()) {
|
||||||
|
if (child.getName().equals("status")) {
|
||||||
|
String code = child.getAttribute("code");
|
||||||
|
if (code != null) {
|
||||||
|
codes.add(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return codes;
|
||||||
|
}
|
||||||
|
|
||||||
public void parseContactPresence(final PresencePacket packet, final Account account) {
|
public void parseContactPresence(final PresencePacket packet, final Account account) {
|
||||||
final PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator();
|
final PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator();
|
||||||
final Jid from = packet.getFrom();
|
final Jid from = packet.getFrom();
|
||||||
|
|
|
@ -58,6 +58,22 @@ public class AvatarService {
|
||||||
return avatar;
|
return avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Bitmap get(final MucOptions.User user, final int size, boolean cachedOnly) {
|
||||||
|
final String KEY = key(user, size);
|
||||||
|
Bitmap avatar = this.mXmppConnectionService.getBitmapCache().get(KEY);
|
||||||
|
if (avatar != null || cachedOnly) {
|
||||||
|
return avatar;
|
||||||
|
}
|
||||||
|
if (user.getAvatar() != null) {
|
||||||
|
avatar = mXmppConnectionService.getFileBackend().getAvatar(user.getAvatar(), size);
|
||||||
|
}
|
||||||
|
if (avatar == null) {
|
||||||
|
avatar = get(user.getName(), size, cachedOnly);
|
||||||
|
}
|
||||||
|
this.mXmppConnectionService.getBitmapCache().put(KEY, avatar);
|
||||||
|
return avatar;
|
||||||
|
}
|
||||||
|
|
||||||
public void clear(Contact contact) {
|
public void clear(Contact contact) {
|
||||||
synchronized (this.sizes) {
|
synchronized (this.sizes) {
|
||||||
for (Integer size : sizes) {
|
for (Integer size : sizes) {
|
||||||
|
@ -77,6 +93,16 @@ public class AvatarService {
|
||||||
+ contact.getJid() + "_" + String.valueOf(size);
|
+ contact.getJid() + "_" + String.valueOf(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String key(MucOptions.User user, int size) {
|
||||||
|
synchronized (this.sizes) {
|
||||||
|
if (!this.sizes.contains(size)) {
|
||||||
|
this.sizes.add(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PREFIX_CONTACT + "_" + user.getAccount().getJid().toBareJid() + "_"
|
||||||
|
+ user.getFullJid() + "_" + String.valueOf(size);
|
||||||
|
}
|
||||||
|
|
||||||
public Bitmap get(ListItem item, int size) {
|
public Bitmap get(ListItem item, int size) {
|
||||||
return get(item,size,false);
|
return get(item,size,false);
|
||||||
}
|
}
|
||||||
|
@ -122,7 +148,7 @@ public class AvatarService {
|
||||||
if (bitmap != null || cachedOnly) {
|
if (bitmap != null || cachedOnly) {
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
final List<MucOptions.User> users = new ArrayList<>(mucOptions.getUsers());
|
final List<MucOptions.User> users = mucOptions.getUsers();
|
||||||
int count = users.size();
|
int count = users.size();
|
||||||
bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
||||||
Canvas canvas = new Canvas(bitmap);
|
Canvas canvas = new Canvas(bitmap);
|
||||||
|
@ -198,15 +224,20 @@ public class AvatarService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Bitmap get(Message message, int size, boolean cachedOnly) {
|
public Bitmap get(Message message, int size, boolean cachedOnly) {
|
||||||
|
final Conversation conversation = message.getConversation();
|
||||||
if (message.getStatus() == Message.STATUS_RECEIVED) {
|
if (message.getStatus() == Message.STATUS_RECEIVED) {
|
||||||
Contact contact = message.getContact();
|
Contact c = message.getContact();
|
||||||
if (contact != null) {
|
if (c != null && (c.getProfilePhoto() != null || c.getAvatar() != null)) {
|
||||||
return get(contact, size, cachedOnly);
|
return get(c, size, cachedOnly);
|
||||||
} else {
|
} else if (message.getConversation().getMode() == Conversation.MODE_MULTI){
|
||||||
return get(UIHelper.getMessageDisplayName(message), size, cachedOnly);
|
MucOptions.User user = conversation.getMucOptions().findUser(message.getCounterpart().getResourcepart());
|
||||||
|
if (user != null) {
|
||||||
|
return get(user,size,cachedOnly);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return get(UIHelper.getMessageDisplayName(message), size, cachedOnly);
|
||||||
} else {
|
} else {
|
||||||
return get(message.getConversation().getAccount(), size, cachedOnly);
|
return get(conversation.getAccount(), size, cachedOnly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,6 +321,11 @@ public class AvatarService {
|
||||||
if (drawTile(canvas, uri, left, top, right, bottom)) {
|
if (drawTile(canvas, uri, left, top, right, bottom)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
} else if (user.getAvatar() != null) {
|
||||||
|
Uri uri = mXmppConnectionService.getFileBackend().getAvatarUri(user.getAvatar());
|
||||||
|
if (drawTile(canvas, uri, left, top, right, bottom)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
String name = contact != null ? contact.getDisplayName() : user.getName();
|
String name = contact != null ? contact.getDisplayName() : user.getName();
|
||||||
drawTile(canvas, name, left, top, right, bottom);
|
drawTile(canvas, name, left, top, right, bottom);
|
||||||
|
|
|
@ -2358,12 +2358,22 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
||||||
if (getFileBackend().save(avatar)) {
|
if (getFileBackend().save(avatar)) {
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid()
|
Log.d(Config.LOGTAG, account.getJid().toBareJid()
|
||||||
+ ": successfully fetched vCard avatar for " + avatar.owner);
|
+ ": successfully fetched vCard avatar for " + avatar.owner);
|
||||||
|
if (avatar.owner.isBareJid()) {
|
||||||
Contact contact = account.getRoster()
|
Contact contact = account.getRoster()
|
||||||
.getContact(avatar.owner);
|
.getContact(avatar.owner);
|
||||||
contact.setAvatar(avatar);
|
contact.setAvatar(avatar);
|
||||||
getAvatarService().clear(contact);
|
getAvatarService().clear(contact);
|
||||||
updateConversationUi();
|
updateConversationUi();
|
||||||
updateRosterUi();
|
updateRosterUi();
|
||||||
|
} else {
|
||||||
|
Conversation conversation = find(account,avatar.owner.toBareJid());
|
||||||
|
if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) {
|
||||||
|
MucOptions.User user = conversation.getMucOptions().findUser(avatar.owner.getResourcepart());
|
||||||
|
if (user != null) {
|
||||||
|
user.setAvatar(avatar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -494,8 +494,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
}
|
}
|
||||||
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
membersView.removeAllViews();
|
membersView.removeAllViews();
|
||||||
final ArrayList<User> users = new ArrayList<>();
|
final ArrayList<User> users = mucOptions.getUsers();
|
||||||
users.addAll(mConversation.getMucOptions().getUsers());
|
|
||||||
Collections.sort(users,new Comparator<User>() {
|
Collections.sort(users,new Comparator<User>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(User lhs, User rhs) {
|
public int compare(User lhs, User rhs) {
|
||||||
|
@ -527,20 +526,17 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
|
||||||
});
|
});
|
||||||
tvKey.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId()));
|
tvKey.setText(OpenPgpUtils.convertKeyIdToHex(user.getPgpKeyId()));
|
||||||
}
|
}
|
||||||
Bitmap bm;
|
|
||||||
Contact contact = user.getContact();
|
Contact contact = user.getContact();
|
||||||
if (contact != null) {
|
if (contact != null) {
|
||||||
bm = avatarService().get(contact, getPixel(48));
|
|
||||||
tvDisplayName.setText(contact.getDisplayName());
|
tvDisplayName.setText(contact.getDisplayName());
|
||||||
tvStatus.setText(user.getName() + " \u2022 " + getStatus(user));
|
tvStatus.setText(user.getName() + " \u2022 " + getStatus(user));
|
||||||
} else {
|
} else {
|
||||||
bm = avatarService().get(user.getName(), getPixel(48));
|
|
||||||
tvDisplayName.setText(user.getName());
|
tvDisplayName.setText(user.getName());
|
||||||
tvStatus.setText(getStatus(user));
|
tvStatus.setText(getStatus(user));
|
||||||
|
|
||||||
}
|
}
|
||||||
ImageView iv = (ImageView) view.findViewById(R.id.contact_photo);
|
ImageView iv = (ImageView) view.findViewById(R.id.contact_photo);
|
||||||
iv.setImageBitmap(bm);
|
iv.setImageBitmap(avatarService().get(user, getPixel(48), false));
|
||||||
membersView.addView(view);
|
membersView.addView(view);
|
||||||
if (mConversation.getMucOptions().canInvite()) {
|
if (mConversation.getMucOptions().canInvite()) {
|
||||||
mInviteButton.setVisibility(View.VISIBLE);
|
mInviteButton.setVisibility(View.VISIBLE);
|
||||||
|
|
Loading…
Reference in a new issue