fetch missing avatars from server

This commit is contained in:
iNPUTmice 2014-08-05 22:58:46 +02:00
parent 08755e56a5
commit ba63727f50
11 changed files with 152 additions and 15 deletions

View File

@ -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;
} }
} }

View File

@ -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);
}
}
} }

View File

@ -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;
}
} }

View File

@ -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();
}
} }

View File

@ -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")) {

View File

@ -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());
} }

View File

@ -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();

View File

@ -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);

View File

@ -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;
} }

View File

@ -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(

View File

@ -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;
}
} }