2014-10-22 16:38:44 +00:00
|
|
|
package eu.siacs.conversations.entities;
|
|
|
|
|
2014-11-05 20:55:47 +00:00
|
|
|
import android.content.ContentValues;
|
2016-04-22 19:25:06 +00:00
|
|
|
import android.content.Context;
|
2014-11-05 20:55:47 +00:00
|
|
|
import android.database.Cursor;
|
2016-08-26 11:35:01 +00:00
|
|
|
import android.net.Uri;
|
2018-03-23 15:59:42 +00:00
|
|
|
import android.support.annotation.NonNull;
|
2018-03-23 15:52:05 +00:00
|
|
|
import android.text.TextUtils;
|
2014-10-22 16:38:44 +00:00
|
|
|
|
|
|
|
import org.json.JSONArray;
|
|
|
|
import org.json.JSONException;
|
|
|
|
import org.json.JSONObject;
|
|
|
|
|
2014-11-15 23:20:20 +00:00
|
|
|
import java.util.ArrayList;
|
2018-06-16 16:14:49 +00:00
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.HashSet;
|
2014-11-16 16:21:21 +00:00
|
|
|
import java.util.List;
|
2014-11-17 16:53:19 +00:00
|
|
|
import java.util.Locale;
|
2014-11-05 20:55:47 +00:00
|
|
|
|
2015-12-19 11:43:09 +00:00
|
|
|
import eu.siacs.conversations.Config;
|
2018-06-16 16:14:49 +00:00
|
|
|
import eu.siacs.conversations.R;
|
2018-10-28 18:05:16 +00:00
|
|
|
import eu.siacs.conversations.android.AbstractPhoneContact;
|
2018-10-28 21:35:31 +00:00
|
|
|
import eu.siacs.conversations.android.JabberIdContact;
|
2018-11-26 11:56:30 +00:00
|
|
|
import eu.siacs.conversations.services.QuickConversationsService;
|
2017-10-27 13:46:12 +00:00
|
|
|
import eu.siacs.conversations.utils.JidHelper;
|
2014-11-16 16:21:21 +00:00
|
|
|
import eu.siacs.conversations.utils.UIHelper;
|
2014-10-22 16:38:44 +00:00
|
|
|
import eu.siacs.conversations.xml.Element;
|
2015-05-05 04:17:34 +00:00
|
|
|
import eu.siacs.conversations.xmpp.pep.Avatar;
|
2020-05-15 15:06:16 +00:00
|
|
|
import eu.siacs.conversations.xmpp.Jid;
|
2014-10-22 16:38:44 +00:00
|
|
|
|
2014-12-21 20:43:58 +00:00
|
|
|
public class Contact implements ListItem, Blockable {
|
2014-10-22 16:38:44 +00:00
|
|
|
public static final String TABLENAME = "contacts";
|
|
|
|
|
|
|
|
public static final String SYSTEMNAME = "systemname";
|
|
|
|
public static final String SERVERNAME = "servername";
|
|
|
|
public static final String JID = "jid";
|
|
|
|
public static final String OPTIONS = "options";
|
|
|
|
public static final String SYSTEMACCOUNT = "systemaccount";
|
|
|
|
public static final String PHOTOURI = "photouri";
|
|
|
|
public static final String KEYS = "pgpkey";
|
|
|
|
public static final String ACCOUNT = "accountUuid";
|
|
|
|
public static final String AVATAR = "avatar";
|
2014-11-16 22:58:30 +00:00
|
|
|
public static final String LAST_PRESENCE = "last_presence";
|
|
|
|
public static final String LAST_TIME = "last_time";
|
2014-11-16 16:21:21 +00:00
|
|
|
public static final String GROUPS = "groups";
|
2018-03-23 15:59:42 +00:00
|
|
|
private String accountUuid;
|
|
|
|
private String systemName;
|
|
|
|
private String serverName;
|
|
|
|
private String presenceName;
|
|
|
|
private String commonName;
|
2014-11-05 20:55:47 +00:00
|
|
|
protected Jid jid;
|
2018-03-23 15:59:42 +00:00
|
|
|
private int subscription = 0;
|
2018-10-26 22:32:09 +00:00
|
|
|
private Uri systemAccount;
|
2018-03-23 15:59:42 +00:00
|
|
|
private String photoUri;
|
|
|
|
private final JSONObject keys;
|
|
|
|
private JSONArray groups = new JSONArray();
|
|
|
|
private final Presences presences = new Presences();
|
2014-10-22 16:38:44 +00:00
|
|
|
protected Account account;
|
2015-05-05 04:17:34 +00:00
|
|
|
protected Avatar avatar;
|
2014-10-22 16:38:44 +00:00
|
|
|
|
2016-06-04 14:16:14 +00:00
|
|
|
private boolean mActive = false;
|
|
|
|
private long mLastseen = 0;
|
|
|
|
private String mLastPresence = null;
|
|
|
|
|
2014-11-04 21:09:27 +00:00
|
|
|
public Contact(final String account, final String systemName, final String serverName,
|
2018-03-23 15:59:42 +00:00
|
|
|
final Jid jid, final int subscription, final String photoUri,
|
2018-10-26 22:32:09 +00:00
|
|
|
final Uri systemAccount, final String keys, final String avatar, final long lastseen,
|
2018-03-23 15:59:42 +00:00
|
|
|
final String presence, final String groups) {
|
2014-10-22 16:38:44 +00:00
|
|
|
this.accountUuid = account;
|
|
|
|
this.systemName = systemName;
|
|
|
|
this.serverName = serverName;
|
|
|
|
this.jid = jid;
|
|
|
|
this.subscription = subscription;
|
|
|
|
this.photoUri = photoUri;
|
|
|
|
this.systemAccount = systemAccount;
|
2018-03-23 15:59:42 +00:00
|
|
|
JSONObject tmpJsonObject;
|
2014-10-22 16:38:44 +00:00
|
|
|
try {
|
2018-03-23 15:59:42 +00:00
|
|
|
tmpJsonObject = (keys == null ? new JSONObject("") : new JSONObject(keys));
|
2014-10-22 16:38:44 +00:00
|
|
|
} catch (JSONException e) {
|
2018-03-23 15:59:42 +00:00
|
|
|
tmpJsonObject = new JSONObject();
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
2018-03-23 15:59:42 +00:00
|
|
|
this.keys = tmpJsonObject;
|
2015-05-05 04:17:34 +00:00
|
|
|
if (avatar != null) {
|
|
|
|
this.avatar = new Avatar();
|
|
|
|
this.avatar.sha1sum = avatar;
|
|
|
|
this.avatar.origin = Avatar.Origin.VCARD; //always assume worst
|
|
|
|
}
|
2014-11-16 16:21:21 +00:00
|
|
|
try {
|
|
|
|
this.groups = (groups == null ? new JSONArray() : new JSONArray(groups));
|
|
|
|
} catch (JSONException e) {
|
|
|
|
this.groups = new JSONArray();
|
|
|
|
}
|
2016-06-04 14:16:14 +00:00
|
|
|
this.mLastseen = lastseen;
|
|
|
|
this.mLastPresence = presence;
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
2014-11-05 20:55:47 +00:00
|
|
|
public Contact(final Jid jid) {
|
2014-10-22 16:38:44 +00:00
|
|
|
this.jid = jid;
|
2018-03-23 15:59:42 +00:00
|
|
|
this.keys = new JSONObject();
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
2014-11-16 22:58:30 +00:00
|
|
|
public static Contact fromCursor(final Cursor cursor) {
|
|
|
|
final Jid jid;
|
|
|
|
try {
|
2018-03-05 17:30:40 +00:00
|
|
|
jid = Jid.of(cursor.getString(cursor.getColumnIndex(JID)));
|
|
|
|
} catch (final IllegalArgumentException e) {
|
2014-11-16 22:58:30 +00:00
|
|
|
// TODO: Borked DB... handle this somehow?
|
|
|
|
return null;
|
|
|
|
}
|
2018-10-26 22:32:09 +00:00
|
|
|
Uri systemAccount;
|
|
|
|
try {
|
|
|
|
systemAccount = Uri.parse(cursor.getString(cursor.getColumnIndex(SYSTEMACCOUNT)));
|
|
|
|
} catch (Exception e) {
|
|
|
|
systemAccount = null;
|
|
|
|
}
|
2014-11-16 22:58:30 +00:00
|
|
|
return new Contact(cursor.getString(cursor.getColumnIndex(ACCOUNT)),
|
|
|
|
cursor.getString(cursor.getColumnIndex(SYSTEMNAME)),
|
|
|
|
cursor.getString(cursor.getColumnIndex(SERVERNAME)),
|
|
|
|
jid,
|
|
|
|
cursor.getInt(cursor.getColumnIndex(OPTIONS)),
|
|
|
|
cursor.getString(cursor.getColumnIndex(PHOTOURI)),
|
2018-10-26 22:32:09 +00:00
|
|
|
systemAccount,
|
2014-11-16 22:58:30 +00:00
|
|
|
cursor.getString(cursor.getColumnIndex(KEYS)),
|
|
|
|
cursor.getString(cursor.getColumnIndex(AVATAR)),
|
2016-06-04 14:16:14 +00:00
|
|
|
cursor.getLong(cursor.getColumnIndex(LAST_TIME)),
|
|
|
|
cursor.getString(cursor.getColumnIndex(LAST_PRESENCE)),
|
2014-11-16 22:58:30 +00:00
|
|
|
cursor.getString(cursor.getColumnIndex(GROUPS)));
|
|
|
|
}
|
|
|
|
|
2014-10-22 16:38:44 +00:00
|
|
|
public String getDisplayName() {
|
2018-03-23 15:52:05 +00:00
|
|
|
if (Config.X509_VERIFICATION && !TextUtils.isEmpty(this.commonName)) {
|
2016-02-02 12:43:20 +00:00
|
|
|
return this.commonName;
|
2018-03-23 15:52:05 +00:00
|
|
|
} else if (!TextUtils.isEmpty(this.systemName)) {
|
2014-11-16 22:58:30 +00:00
|
|
|
return this.systemName;
|
2018-03-23 15:52:05 +00:00
|
|
|
} else if (!TextUtils.isEmpty(this.serverName)) {
|
2014-11-16 22:58:30 +00:00
|
|
|
return this.serverName;
|
2020-05-17 08:24:46 +00:00
|
|
|
} else if (!TextUtils.isEmpty(this.presenceName) && ((QuickConversationsService.isQuicksy() && Config.QUICKSY_DOMAIN.equals(jid.getDomain().toEscapedString())) ||mutualPresenceSubscription())) {
|
2014-11-16 22:58:30 +00:00
|
|
|
return this.presenceName;
|
2018-03-05 17:30:40 +00:00
|
|
|
} else if (jid.getLocal() != null) {
|
2017-10-27 13:46:12 +00:00
|
|
|
return JidHelper.localPartOrFallback(jid);
|
2014-10-22 16:38:44 +00:00
|
|
|
} else {
|
2020-05-17 08:24:46 +00:00
|
|
|
return jid.getDomain().toEscapedString();
|
2014-11-16 22:58:30 +00:00
|
|
|
}
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public String getProfilePhoto() {
|
|
|
|
return this.photoUri;
|
|
|
|
}
|
|
|
|
|
2014-11-05 20:55:47 +00:00
|
|
|
public Jid getJid() {
|
|
|
|
return jid;
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
2014-11-16 16:21:21 +00:00
|
|
|
@Override
|
2016-04-22 19:25:06 +00:00
|
|
|
public List<Tag> getTags(Context context) {
|
2014-12-21 20:43:58 +00:00
|
|
|
final ArrayList<Tag> tags = new ArrayList<>();
|
2018-06-16 16:14:49 +00:00
|
|
|
for (final String group : getGroups(true)) {
|
2014-11-16 16:21:21 +00:00
|
|
|
tags.add(new Tag(group, UIHelper.getColorForName(group)));
|
|
|
|
}
|
2016-06-30 21:08:55 +00:00
|
|
|
Presence.Status status = getShownStatus();
|
2016-04-22 19:25:06 +00:00
|
|
|
if (status != Presence.Status.OFFLINE) {
|
|
|
|
tags.add(UIHelper.getTagForStatus(context, status));
|
2014-11-16 16:21:21 +00:00
|
|
|
}
|
2014-12-21 20:43:58 +00:00
|
|
|
if (isBlocked()) {
|
2018-06-16 16:14:49 +00:00
|
|
|
tags.add(new Tag(context.getString(R.string.blocked), 0xff2e2f3b));
|
2014-12-21 20:43:58 +00:00
|
|
|
}
|
2014-11-16 16:21:21 +00:00
|
|
|
return tags;
|
|
|
|
}
|
|
|
|
|
2016-04-22 19:25:06 +00:00
|
|
|
public boolean match(Context context, String needle) {
|
2018-03-23 15:52:05 +00:00
|
|
|
if (TextUtils.isEmpty(needle)) {
|
2014-11-16 22:58:30 +00:00
|
|
|
return true;
|
|
|
|
}
|
2014-11-17 16:53:19 +00:00
|
|
|
needle = needle.toLowerCase(Locale.US).trim();
|
2014-11-17 16:24:33 +00:00
|
|
|
String[] parts = needle.split("\\s+");
|
|
|
|
if (parts.length > 1) {
|
2018-03-23 15:59:42 +00:00
|
|
|
for (String part : parts) {
|
|
|
|
if (!match(context, part)) {
|
2014-11-17 16:24:33 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
} else {
|
2014-11-17 16:53:19 +00:00
|
|
|
return jid.toString().contains(needle) ||
|
2018-03-23 15:59:42 +00:00
|
|
|
getDisplayName().toLowerCase(Locale.US).contains(needle) ||
|
|
|
|
matchInTag(context, needle);
|
2014-11-17 16:24:33 +00:00
|
|
|
}
|
2014-11-16 22:58:30 +00:00
|
|
|
}
|
|
|
|
|
2016-04-22 19:25:06 +00:00
|
|
|
private boolean matchInTag(Context context, String needle) {
|
2014-11-17 16:53:19 +00:00
|
|
|
needle = needle.toLowerCase(Locale.US);
|
2016-04-22 19:25:06 +00:00
|
|
|
for (Tag tag : getTags(context)) {
|
2014-11-17 16:53:19 +00:00
|
|
|
if (tag.getName().toLowerCase(Locale.US).contains(needle)) {
|
2014-11-16 22:58:30 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public ContentValues getContentValues() {
|
2015-05-29 09:17:26 +00:00
|
|
|
synchronized (this.keys) {
|
|
|
|
final ContentValues values = new ContentValues();
|
|
|
|
values.put(ACCOUNT, accountUuid);
|
|
|
|
values.put(SYSTEMNAME, systemName);
|
|
|
|
values.put(SERVERNAME, serverName);
|
2018-03-05 17:30:40 +00:00
|
|
|
values.put(JID, jid.toString());
|
2015-05-29 09:17:26 +00:00
|
|
|
values.put(OPTIONS, subscription);
|
2018-10-26 22:32:09 +00:00
|
|
|
values.put(SYSTEMACCOUNT, systemAccount != null ? systemAccount.toString() : null);
|
2015-05-29 09:17:26 +00:00
|
|
|
values.put(PHOTOURI, photoUri);
|
|
|
|
values.put(KEYS, keys.toString());
|
|
|
|
values.put(AVATAR, avatar == null ? null : avatar.getFilename());
|
2016-06-04 14:16:14 +00:00
|
|
|
values.put(LAST_PRESENCE, mLastPresence);
|
|
|
|
values.put(LAST_TIME, mLastseen);
|
2015-05-29 09:17:26 +00:00
|
|
|
values.put(GROUPS, groups.toString());
|
|
|
|
return values;
|
|
|
|
}
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
2014-11-16 22:58:30 +00:00
|
|
|
public Account getAccount() {
|
|
|
|
return this.account;
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setAccount(Account account) {
|
|
|
|
this.account = account;
|
|
|
|
this.accountUuid = account.getUuid();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Presences getPresences() {
|
|
|
|
return this.presences;
|
|
|
|
}
|
|
|
|
|
2016-01-17 21:28:38 +00:00
|
|
|
public void updatePresence(final String resource, final Presence presence) {
|
|
|
|
this.presences.updatePresence(resource, presence);
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
2014-12-21 20:43:58 +00:00
|
|
|
public void removePresence(final String resource) {
|
2014-10-22 16:38:44 +00:00
|
|
|
this.presences.removePresence(resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void clearPresences() {
|
|
|
|
this.presences.clearPresences();
|
|
|
|
this.resetOption(Options.PENDING_SUBSCRIPTION_REQUEST);
|
|
|
|
}
|
|
|
|
|
2016-06-30 21:08:55 +00:00
|
|
|
public Presence.Status getShownStatus() {
|
|
|
|
return this.presences.getShownStatus();
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
2015-06-03 12:05:54 +00:00
|
|
|
public boolean setPhotoUri(String uri) {
|
|
|
|
if (uri != null && !uri.equals(this.photoUri)) {
|
|
|
|
this.photoUri = uri;
|
|
|
|
return true;
|
|
|
|
} else if (this.photoUri != null && uri == null) {
|
|
|
|
this.photoUri = null;
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setServerName(String serverName) {
|
|
|
|
this.serverName = serverName;
|
|
|
|
}
|
|
|
|
|
2017-02-10 19:26:21 +00:00
|
|
|
public boolean setSystemName(String systemName) {
|
2017-08-23 19:49:25 +00:00
|
|
|
final String old = getDisplayName();
|
2014-10-22 16:38:44 +00:00
|
|
|
this.systemName = systemName;
|
2017-08-23 19:49:25 +00:00
|
|
|
return !old.equals(getDisplayName());
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
2017-08-23 19:49:25 +00:00
|
|
|
public boolean setPresenceName(String presenceName) {
|
|
|
|
final String old = getDisplayName();
|
2014-10-22 16:38:44 +00:00
|
|
|
this.presenceName = presenceName;
|
2017-08-23 19:49:25 +00:00
|
|
|
return !old.equals(getDisplayName());
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
2016-08-26 11:35:01 +00:00
|
|
|
public Uri getSystemAccount() {
|
2018-10-26 22:32:09 +00:00
|
|
|
return systemAccount;
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
2018-10-26 22:32:09 +00:00
|
|
|
public void setSystemAccount(Uri lookupUri) {
|
|
|
|
this.systemAccount = lookupUri;
|
2014-11-16 22:58:30 +00:00
|
|
|
}
|
|
|
|
|
2018-06-16 16:14:49 +00:00
|
|
|
private Collection<String> getGroups(final boolean unique) {
|
|
|
|
final Collection<String> groups = unique ? new HashSet<>() : new ArrayList<>();
|
2014-11-16 22:58:30 +00:00
|
|
|
for (int i = 0; i < this.groups.length(); ++i) {
|
2014-11-16 16:21:21 +00:00
|
|
|
try {
|
|
|
|
groups.add(this.groups.getString(i));
|
|
|
|
} catch (final JSONException ignored) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return groups;
|
|
|
|
}
|
|
|
|
|
2015-05-29 09:17:26 +00:00
|
|
|
public long getPgpKeyId() {
|
|
|
|
synchronized (this.keys) {
|
|
|
|
if (this.keys.has("pgp_keyid")) {
|
|
|
|
try {
|
|
|
|
return this.keys.getLong("pgp_keyid");
|
|
|
|
} catch (JSONException e) {
|
|
|
|
return 0;
|
|
|
|
}
|
2014-10-22 16:38:44 +00:00
|
|
|
} else {
|
2015-05-29 09:17:26 +00:00
|
|
|
return 0;
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-08 10:46:15 +00:00
|
|
|
public boolean setPgpKeyId(long keyId) {
|
|
|
|
final long previousKeyId = getPgpKeyId();
|
2015-05-29 09:17:26 +00:00
|
|
|
synchronized (this.keys) {
|
2014-10-22 16:38:44 +00:00
|
|
|
try {
|
2015-05-29 09:17:26 +00:00
|
|
|
this.keys.put("pgp_keyid", keyId);
|
2018-09-08 10:46:15 +00:00
|
|
|
return previousKeyId != keyId;
|
2015-05-29 09:17:26 +00:00
|
|
|
} catch (final JSONException ignored) {
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
}
|
2018-09-08 10:46:15 +00:00
|
|
|
return false;
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setOption(int option) {
|
|
|
|
this.subscription |= 1 << option;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void resetOption(int option) {
|
|
|
|
this.subscription &= ~(1 << option);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean getOption(int option) {
|
|
|
|
return ((this.subscription & (1 << option)) != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean showInRoster() {
|
|
|
|
return (this.getOption(Contact.Options.IN_ROSTER) && (!this
|
2018-03-23 15:59:42 +00:00
|
|
|
.getOption(Contact.Options.DIRTY_DELETE)))
|
|
|
|
|| (this.getOption(Contact.Options.DIRTY_PUSH));
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
2018-10-31 09:52:14 +00:00
|
|
|
public boolean showInContactList() {
|
2019-12-02 12:50:58 +00:00
|
|
|
return showInRoster()
|
|
|
|
|| getOption(Options.SYNCED_VIA_OTHER)
|
|
|
|
|| (QuickConversationsService.isQuicksy() && systemAccount != null);
|
2018-08-30 16:45:22 +00:00
|
|
|
}
|
|
|
|
|
2014-10-22 16:38:44 +00:00
|
|
|
public void parseSubscriptionFromElement(Element item) {
|
|
|
|
String ask = item.getAttribute("ask");
|
|
|
|
String subscription = item.getAttribute("subscription");
|
|
|
|
|
2018-06-20 10:59:15 +00:00
|
|
|
if (subscription == null) {
|
|
|
|
this.resetOption(Options.FROM);
|
|
|
|
this.resetOption(Options.TO);
|
|
|
|
} else {
|
2014-11-16 22:58:30 +00:00
|
|
|
switch (subscription) {
|
|
|
|
case "to":
|
|
|
|
this.resetOption(Options.FROM);
|
|
|
|
this.setOption(Options.TO);
|
|
|
|
break;
|
|
|
|
case "from":
|
|
|
|
this.resetOption(Options.TO);
|
|
|
|
this.setOption(Options.FROM);
|
|
|
|
this.resetOption(Options.PREEMPTIVE_GRANT);
|
2016-02-23 15:14:55 +00:00
|
|
|
this.resetOption(Options.PENDING_SUBSCRIPTION_REQUEST);
|
2014-11-16 22:58:30 +00:00
|
|
|
break;
|
|
|
|
case "both":
|
|
|
|
this.setOption(Options.TO);
|
|
|
|
this.setOption(Options.FROM);
|
|
|
|
this.resetOption(Options.PREEMPTIVE_GRANT);
|
2016-02-23 15:14:55 +00:00
|
|
|
this.resetOption(Options.PENDING_SUBSCRIPTION_REQUEST);
|
2014-11-16 22:58:30 +00:00
|
|
|
break;
|
|
|
|
case "none":
|
|
|
|
this.resetOption(Options.FROM);
|
|
|
|
this.resetOption(Options.TO);
|
|
|
|
break;
|
|
|
|
}
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// do NOT override asking if pending push request
|
|
|
|
if (!this.getOption(Contact.Options.DIRTY_PUSH)) {
|
|
|
|
if ((ask != null) && (ask.equals("subscribe"))) {
|
|
|
|
this.setOption(Contact.Options.ASKING);
|
|
|
|
} else {
|
|
|
|
this.resetOption(Contact.Options.ASKING);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-16 16:21:21 +00:00
|
|
|
public void parseGroupsFromElement(Element item) {
|
|
|
|
this.groups = new JSONArray();
|
2014-11-16 22:58:30 +00:00
|
|
|
for (Element element : item.getChildren()) {
|
2014-11-16 16:21:21 +00:00
|
|
|
if (element.getName().equals("group") && element.getContent() != null) {
|
|
|
|
this.groups.put(element.getContent());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-22 16:38:44 +00:00
|
|
|
public Element asElement() {
|
2014-11-05 20:55:47 +00:00
|
|
|
final Element item = new Element("item");
|
2020-05-15 15:06:16 +00:00
|
|
|
item.setAttribute("jid", this.jid);
|
2014-10-22 16:38:44 +00:00
|
|
|
if (this.serverName != null) {
|
|
|
|
item.setAttribute("name", this.serverName);
|
|
|
|
}
|
2018-06-16 16:14:49 +00:00
|
|
|
for (String group : getGroups(false)) {
|
2014-11-16 16:21:21 +00:00
|
|
|
item.addChild("group").setContent(group);
|
|
|
|
}
|
2014-10-22 16:38:44 +00:00
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2018-03-23 15:59:42 +00:00
|
|
|
public int compareTo(@NonNull final ListItem another) {
|
2014-10-22 16:38:44 +00:00
|
|
|
return this.getDisplayName().compareToIgnoreCase(
|
|
|
|
another.getDisplayName());
|
|
|
|
}
|
|
|
|
|
2018-03-11 11:13:56 +00:00
|
|
|
public String getServer() {
|
2020-05-17 08:24:46 +00:00
|
|
|
return getJid().getDomain().toEscapedString();
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
2015-05-05 04:17:34 +00:00
|
|
|
public boolean setAvatar(Avatar avatar) {
|
2019-01-17 16:55:47 +00:00
|
|
|
return setAvatar(avatar, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean setAvatar(Avatar avatar, boolean previouslyOmittedPepFetch) {
|
2015-05-05 04:17:34 +00:00
|
|
|
if (this.avatar != null && this.avatar.equals(avatar)) {
|
2014-10-22 16:38:44 +00:00
|
|
|
return false;
|
|
|
|
} else {
|
2019-01-17 16:55:47 +00:00
|
|
|
if (!previouslyOmittedPepFetch && this.avatar != null && this.avatar.origin == Avatar.Origin.PEP && avatar.origin == Avatar.Origin.VCARD) {
|
2015-05-05 04:17:34 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
this.avatar = avatar;
|
2014-10-22 16:38:44 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-21 10:27:58 +00:00
|
|
|
public String getAvatarFilename() {
|
2015-05-05 04:17:34 +00:00
|
|
|
return avatar == null ? null : avatar.getFilename();
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|
|
|
|
|
2018-09-21 10:27:58 +00:00
|
|
|
public Avatar getAvatar() {
|
|
|
|
return avatar;
|
|
|
|
}
|
|
|
|
|
2016-10-07 08:05:08 +00:00
|
|
|
public boolean mutualPresenceSubscription() {
|
2014-10-22 16:38:44 +00:00
|
|
|
return getOption(Options.FROM) && getOption(Options.TO);
|
|
|
|
}
|
2014-11-15 23:20:20 +00:00
|
|
|
|
2014-12-21 20:43:58 +00:00
|
|
|
@Override
|
|
|
|
public boolean isBlocked() {
|
|
|
|
return getAccount().isBlocked(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isDomainBlocked() {
|
2020-05-18 07:14:57 +00:00
|
|
|
return getAccount().isBlocked(this.getJid().getDomain());
|
2014-12-21 20:43:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Jid getBlockedJid() {
|
|
|
|
if (isDomainBlocked()) {
|
2020-05-18 07:14:57 +00:00
|
|
|
return getJid().getDomain();
|
2014-12-21 20:43:58 +00:00
|
|
|
} else {
|
|
|
|
return getJid();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-05 04:17:34 +00:00
|
|
|
public boolean isSelf() {
|
2018-04-21 17:52:37 +00:00
|
|
|
return account.getJid().asBareJid().equals(jid.asBareJid());
|
|
|
|
}
|
|
|
|
|
2018-05-01 21:18:05 +00:00
|
|
|
boolean isOwnServer() {
|
|
|
|
return account.getJid().getDomain().equals(jid.asBareJid().toString());
|
2015-05-05 04:17:34 +00:00
|
|
|
}
|
|
|
|
|
2016-02-02 12:43:20 +00:00
|
|
|
public void setCommonName(String cn) {
|
|
|
|
this.commonName = cn;
|
|
|
|
}
|
|
|
|
|
2016-06-04 14:16:14 +00:00
|
|
|
public void flagActive() {
|
|
|
|
this.mActive = true;
|
|
|
|
}
|
2014-11-16 22:58:30 +00:00
|
|
|
|
2016-06-04 14:16:14 +00:00
|
|
|
public void flagInactive() {
|
|
|
|
this.mActive = false;
|
|
|
|
}
|
2014-11-16 22:58:30 +00:00
|
|
|
|
2016-06-04 14:16:14 +00:00
|
|
|
public boolean isActive() {
|
|
|
|
return this.mActive;
|
|
|
|
}
|
|
|
|
|
2017-03-20 16:58:58 +00:00
|
|
|
public boolean setLastseen(long timestamp) {
|
|
|
|
if (timestamp > this.mLastseen) {
|
|
|
|
this.mLastseen = timestamp;
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
2016-06-04 14:16:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public long getLastseen() {
|
|
|
|
return this.mLastseen;
|
|
|
|
}
|
|
|
|
|
2016-07-28 20:58:37 +00:00
|
|
|
public void setLastResource(String resource) {
|
|
|
|
this.mLastPresence = resource;
|
2016-06-04 14:16:14 +00:00
|
|
|
}
|
|
|
|
|
2016-07-28 20:58:37 +00:00
|
|
|
public String getLastResource() {
|
2016-06-04 14:16:14 +00:00
|
|
|
return this.mLastPresence;
|
2014-11-16 22:58:30 +00:00
|
|
|
}
|
|
|
|
|
2018-06-22 15:42:52 +00:00
|
|
|
public String getServerName() {
|
|
|
|
return serverName;
|
|
|
|
}
|
|
|
|
|
2018-10-28 18:05:16 +00:00
|
|
|
public synchronized boolean setPhoneContact(AbstractPhoneContact phoneContact) {
|
|
|
|
setOption(getOption(phoneContact.getClass()));
|
|
|
|
setSystemAccount(phoneContact.getLookupUri());
|
|
|
|
boolean changed = setSystemName(phoneContact.getDisplayName());
|
|
|
|
changed |= setPhotoUri(phoneContact.getPhotoUri());
|
|
|
|
return changed;
|
|
|
|
}
|
|
|
|
|
|
|
|
public synchronized boolean unsetPhoneContact(Class<?extends AbstractPhoneContact> clazz) {
|
|
|
|
resetOption(getOption(clazz));
|
|
|
|
boolean changed = false;
|
|
|
|
if (!getOption(Options.SYNCED_VIA_ADDRESSBOOK) && !getOption(Options.SYNCED_VIA_OTHER)) {
|
|
|
|
setSystemAccount(null);
|
|
|
|
changed |= setPhotoUri(null);
|
|
|
|
changed |= setSystemName(null);
|
|
|
|
}
|
|
|
|
return changed;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int getOption(Class<? extends AbstractPhoneContact> clazz) {
|
2018-10-28 21:35:31 +00:00
|
|
|
if (clazz == JabberIdContact.class) {
|
2018-10-28 18:05:16 +00:00
|
|
|
return Options.SYNCED_VIA_ADDRESSBOOK;
|
|
|
|
} else {
|
|
|
|
return Options.SYNCED_VIA_OTHER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-25 09:07:02 +00:00
|
|
|
@Override
|
|
|
|
public int getAvatarBackgroundColor() {
|
|
|
|
return UIHelper.getColorForName(jid != null ? jid.asBareJid().toString() : getDisplayName());
|
|
|
|
}
|
|
|
|
|
|
|
|
public final class Options {
|
2014-11-16 22:58:30 +00:00
|
|
|
public static final int TO = 0;
|
|
|
|
public static final int FROM = 1;
|
|
|
|
public static final int ASKING = 2;
|
|
|
|
public static final int PREEMPTIVE_GRANT = 3;
|
|
|
|
public static final int IN_ROSTER = 4;
|
|
|
|
public static final int PENDING_SUBSCRIPTION_REQUEST = 5;
|
|
|
|
public static final int DIRTY_PUSH = 6;
|
|
|
|
public static final int DIRTY_DELETE = 7;
|
2018-10-28 18:05:16 +00:00
|
|
|
private static final int SYNCED_VIA_ADDRESSBOOK = 8;
|
2018-10-28 21:35:31 +00:00
|
|
|
public static final int SYNCED_VIA_OTHER = 9;
|
2014-11-16 22:58:30 +00:00
|
|
|
}
|
2014-10-22 16:38:44 +00:00
|
|
|
}
|