fetch missing avatars from server
This commit is contained in:
parent
08755e56a5
commit
ba63727f50
|
@ -8,12 +8,14 @@ import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.persistance.FileBackend;
|
||||||
import eu.siacs.conversations.utils.UIHelper;
|
import eu.siacs.conversations.utils.UIHelper;
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
|
||||||
public class Contact implements ListItem {
|
public class Contact implements ListItem {
|
||||||
public static final String TABLENAME = "contacts";
|
public static final String TABLENAME = "contacts";
|
||||||
|
@ -34,6 +36,7 @@ public class Contact implements ListItem {
|
||||||
protected int subscription = 0;
|
protected int subscription = 0;
|
||||||
protected String systemAccount;
|
protected String systemAccount;
|
||||||
protected String photoUri;
|
protected String photoUri;
|
||||||
|
protected String avatar;
|
||||||
protected JSONObject keys = new JSONObject();
|
protected JSONObject keys = new JSONObject();
|
||||||
protected Presences presences = new Presences();
|
protected Presences presences = new Presences();
|
||||||
|
|
||||||
|
@ -316,7 +319,20 @@ public class Contact implements ListItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Bitmap getImage(int dpSize, Context context) {
|
public Bitmap getImage(int size, Context context) {
|
||||||
return UIHelper.getContactPicture(this, dpSize, context, false);
|
if (this.avatar!=null) {
|
||||||
|
Bitmap bm = BitmapFactory.decodeFile(FileBackend.getAvatarPath(context, avatar));
|
||||||
|
if (bm==null) {
|
||||||
|
return UIHelper.getContactPicture(this, size, context, false);
|
||||||
|
} else {
|
||||||
|
return bm;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return UIHelper.getContactPicture(this, size, context, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvatar(String filename) {
|
||||||
|
this.avatar = filename;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ import java.security.interfaces.DSAPublicKey;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.utils.UIHelper;
|
||||||
|
|
||||||
import net.java.otr4j.OtrException;
|
import net.java.otr4j.OtrException;
|
||||||
import net.java.otr4j.crypto.OtrCryptoEngineImpl;
|
import net.java.otr4j.crypto.OtrCryptoEngineImpl;
|
||||||
import net.java.otr4j.crypto.OtrCryptoException;
|
import net.java.otr4j.crypto.OtrCryptoException;
|
||||||
|
@ -13,7 +15,7 @@ import net.java.otr4j.session.SessionStatus;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
public class Conversation extends AbstractEntity {
|
public class Conversation extends AbstractEntity {
|
||||||
public static final String TABLENAME = "conversations";
|
public static final String TABLENAME = "conversations";
|
||||||
|
@ -174,13 +176,6 @@ public class Conversation extends AbstractEntity {
|
||||||
return this.contactJid;
|
return this.contactJid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uri getProfilePhotoUri() {
|
|
||||||
if (this.getProfilePhotoString() != null) {
|
|
||||||
return Uri.parse(this.getProfilePhotoString());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStatus() {
|
public int getStatus() {
|
||||||
return this.status;
|
return this.status;
|
||||||
}
|
}
|
||||||
|
@ -396,4 +391,12 @@ public class Conversation extends AbstractEntity {
|
||||||
public Bookmark getBookmark() {
|
public Bookmark getBookmark() {
|
||||||
return this.bookmark;
|
return this.bookmark;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Bitmap getImage(Context context, int size) {
|
||||||
|
if (mode==MODE_SINGLE) {
|
||||||
|
return getContact().getImage(size, context);
|
||||||
|
} else {
|
||||||
|
return UIHelper.getContactPicture(this, size, context, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,15 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected IqPacket retrieve(String node, Element item) {
|
||||||
|
IqPacket packet = new IqPacket(IqPacket.TYPE_GET);
|
||||||
|
Element pubsub = packet.addChild("pubsub", "http://jabber.org/protocol/pubsub");
|
||||||
|
Element items = pubsub.addChild("items");
|
||||||
|
items.setAttribute("node", node);
|
||||||
|
items.addChild(item);
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
public IqPacket publishAvatar(Avatar avatar) {
|
public IqPacket publishAvatar(Avatar avatar) {
|
||||||
Element item = new Element("item");
|
Element item = new Element("item");
|
||||||
item.setAttribute("id", avatar.sha1sum);
|
item.setAttribute("id", avatar.sha1sum);
|
||||||
|
@ -59,4 +68,12 @@ public class IqGenerator extends AbstractGenerator {
|
||||||
info.setAttribute("type", avatar.type);
|
info.setAttribute("type", avatar.type);
|
||||||
return publish("urn:xmpp:avatar:metadata",item);
|
return publish("urn:xmpp:avatar:metadata",item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IqPacket retrieveAvatar(Avatar avatar) {
|
||||||
|
Element item = new Element("item");
|
||||||
|
item.setAttribute("id", avatar.sha1sum);
|
||||||
|
IqPacket packet = retrieve("urn:xmpp:avatar:data", item);
|
||||||
|
packet.setTo(avatar.owner);
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,4 +73,16 @@ public abstract class AbstractParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String avatarData(Element items) {
|
||||||
|
Element item = items.findChild("item");
|
||||||
|
if (item==null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Element data = item.findChild("data","urn:xmpp:avatar:data");
|
||||||
|
if (data==null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return data.getContent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,18 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
|
||||||
mXmppConnectionService.updateRosterUi();
|
mXmppConnectionService.updateRosterUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String avatarData(IqPacket packet) {
|
||||||
|
Element pubsub = packet.findChild("pubsub", "http://jabber.org/protocol/pubsub");
|
||||||
|
if (pubsub==null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Element items = pubsub.findChild("items");
|
||||||
|
if (items==null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return super.avatarData(items);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
public void onIqPacketReceived(Account account, IqPacket packet) {
|
||||||
if (packet.hasChild("query", "jabber:iq:roster")) {
|
if (packet.hasChild("query", "jabber:iq:roster")) {
|
||||||
|
|
|
@ -5,12 +5,14 @@ import android.util.Log;
|
||||||
import net.java.otr4j.session.Session;
|
import net.java.otr4j.session.Session;
|
||||||
import net.java.otr4j.session.SessionStatus;
|
import net.java.otr4j.session.SessionStatus;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
|
import eu.siacs.conversations.entities.Contact;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
import eu.siacs.conversations.entities.Message;
|
import eu.siacs.conversations.entities.Message;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.utils.CryptoHelper;
|
import eu.siacs.conversations.utils.CryptoHelper;
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
import eu.siacs.conversations.xmpp.OnMessagePacketReceived;
|
import eu.siacs.conversations.xmpp.OnMessagePacketReceived;
|
||||||
|
import eu.siacs.conversations.xmpp.pep.Avatar;
|
||||||
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
|
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
|
||||||
|
|
||||||
public class MessageParser extends AbstractParser implements
|
public class MessageParser extends AbstractParser implements
|
||||||
|
@ -263,7 +265,22 @@ public class MessageParser extends AbstractParser implements
|
||||||
Element items = event.findChild("items");
|
Element items = event.findChild("items");
|
||||||
String node = items.getAttribute("node");
|
String node = items.getAttribute("node");
|
||||||
if (node!=null) {
|
if (node!=null) {
|
||||||
Log.d("xmppService",account.getJid()+": "+node+" from "+from);
|
if (node.equals("urn:xmpp:avatar:metadata")) {
|
||||||
|
Avatar avatar = Avatar.parseMetadata(items);
|
||||||
|
avatar.owner = from;
|
||||||
|
if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
|
||||||
|
if (account.getJid().equals(from)) {
|
||||||
|
account.setAvatar(avatar.getFilename());
|
||||||
|
} else {
|
||||||
|
Contact contact = account.getRoster().getContact(from);
|
||||||
|
contact.setAvatar(avatar.getFilename());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mXmppConnectionService.fetchAvatar(account, avatar);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.d("xmppService",account.getJid()+": "+node+" from "+from);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.d("xmppService",event.toString());
|
Log.d("xmppService",event.toString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,6 +248,11 @@ public class FileBackend {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAvatarCached(Avatar avatar) {
|
||||||
|
File file = new File(getAvatarPath(context, avatar.getFilename()));
|
||||||
|
return file.exists();
|
||||||
|
}
|
||||||
|
|
||||||
public void save(Avatar avatar) {
|
public void save(Avatar avatar) {
|
||||||
File file = new File(getAvatarPath(context, avatar.getFilename()));
|
File file = new File(getAvatarPath(context, avatar.getFilename()));
|
||||||
file.getParentFile().mkdirs();
|
file.getParentFile().mkdirs();
|
||||||
|
|
|
@ -1231,6 +1231,22 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void fetchAvatar(Account account, final Avatar avatar) {
|
||||||
|
IqPacket packet = this.mIqGenerator.retrieveAvatar(avatar);
|
||||||
|
sendIqPacket(account, packet, new OnIqPacketReceived() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onIqPacketReceived(Account account, IqPacket result) {
|
||||||
|
avatar.image = mIqParser.avatarData(result);
|
||||||
|
if (avatar.image!=null) {
|
||||||
|
getFileBackend().save(avatar);
|
||||||
|
Contact contact = account.getRoster().getContact(avatar.owner);
|
||||||
|
contact.setAvatar(avatar.getFilename());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void deleteContactOnServer(Contact contact) {
|
public void deleteContactOnServer(Contact contact) {
|
||||||
contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
|
contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
|
||||||
contact.resetOption(Contact.Options.DIRTY_PUSH);
|
contact.resetOption(Contact.Options.DIRTY_PUSH);
|
||||||
|
|
|
@ -229,8 +229,7 @@ public class ConversationActivity extends XmppActivity {
|
||||||
|
|
||||||
ImageView profilePicture = (ImageView) view
|
ImageView profilePicture = (ImageView) view
|
||||||
.findViewById(R.id.conversation_image);
|
.findViewById(R.id.conversation_image);
|
||||||
profilePicture.setImageBitmap(UIHelper.getContactPicture(conv,
|
profilePicture.setImageBitmap(conv.getImage(getApplicationContext(),56)); //;UIHelper.getContactPicture(conv,56, activity.getApplicationContext(), false));
|
||||||
56, activity.getApplicationContext(), false));
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
|
@ -488,8 +488,7 @@ public class UIHelper {
|
||||||
long id = Long.parseLong(systemAccount[0]);
|
long id = Long.parseLong(systemAccount[0]);
|
||||||
badge.assignContactUri(Contacts.getLookupUri(id, systemAccount[1]));
|
badge.assignContactUri(Contacts.getLookupUri(id, systemAccount[1]));
|
||||||
}
|
}
|
||||||
badge.setImageBitmap(UIHelper.getContactPicture(contact, 72, context,
|
badge.setImageBitmap(contact.getImage(72, context));
|
||||||
false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AlertDialog getVerifyFingerprintDialog(
|
public static AlertDialog getVerifyFingerprintDialog(
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package eu.siacs.conversations.xmpp.pep;
|
package eu.siacs.conversations.xmpp.pep;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.xml.Element;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
|
|
||||||
public class Avatar {
|
public class Avatar {
|
||||||
|
@ -9,6 +10,7 @@ public class Avatar {
|
||||||
public int height;
|
public int height;
|
||||||
public int width;
|
public int width;
|
||||||
public long size;
|
public long size;
|
||||||
|
public String owner;
|
||||||
public byte[] getImageAsBytes() {
|
public byte[] getImageAsBytes() {
|
||||||
return Base64.decode(image, Base64.DEFAULT);
|
return Base64.decode(image, Base64.DEFAULT);
|
||||||
}
|
}
|
||||||
|
@ -23,4 +25,43 @@ public class Avatar {
|
||||||
return sha1sum;
|
return sha1sum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static Avatar parseMetadata(Element items) {
|
||||||
|
Element item = items.findChild("item");
|
||||||
|
if (item==null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Element metadata = item.findChild("metadata");
|
||||||
|
if (metadata==null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String primaryId = item.getAttribute("id");
|
||||||
|
if (primaryId==null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for(Element child : metadata.getChildren()) {
|
||||||
|
if (child.getName().equals("info") && primaryId.equals(child.getAttribute("id"))) {
|
||||||
|
Avatar avatar = new Avatar();
|
||||||
|
String height = child.getAttribute("height");
|
||||||
|
String width = child.getAttribute("width");
|
||||||
|
String size = child.getAttribute("bytes");
|
||||||
|
try {
|
||||||
|
if (height!=null) {
|
||||||
|
avatar.height = Integer.parseInt(height);
|
||||||
|
}
|
||||||
|
if (width!=null) {
|
||||||
|
avatar.width = Integer.parseInt(width);
|
||||||
|
}
|
||||||
|
if (size!=null) {
|
||||||
|
avatar.size = Long.parseLong(size);
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
avatar.type = child.getAttribute("type");
|
||||||
|
avatar.sha1sum = child.getAttribute("id");
|
||||||
|
return avatar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue