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.JSONObject;
|
||||
|
||||
import eu.siacs.conversations.persistance.FileBackend;
|
||||
import eu.siacs.conversations.utils.UIHelper;
|
||||
import eu.siacs.conversations.xml.Element;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
||||
public class Contact implements ListItem {
|
||||
public static final String TABLENAME = "contacts";
|
||||
|
@ -34,6 +36,7 @@ public class Contact implements ListItem {
|
|||
protected int subscription = 0;
|
||||
protected String systemAccount;
|
||||
protected String photoUri;
|
||||
protected String avatar;
|
||||
protected JSONObject keys = new JSONObject();
|
||||
protected Presences presences = new Presences();
|
||||
|
||||
|
@ -316,7 +319,20 @@ public class Contact implements ListItem {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Bitmap getImage(int dpSize, Context context) {
|
||||
return UIHelper.getContactPicture(this, dpSize, context, false);
|
||||
public Bitmap getImage(int size, Context context) {
|
||||
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.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import eu.siacs.conversations.utils.UIHelper;
|
||||
|
||||
import net.java.otr4j.OtrException;
|
||||
import net.java.otr4j.crypto.OtrCryptoEngineImpl;
|
||||
import net.java.otr4j.crypto.OtrCryptoException;
|
||||
|
@ -13,7 +15,7 @@ import net.java.otr4j.session.SessionStatus;
|
|||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
public class Conversation extends AbstractEntity {
|
||||
public static final String TABLENAME = "conversations";
|
||||
|
@ -174,13 +176,6 @@ public class Conversation extends AbstractEntity {
|
|||
return this.contactJid;
|
||||
}
|
||||
|
||||
public Uri getProfilePhotoUri() {
|
||||
if (this.getProfilePhotoString() != null) {
|
||||
return Uri.parse(this.getProfilePhotoString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
|
@ -396,4 +391,12 @@ public class Conversation extends AbstractEntity {
|
|||
public Bookmark getBookmark() {
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
Element item = new Element("item");
|
||||
item.setAttribute("id", avatar.sha1sum);
|
||||
|
@ -59,4 +68,12 @@ public class IqGenerator extends AbstractGenerator {
|
|||
info.setAttribute("type", avatar.type);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,18 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
|
|||
}
|
||||
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
|
||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
||||
|
|
|
@ -5,12 +5,14 @@ import android.util.Log;
|
|||
import net.java.otr4j.session.Session;
|
||||
import net.java.otr4j.session.SessionStatus;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.entities.Contact;
|
||||
import eu.siacs.conversations.entities.Conversation;
|
||||
import eu.siacs.conversations.entities.Message;
|
||||
import eu.siacs.conversations.services.XmppConnectionService;
|
||||
import eu.siacs.conversations.utils.CryptoHelper;
|
||||
import eu.siacs.conversations.xml.Element;
|
||||
import eu.siacs.conversations.xmpp.OnMessagePacketReceived;
|
||||
import eu.siacs.conversations.xmpp.pep.Avatar;
|
||||
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
|
||||
|
||||
public class MessageParser extends AbstractParser implements
|
||||
|
@ -263,7 +265,22 @@ public class MessageParser extends AbstractParser implements
|
|||
Element items = event.findChild("items");
|
||||
String node = items.getAttribute("node");
|
||||
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 {
|
||||
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) {
|
||||
File file = new File(getAvatarPath(context, avatar.getFilename()));
|
||||
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) {
|
||||
contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
|
||||
contact.resetOption(Contact.Options.DIRTY_PUSH);
|
||||
|
|
|
@ -229,8 +229,7 @@ public class ConversationActivity extends XmppActivity {
|
|||
|
||||
ImageView profilePicture = (ImageView) view
|
||||
.findViewById(R.id.conversation_image);
|
||||
profilePicture.setImageBitmap(UIHelper.getContactPicture(conv,
|
||||
56, activity.getApplicationContext(), false));
|
||||
profilePicture.setImageBitmap(conv.getImage(getApplicationContext(),56)); //;UIHelper.getContactPicture(conv,56, activity.getApplicationContext(), false));
|
||||
|
||||
return view;
|
||||
}
|
||||
|
|
|
@ -488,8 +488,7 @@ public class UIHelper {
|
|||
long id = Long.parseLong(systemAccount[0]);
|
||||
badge.assignContactUri(Contacts.getLookupUri(id, systemAccount[1]));
|
||||
}
|
||||
badge.setImageBitmap(UIHelper.getContactPicture(contact, 72, context,
|
||||
false));
|
||||
badge.setImageBitmap(contact.getImage(72, context));
|
||||
}
|
||||
|
||||
public static AlertDialog getVerifyFingerprintDialog(
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package eu.siacs.conversations.xmpp.pep;
|
||||
|
||||
import eu.siacs.conversations.xml.Element;
|
||||
import android.util.Base64;
|
||||
|
||||
public class Avatar {
|
||||
|
@ -9,6 +10,7 @@ public class Avatar {
|
|||
public int height;
|
||||
public int width;
|
||||
public long size;
|
||||
public String owner;
|
||||
public byte[] getImageAsBytes() {
|
||||
return Base64.decode(image, Base64.DEFAULT);
|
||||
}
|
||||
|
@ -23,4 +25,43 @@ public class Avatar {
|
|||
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