aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/eu/siacs/conversations/entities/Contact.java20
-rw-r--r--src/eu/siacs/conversations/entities/Conversation.java19
-rw-r--r--src/eu/siacs/conversations/generator/IqGenerator.java17
-rw-r--r--src/eu/siacs/conversations/parser/AbstractParser.java12
-rw-r--r--src/eu/siacs/conversations/parser/IqParser.java12
-rw-r--r--src/eu/siacs/conversations/parser/MessageParser.java19
-rw-r--r--src/eu/siacs/conversations/persistance/FileBackend.java5
-rw-r--r--src/eu/siacs/conversations/services/XmppConnectionService.java16
-rw-r--r--src/eu/siacs/conversations/ui/ConversationActivity.java3
-rw-r--r--src/eu/siacs/conversations/utils/UIHelper.java3
-rw-r--r--src/eu/siacs/conversations/xmpp/pep/Avatar.java41
11 files changed, 152 insertions, 15 deletions
diff --git a/src/eu/siacs/conversations/entities/Contact.java b/src/eu/siacs/conversations/entities/Contact.java
index 8f8e38a5..db120200 100644
--- a/src/eu/siacs/conversations/entities/Contact.java
+++ b/src/eu/siacs/conversations/entities/Contact.java
@@ -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;
}
}
diff --git a/src/eu/siacs/conversations/entities/Conversation.java b/src/eu/siacs/conversations/entities/Conversation.java
index 29eb22b9..be641ea4 100644
--- a/src/eu/siacs/conversations/entities/Conversation.java
+++ b/src/eu/siacs/conversations/entities/Conversation.java
@@ -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);
+ }
+ }
}
diff --git a/src/eu/siacs/conversations/generator/IqGenerator.java b/src/eu/siacs/conversations/generator/IqGenerator.java
index 1a38347b..c4d84020 100644
--- a/src/eu/siacs/conversations/generator/IqGenerator.java
+++ b/src/eu/siacs/conversations/generator/IqGenerator.java
@@ -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;
+ }
}
diff --git a/src/eu/siacs/conversations/parser/AbstractParser.java b/src/eu/siacs/conversations/parser/AbstractParser.java
index c4c6720a..e06f16e9 100644
--- a/src/eu/siacs/conversations/parser/AbstractParser.java
+++ b/src/eu/siacs/conversations/parser/AbstractParser.java
@@ -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();
+ }
}
diff --git a/src/eu/siacs/conversations/parser/IqParser.java b/src/eu/siacs/conversations/parser/IqParser.java
index 023fb4df..49268450 100644
--- a/src/eu/siacs/conversations/parser/IqParser.java
+++ b/src/eu/siacs/conversations/parser/IqParser.java
@@ -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) {
diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java
index 0a812669..b54f6b98 100644
--- a/src/eu/siacs/conversations/parser/MessageParser.java
+++ b/src/eu/siacs/conversations/parser/MessageParser.java
@@ -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());
}
diff --git a/src/eu/siacs/conversations/persistance/FileBackend.java b/src/eu/siacs/conversations/persistance/FileBackend.java
index 4014cf60..c371e039 100644
--- a/src/eu/siacs/conversations/persistance/FileBackend.java
+++ b/src/eu/siacs/conversations/persistance/FileBackend.java
@@ -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();
diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java
index 8c964517..71f2cfc2 100644
--- a/src/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/eu/siacs/conversations/services/XmppConnectionService.java
@@ -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);
diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java
index b04fc131..d7708b52 100644
--- a/src/eu/siacs/conversations/ui/ConversationActivity.java
+++ b/src/eu/siacs/conversations/ui/ConversationActivity.java
@@ -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;
}
diff --git a/src/eu/siacs/conversations/utils/UIHelper.java b/src/eu/siacs/conversations/utils/UIHelper.java
index d14970f5..5d959b17 100644
--- a/src/eu/siacs/conversations/utils/UIHelper.java
+++ b/src/eu/siacs/conversations/utils/UIHelper.java
@@ -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(
diff --git a/src/eu/siacs/conversations/xmpp/pep/Avatar.java b/src/eu/siacs/conversations/xmpp/pep/Avatar.java
index b000c055..b99a2fe3 100644
--- a/src/eu/siacs/conversations/xmpp/pep/Avatar.java
+++ b/src/eu/siacs/conversations/xmpp/pep/Avatar.java
@@ -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;
+ }
}