Avatar.java

  1package eu.siacs.conversations.xmpp.pep;
  2
  3import android.util.Base64;
  4import androidx.annotation.NonNull;
  5import com.google.common.base.MoreObjects;
  6import eu.siacs.conversations.xml.Element;
  7import eu.siacs.conversations.xmpp.Jid;
  8import im.conversations.android.xmpp.model.avatar.Metadata;
  9import okhttp3.HttpUrl;
 10
 11public class Avatar {
 12
 13    @Override
 14    @NonNull
 15    public String toString() {
 16        return MoreObjects.toStringHelper(this)
 17                .add("type", type)
 18                .add("sha1sum", sha1sum)
 19                .add("url", url)
 20                .add("image", image)
 21                .add("height", height)
 22                .add("width", width)
 23                .add("size", size)
 24                .add("owner", owner)
 25                .add("origin", origin)
 26                .toString();
 27    }
 28
 29    public enum Origin {
 30        PEP,
 31        VCARD
 32    }
 33
 34    public String type;
 35    public String sha1sum;
 36    public HttpUrl url;
 37    public String image;
 38    public int height;
 39    public int width;
 40    public long size;
 41    public Jid owner;
 42    public Origin origin = Origin.PEP; // default to maintain compat
 43
 44    public byte[] getImageAsBytes() {
 45        return Base64.decode(image, Base64.DEFAULT);
 46    }
 47
 48    public String getFilename() {
 49        return sha1sum;
 50    }
 51
 52    public static Avatar parseMetadata(final String primaryId, final Metadata metadata) {
 53        if (primaryId == null || metadata == null) {
 54            return null;
 55        }
 56        for (Element child : metadata.getChildren()) {
 57            if (child.getName().equals("info") && primaryId.equals(child.getAttribute("id"))) {
 58                Avatar avatar = new Avatar();
 59                String height = child.getAttribute("height");
 60                String width = child.getAttribute("width");
 61                String size = child.getAttribute("bytes");
 62                try {
 63                    if (height != null) {
 64                        avatar.height = Integer.parseInt(height);
 65                    }
 66                    if (width != null) {
 67                        avatar.width = Integer.parseInt(width);
 68                    }
 69                    if (size != null) {
 70                        avatar.size = Long.parseLong(size);
 71                    }
 72                } catch (NumberFormatException e) {
 73                    return null;
 74                }
 75                avatar.type = child.getAttribute("type");
 76                String hash = child.getAttribute("id");
 77                if (!isValidSHA1(hash)) {
 78                    return null;
 79                }
 80                avatar.sha1sum = hash;
 81                avatar.origin = Origin.PEP;
 82                return avatar;
 83            }
 84        }
 85        return null;
 86    }
 87
 88    @Override
 89    public boolean equals(Object object) {
 90        if (object != null && object instanceof Avatar other) {
 91            return other.getFilename().equals(this.getFilename());
 92        } else {
 93            return false;
 94        }
 95    }
 96
 97    public static Avatar parsePresence(Element x) {
 98        String hash = x == null ? null : x.findChildContent("photo");
 99        if (hash == null) {
100            return null;
101        }
102        if (!isValidSHA1(hash)) {
103            return null;
104        }
105        Avatar avatar = new Avatar();
106        avatar.sha1sum = hash;
107        avatar.origin = Origin.VCARD;
108        return avatar;
109    }
110
111    private static boolean isValidSHA1(String s) {
112        return s != null && s.matches("[a-fA-F0-9]{40}");
113    }
114}