diff options
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus/entities')
14 files changed, 0 insertions, 3594 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/AbstractEntity.java b/src/main/java/de/thedevstack/conversationsplus/entities/AbstractEntity.java deleted file mode 100644 index ebc0a8d5..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/entities/AbstractEntity.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.thedevstack.conversationsplus.entities; - -import android.content.ContentValues; - -public abstract class AbstractEntity { - - public static final String UUID = "uuid"; - - protected String uuid; - - public String getUuid() { - return this.uuid; - } - - public abstract ContentValues getContentValues(); - - public boolean equals(AbstractEntity entity) { - return this.getUuid().equals(entity.getUuid()); - } -} diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Account.java b/src/main/java/de/thedevstack/conversationsplus/entities/Account.java deleted file mode 100644 index 8d879fa0..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/entities/Account.java +++ /dev/null @@ -1,427 +0,0 @@ -package de.thedevstack.conversationsplus.entities; - -import android.content.ContentValues; -import android.database.Cursor; -import android.os.SystemClock; - -import net.java.otr4j.crypto.OtrCryptoEngineImpl; -import net.java.otr4j.crypto.OtrCryptoException; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.security.PublicKey; -import java.security.interfaces.DSAPublicKey; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.CopyOnWriteArraySet; - -import de.thedevstack.conversationsplus.Config; -import de.thedevstack.conversationsplus.R; -import de.thedevstack.conversationsplus.crypto.OtrService; -import de.thedevstack.conversationsplus.services.XmppConnectionService; -import de.thedevstack.conversationsplus.xmpp.XmppConnection; -import de.thedevstack.conversationsplus.xmpp.jid.InvalidJidException; -import de.thedevstack.conversationsplus.xmpp.jid.Jid; - -public class Account extends AbstractEntity { - - public static final String TABLENAME = "accounts"; - - public static final String USERNAME = "username"; - public static final String SERVER = "server"; - public static final String PASSWORD = "password"; - public static final String OPTIONS = "options"; - public static final String ROSTERVERSION = "rosterversion"; - public static final String KEYS = "keys"; - public static final String AVATAR = "avatar"; - - public static final String PINNED_MECHANISM_KEY = "pinned_mechanism"; - - public static final int OPTION_USETLS = 0; - public static final int OPTION_DISABLED = 1; - public static final int OPTION_REGISTER = 2; - public static final int OPTION_USECOMPRESSION = 3; - - public boolean httpUploadAvailable() { - return xmppConnection != null && xmppConnection.getFeatures().httpUpload(); - } - - public static enum State { - DISABLED, - OFFLINE, - CONNECTING, - ONLINE, - NO_INTERNET, - UNAUTHORIZED(true), - SERVER_NOT_FOUND(true), - REGISTRATION_FAILED(true), - REGISTRATION_CONFLICT(true), - REGISTRATION_SUCCESSFUL, - REGISTRATION_NOT_SUPPORTED(true), - SECURITY_ERROR(true), - INCOMPATIBLE_SERVER(true); - - private final boolean isError; - - public boolean isError() { - return this.isError; - } - - private State(final boolean isError) { - this.isError = isError; - } - - private State() { - this(false); - } - - public int getReadableId() { - switch (this) { - case DISABLED: - return R.string.account_status_disabled; - case ONLINE: - return R.string.account_status_online; - case CONNECTING: - return R.string.account_status_connecting; - case OFFLINE: - return R.string.account_status_offline; - case UNAUTHORIZED: - return R.string.account_status_unauthorized; - case SERVER_NOT_FOUND: - return R.string.account_status_not_found; - case NO_INTERNET: - return R.string.account_status_no_internet; - case REGISTRATION_FAILED: - return R.string.account_status_regis_fail; - case REGISTRATION_CONFLICT: - return R.string.account_status_regis_conflict; - case REGISTRATION_SUCCESSFUL: - return R.string.account_status_regis_success; - case REGISTRATION_NOT_SUPPORTED: - return R.string.account_status_regis_not_sup; - case SECURITY_ERROR: - return R.string.account_status_security_error; - case INCOMPATIBLE_SERVER: - return R.string.account_status_incompatible_server; - default: - return R.string.account_status_unknown; - } - } - } - - public List<Conversation> pendingConferenceJoins = new CopyOnWriteArrayList<>(); - public List<Conversation> pendingConferenceLeaves = new CopyOnWriteArrayList<>(); - protected Jid jid; - protected String password; - protected int options = 0; - protected String rosterVersion; - protected State status = State.OFFLINE; - protected JSONObject keys = new JSONObject(); - protected String avatar; - protected boolean online = false; - private OtrService mOtrService = null; - private XmppConnection xmppConnection = null; - private long mEndGracePeriod = 0L; - private String otrFingerprint; - private final Roster roster = new Roster(this); - private List<Bookmark> bookmarks = new CopyOnWriteArrayList<>(); - private final Collection<Jid> blocklist = new CopyOnWriteArraySet<>(); - private XmppConnectionService mXmppConnectionService; - - public Account() { - this.uuid = "0"; - } - - public Account(final Jid jid, final String password) { - this(java.util.UUID.randomUUID().toString(), jid, - password, 0, null, "", null); - } - - public Account(final String uuid, final Jid jid, - final String password, final int options, final String rosterVersion, final String keys, - final String avatar) { - this.uuid = uuid; - this.jid = jid; - if (jid.isBareJid()) { - this.setResource("mobile"); - } - this.password = password; - this.options = options; - this.rosterVersion = rosterVersion; - try { - this.keys = new JSONObject(keys); - } catch (final JSONException ignored) { - this.keys = new JSONObject(); - } - this.avatar = avatar; - } - - public static Account fromCursor(final Cursor cursor) { - Jid jid = null; - try { - jid = Jid.fromParts(cursor.getString(cursor.getColumnIndex(USERNAME)), - cursor.getString(cursor.getColumnIndex(SERVER)), "mobile"); - } catch (final InvalidJidException ignored) { - } - return new Account(cursor.getString(cursor.getColumnIndex(UUID)), - jid, - cursor.getString(cursor.getColumnIndex(PASSWORD)), - cursor.getInt(cursor.getColumnIndex(OPTIONS)), - cursor.getString(cursor.getColumnIndex(ROSTERVERSION)), - cursor.getString(cursor.getColumnIndex(KEYS)), - cursor.getString(cursor.getColumnIndex(AVATAR))); - } - - public boolean isOptionSet(final int option) { - return ((options & (1 << option)) != 0); - } - - public void setOption(final int option, final boolean value) { - if (value) { - this.options |= 1 << option; - } else { - this.options &= ~(1 << option); - } - } - - public String getUsername() { - return jid.getLocalpart(); - } - - public void setUsername(final String username) throws InvalidJidException { - jid = Jid.fromParts(username, jid.getDomainpart(), jid.getResourcepart()); - } - - public Jid getServer() { - return jid.toDomainJid(); - } - - public void setServer(final String server) throws InvalidJidException { - jid = Jid.fromParts(jid.getLocalpart(), server, jid.getResourcepart()); - } - - public String getPassword() { - return password; - } - - public void setPassword(final String password) { - this.password = password; - } - - public State getStatus() { - if (isOptionSet(OPTION_DISABLED)) { - return State.DISABLED; - } else { - return this.status; - } - } - - public void setStatus(final State status) { - this.status = status; - } - - public boolean errorStatus() { - return getStatus().isError(); - } - - public boolean hasErrorStatus() { - return getXmppConnection() != null && getStatus().isError() && getXmppConnection().getAttempt() >= 2; - } - - public String getResource() { - return jid.getResourcepart(); - } - - public boolean setResource(final String resource) { - final String oldResource = jid.getResourcepart(); - if (oldResource == null || !oldResource.equals(resource)) { - try { - jid = Jid.fromParts(jid.getLocalpart(), jid.getDomainpart(), resource); - return true; - } catch (final InvalidJidException ignored) { - return true; - } - } - return false; - } - - public Jid getJid() { - return jid; - } - - public JSONObject getKeys() { - return keys; - } - - public boolean setKey(final String keyName, final String keyValue) { - try { - this.keys.put(keyName, keyValue); - return true; - } catch (final JSONException e) { - return false; - } - } - - @Override - public ContentValues getContentValues() { - final ContentValues values = new ContentValues(); - values.put(UUID, uuid); - values.put(USERNAME, jid.getLocalpart()); - values.put(SERVER, jid.getDomainpart()); - values.put(PASSWORD, password); - values.put(OPTIONS, options); - values.put(KEYS, this.keys.toString()); - values.put(ROSTERVERSION, rosterVersion); - values.put(AVATAR, avatar); - return values; - } - - public void initAccountServices(final XmppConnectionService context) { - this.mXmppConnectionService = context; - this.mOtrService = new OtrService(context, this); - } - - public OtrService getOtrService() { - return this.mOtrService; - } - - public XmppConnection getXmppConnection() { - return this.xmppConnection; - } - - public void setXmppConnection(final XmppConnection connection) { - this.xmppConnection = connection; - } - - public String getOtrFingerprint() { - if (this.otrFingerprint == null) { - try { - if (this.mOtrService == null) { - return null; - } - final PublicKey publicKey = this.mOtrService.getPublicKey(); - if (publicKey == null || !(publicKey instanceof DSAPublicKey)) { - return null; - } - this.otrFingerprint = new OtrCryptoEngineImpl().getFingerprint(publicKey); - return this.otrFingerprint; - } catch (final OtrCryptoException ignored) { - return null; - } - } else { - return this.otrFingerprint; - } - } - - public String getRosterVersion() { - if (this.rosterVersion == null) { - return ""; - } else { - return this.rosterVersion; - } - } - - public void setRosterVersion(final String version) { - this.rosterVersion = version; - } - - public int countPresences() { - return this.getRoster().getContact(this.getJid().toBareJid()).getPresences().size(); - } - - public String getPgpSignature() { - if (keys.has("pgp_signature")) { - try { - return keys.getString("pgp_signature"); - } catch (final JSONException e) { - return null; - } - } else { - return null; - } - } - - public Roster getRoster() { - return this.roster; - } - - public List<Bookmark> getBookmarks() { - return this.bookmarks; - } - - public void setBookmarks(final List<Bookmark> bookmarks) { - this.bookmarks = bookmarks; - } - - public boolean hasBookmarkFor(final Jid conferenceJid) { - for (final Bookmark bookmark : this.bookmarks) { - final Jid jid = bookmark.getJid(); - if (jid != null && jid.equals(conferenceJid.toBareJid())) { - return true; - } - } - return false; - } - - public boolean setAvatar(final String filename) { - if (this.avatar != null && this.avatar.equals(filename)) { - return false; - } else { - this.avatar = filename; - return true; - } - } - - public String getAvatar() { - return this.avatar; - } - - public void activateGracePeriod() { - this.mEndGracePeriod = SystemClock.elapsedRealtime() - + (Config.CARBON_GRACE_PERIOD * 1000); - } - - public void deactivateGracePeriod() { - this.mEndGracePeriod = 0L; - } - - public boolean inGracePeriod() { - return SystemClock.elapsedRealtime() < this.mEndGracePeriod; - } - - public String getShareableUri() { - final String fingerprint = this.getOtrFingerprint(); - if (fingerprint != null) { - return "xmpp:" + this.getJid().toBareJid().toString() + "?otr-fingerprint="+fingerprint; - } else { - return "xmpp:" + this.getJid().toBareJid().toString(); - } - } - - public boolean isBlocked(final ListItem contact) { - final Jid jid = contact.getJid(); - return jid != null && (blocklist.contains(jid.toBareJid()) || blocklist.contains(jid.toDomainJid())); - } - - public boolean isBlocked(final Jid jid) { - return jid != null && blocklist.contains(jid.toBareJid()); - } - - public Collection<Jid> getBlocklist() { - return this.blocklist; - } - - public void clearBlocklist() { - getBlocklist().clear(); - } - - public boolean isOnlineAndConnected() { - return this.getStatus() == State.ONLINE && this.getXmppConnection() != null; - } - - public XmppConnectionService getXmppConnectionService() { - return mXmppConnectionService; - } -} diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Blockable.java b/src/main/java/de/thedevstack/conversationsplus/entities/Blockable.java deleted file mode 100644 index beff901d..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/entities/Blockable.java +++ /dev/null @@ -1,11 +0,0 @@ -package de.thedevstack.conversationsplus.entities; - -import de.thedevstack.conversationsplus.xmpp.jid.Jid; - -public interface Blockable { - public boolean isBlocked(); - public boolean isDomainBlocked(); - public Jid getBlockedJid(); - public Jid getJid(); - public Account getAccount(); -} diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Bookmark.java b/src/main/java/de/thedevstack/conversationsplus/entities/Bookmark.java deleted file mode 100644 index 9e67bf2d..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/entities/Bookmark.java +++ /dev/null @@ -1,159 +0,0 @@ -package de.thedevstack.conversationsplus.entities; - -import android.graphics.Color; - -import android.graphics.Color; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -import de.thedevstack.conversationsplus.utils.UIHelper; -import de.thedevstack.conversationsplus.xml.Element; -import de.thedevstack.conversationsplus.xmpp.jid.Jid; - -public class Bookmark extends Element implements ListItem { - - private Account account; - private Conversation mJoinedConversation; - - public Bookmark(final Account account, final Jid jid) { - super("conference"); - this.setAttribute("jid", jid.toString()); - this.account = account; - } - - private Bookmark(Account account) { - super("conference"); - this.account = account; - } - - public static Bookmark parse(Element element, Account account) { - Bookmark bookmark = new Bookmark(account); - bookmark.setAttributes(element.getAttributes()); - bookmark.setChildren(element.getChildren()); - return bookmark; - } - - public void setAutojoin(boolean autojoin) { - if (autojoin) { - this.setAttribute("autojoin", "true"); - } else { - this.setAttribute("autojoin", "false"); - } - } - - @Override - public int compareTo(final ListItem another) { - return this.getDisplayName().compareToIgnoreCase( - another.getDisplayName()); - } - - @Override - public String getDisplayName() { - if (this.mJoinedConversation != null - && (this.mJoinedConversation.getMucOptions().getSubject() != null)) { - return this.mJoinedConversation.getMucOptions().getSubject(); - } else if (getName() != null) { - return getName(); - } else { - return this.getJid().getLocalpart(); - } - } - - @Override - public Jid getJid() { - return this.getAttributeAsJid("jid"); - } - - @Override - public List<Tag> getTags() { - ArrayList<Tag> tags = new ArrayList<Tag>(); - for (Element element : getChildren()) { - if (element.getName().equals("group") && element.getContent() != null) { - String group = element.getContent(); - tags.add(new Tag(group, UIHelper.getColorForName(group))); - } - } - return tags; - } - - @Override - public int getStatusColor() { - return Color.parseColor("#259B23"); - } - - public String getNick() { - return this.findChildContent("nick"); - } - - public void setNick(String nick) { - Element element = this.findChild("nick"); - if (element == null) { - element = this.addChild("nick"); - } - element.setContent(nick); - } - - public boolean autojoin() { - return this.getAttributeAsBoolean("autojoin"); - } - - public String getPassword() { - return this.findChildContent("password"); - } - - public void setPassword(String password) { - Element element = this.findChild("password"); - if (element != null) { - element.setContent(password); - } - } - - public boolean match(String needle) { - if (needle == null) { - return true; - } - needle = needle.toLowerCase(Locale.US); - final Jid jid = getJid(); - return (jid != null && jid.toString().contains(needle)) || - getDisplayName().toLowerCase(Locale.US).contains(needle) || - matchInTag(needle); - } - - private boolean matchInTag(String needle) { - needle = needle.toLowerCase(Locale.US); - for (Tag tag : getTags()) { - if (tag.getName().toLowerCase(Locale.US).contains(needle)) { - return true; - } - } - return false; - } - - public Account getAccount() { - return this.account; - } - - public Conversation getConversation() { - return this.mJoinedConversation; - } - - public void setConversation(Conversation conversation) { - this.mJoinedConversation = conversation; - } - - public String getName() { - return this.getAttribute("name"); - } - - public void setName(String name) { - this.name = name; - } - - public void unregisterConversation() { - if (this.mJoinedConversation != null) { - this.mJoinedConversation.deregisterWithBookmark(); - } - } -} diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Contact.java b/src/main/java/de/thedevstack/conversationsplus/entities/Contact.java deleted file mode 100644 index ca734403..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/entities/Contact.java +++ /dev/null @@ -1,531 +0,0 @@ -package de.thedevstack.conversationsplus.entities; - -import android.content.ContentValues; -import android.database.Cursor; -import android.graphics.Color; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -import de.thedevstack.conversationsplus.utils.UIHelper; -import de.thedevstack.conversationsplus.xml.Element; -import de.thedevstack.conversationsplus.xmpp.jid.InvalidJidException; -import de.thedevstack.conversationsplus.xmpp.jid.Jid; -import de.thedevstack.conversationsplus.xmpp.pep.Avatar; - -public class Contact implements ListItem, Blockable { - 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"; - public static final String LAST_PRESENCE = "last_presence"; - public static final String LAST_TIME = "last_time"; - public static final String GROUPS = "groups"; - public Lastseen lastseen = new Lastseen(); - protected String accountUuid; - protected String systemName; - protected String serverName; - protected String presenceName; - protected Jid jid; - protected int subscription = 0; - protected String systemAccount; - protected String photoUri; - protected JSONObject keys = new JSONObject(); - protected JSONArray groups = new JSONArray(); - protected Presences presences = new Presences(); - protected Account account; - protected Avatar avatar; - - public Contact(final String account, final String systemName, final String serverName, - final Jid jid, final int subscription, final String photoUri, - final String systemAccount, final String keys, final String avatar, final Lastseen lastseen, final String groups) { - this.accountUuid = account; - this.systemName = systemName; - this.serverName = serverName; - this.jid = jid; - this.subscription = subscription; - this.photoUri = photoUri; - this.systemAccount = systemAccount; - try { - this.keys = (keys == null ? new JSONObject("") : new JSONObject(keys)); - } catch (JSONException e) { - this.keys = new JSONObject(); - } - if (avatar != null) { - this.avatar = new Avatar(); - this.avatar.sha1sum = avatar; - this.avatar.origin = Avatar.Origin.VCARD; //always assume worst - } - try { - this.groups = (groups == null ? new JSONArray() : new JSONArray(groups)); - } catch (JSONException e) { - this.groups = new JSONArray(); - } - this.lastseen = lastseen; - } - - public Contact(final Jid jid) { - this.jid = jid; - } - - public static Contact fromCursor(final Cursor cursor) { - final Lastseen lastseen = new Lastseen( - cursor.getString(cursor.getColumnIndex(LAST_PRESENCE)), - cursor.getLong(cursor.getColumnIndex(LAST_TIME))); - final Jid jid; - try { - jid = Jid.fromString(cursor.getString(cursor.getColumnIndex(JID)), true); - } catch (final InvalidJidException e) { - // TODO: Borked DB... handle this somehow? - return null; - } - 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)), - cursor.getString(cursor.getColumnIndex(SYSTEMACCOUNT)), - cursor.getString(cursor.getColumnIndex(KEYS)), - cursor.getString(cursor.getColumnIndex(AVATAR)), - lastseen, - cursor.getString(cursor.getColumnIndex(GROUPS))); - } - - public String getDisplayName() { - if (this.systemName != null) { - return this.systemName; - } else if (this.serverName != null) { - return this.serverName; - } else if (this.presenceName != null) { - return this.presenceName; - } else if (jid.hasLocalpart()) { - return jid.getLocalpart(); - } else { - return jid.getDomainpart(); - } - } - - public String getProfilePhoto() { - return this.photoUri; - } - - public Jid getJid() { - return jid; - } - - @Override - public List<Tag> getTags() { - final ArrayList<Tag> tags = new ArrayList<>(); - for (final String group : getGroups()) { - tags.add(new Tag(group, UIHelper.getColorForName(group))); - } - switch (getMostAvailableStatus()) { - case Presences.CHAT: - case Presences.ONLINE: - tags.add(new Tag("online", 0xff259b24)); - break; - case Presences.AWAY: - tags.add(new Tag("away", 0xffff9800)); - break; - case Presences.XA: - tags.add(new Tag("not available", 0xfff44336)); - break; - case Presences.DND: - tags.add(new Tag("dnd", 0xfff44336)); - break; - } - if (isBlocked()) { - tags.add(new Tag("blocked", 0xff2e2f3b)); - } - return tags; - } - - @Override - public int getStatusColor() { - return Color.parseColor(UIHelper.getStatusColor(getMostAvailableStatus())); - } - - public boolean match(String needle) { - if (needle == null || needle.isEmpty()) { - return true; - } - needle = needle.toLowerCase(Locale.US); - String[] parts = needle.split("\\s+"); - if (parts.length > 1) { - for(int i = 0; i < parts.length; ++i) { - if (!match(parts[i])) { - return false; - } - } - return true; - } else { - return jid.toString().contains(needle) || - getDisplayName().toLowerCase(Locale.US).contains(needle) || - matchInTag(needle); - } - } - - private boolean matchInTag(String needle) { - needle = needle.toLowerCase(Locale.US); - for (Tag tag : getTags()) { - if (tag.getName().toLowerCase(Locale.US).contains(needle)) { - return true; - } - } - return false; - } - - public ContentValues getContentValues() { - final ContentValues values = new ContentValues(); - values.put(ACCOUNT, accountUuid); - values.put(SYSTEMNAME, systemName); - values.put(SERVERNAME, serverName); - values.put(JID, jid.toString()); - values.put(OPTIONS, subscription); - values.put(SYSTEMACCOUNT, systemAccount); - values.put(PHOTOURI, photoUri); - values.put(KEYS, keys.toString()); - values.put(AVATAR, avatar == null ? null : avatar.getFilename()); - values.put(LAST_PRESENCE, lastseen.presence); - values.put(LAST_TIME, lastseen.time); - values.put(GROUPS, groups.toString()); - return values; - } - - public int getSubscription() { - return this.subscription; - } - - public Account getAccount() { - return this.account; - } - - public void setAccount(Account account) { - this.account = account; - this.accountUuid = account.getUuid(); - } - - public Presences getPresences() { - return this.presences; - } - - public void setPresences(Presences pres) { - this.presences = pres; - } - - public void updatePresence(final String resource, final int status) { - this.presences.updatePresence(resource, status); - } - - public void removePresence(final String resource) { - this.presences.removePresence(resource); - } - - public void clearPresences() { - this.presences.clearPresences(); - this.resetOption(Options.PENDING_SUBSCRIPTION_REQUEST); - } - - public int getMostAvailableStatus() { - return this.presences.getMostAvailableStatus(); - } - - 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; - } - } - - public void setServerName(String serverName) { - this.serverName = serverName; - } - - public void setSystemName(String systemName) { - this.systemName = systemName; - } - - public void setPresenceName(String presenceName) { - this.presenceName = presenceName; - } - - public String getSystemAccount() { - return systemAccount; - } - - public void setSystemAccount(String account) { - this.systemAccount = account; - } - - public List<String> getGroups() { - ArrayList<String> groups = new ArrayList<String>(); - for (int i = 0; i < this.groups.length(); ++i) { - try { - groups.add(this.groups.getString(i)); - } catch (final JSONException ignored) { - } - } - return groups; - } - - public ArrayList<String> getOtrFingerprints() { - final ArrayList<String> fingerprints = new ArrayList<String>(); - try { - if (this.keys.has("otr_fingerprints")) { - final JSONArray prints = this.keys.getJSONArray("otr_fingerprints"); - for (int i = 0; i < prints.length(); ++i) { - final String print = prints.isNull(i) ? null : prints.getString(i); - if (print != null && !print.isEmpty()) { - fingerprints.add(prints.getString(i)); - } - } - } - } catch (final JSONException ignored) { - - } - return fingerprints; - } - - public boolean addOtrFingerprint(String print) { - if (getOtrFingerprints().contains(print)) { - return false; - } - try { - JSONArray fingerprints; - if (!this.keys.has("otr_fingerprints")) { - fingerprints = new JSONArray(); - - } else { - fingerprints = this.keys.getJSONArray("otr_fingerprints"); - } - fingerprints.put(print); - this.keys.put("otr_fingerprints", fingerprints); - return true; - } catch (final JSONException ignored) { - return false; - } - } - - public long getPgpKeyId() { - if (this.keys.has("pgp_keyid")) { - try { - return this.keys.getLong("pgp_keyid"); - } catch (JSONException e) { - return 0; - } - } else { - return 0; - } - } - - public void setPgpKeyId(long keyId) { - try { - this.keys.put("pgp_keyid", keyId); - } catch (final JSONException ignored) { - - } - } - - 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 - .getOption(Contact.Options.DIRTY_DELETE))) - || (this.getOption(Contact.Options.DIRTY_PUSH)); - } - - public void parseSubscriptionFromElement(Element item) { - String ask = item.getAttribute("ask"); - String subscription = item.getAttribute("subscription"); - - if (subscription != null) { - 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); - break; - case "both": - this.setOption(Options.TO); - this.setOption(Options.FROM); - this.resetOption(Options.PREEMPTIVE_GRANT); - break; - case "none": - this.resetOption(Options.FROM); - this.resetOption(Options.TO); - break; - } - } - - // 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); - } - } - } - - public void parseGroupsFromElement(Element item) { - this.groups = new JSONArray(); - for (Element element : item.getChildren()) { - if (element.getName().equals("group") && element.getContent() != null) { - this.groups.put(element.getContent()); - } - } - } - - public Element asElement() { - final Element item = new Element("item"); - item.setAttribute("jid", this.jid.toString()); - if (this.serverName != null) { - item.setAttribute("name", this.serverName); - } - for (String group : getGroups()) { - item.addChild("group").setContent(group); - } - return item; - } - - @Override - public int compareTo(final ListItem another) { - return this.getDisplayName().compareToIgnoreCase( - another.getDisplayName()); - } - - public Jid getServer() { - return getJid().toDomainJid(); - } - - public boolean setAvatar(Avatar avatar) { - if (this.avatar != null && this.avatar.equals(avatar)) { - return false; - } else { - if (this.avatar != null && this.avatar.origin == Avatar.Origin.PEP && avatar.origin == Avatar.Origin.VCARD) { - return false; - } - this.avatar = avatar; - return true; - } - } - - public String getAvatar() { - return avatar == null ? null : avatar.getFilename(); - } - - public boolean deleteOtrFingerprint(String fingerprint) { - boolean success = false; - try { - if (this.keys.has("otr_fingerprints")) { - JSONArray newPrints = new JSONArray(); - JSONArray oldPrints = this.keys - .getJSONArray("otr_fingerprints"); - for (int i = 0; i < oldPrints.length(); ++i) { - if (!oldPrints.getString(i).equals(fingerprint)) { - newPrints.put(oldPrints.getString(i)); - } else { - success = true; - } - } - this.keys.put("otr_fingerprints", newPrints); - } - return success; - } catch (JSONException e) { - return false; - } - } - - public boolean trusted() { - return getOption(Options.FROM) && getOption(Options.TO); - } - - public String getShareableUri() { - if (getOtrFingerprints().size() >= 1) { - String otr = getOtrFingerprints().get(0); - return "xmpp:" + getJid().toBareJid().toString() + "?otr-fingerprint=" + otr; - } else { - return "xmpp:" + getJid().toBareJid().toString(); - } - } - - @Override - public boolean isBlocked() { - return getAccount().isBlocked(this); - } - - @Override - public boolean isDomainBlocked() { - return getAccount().isBlocked(this.getJid().toDomainJid()); - } - - @Override - public Jid getBlockedJid() { - if (isDomainBlocked()) { - return getJid().toDomainJid(); - } else { - return getJid(); - } - } - - public boolean isSelf() { - return account.getJid().toBareJid().equals(getJid().toBareJid()); - } - - public static class Lastseen { - public long time; - public String presence; - - public Lastseen() { - this(null, 0); - } - - public Lastseen(final String presence, final long time) { - this.presence = presence; - this.time = time; - } - } - - public final class Options { - 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; - } -} diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java b/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java deleted file mode 100644 index e26f7944..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java +++ /dev/null @@ -1,789 +0,0 @@ -package de.thedevstack.conversationsplus.entities; - -import android.content.ContentValues; -import android.database.Cursor; - -import net.java.otr4j.OtrException; -import net.java.otr4j.crypto.OtrCryptoException; -import net.java.otr4j.session.SessionID; -import net.java.otr4j.session.SessionImpl; -import net.java.otr4j.session.SessionStatus; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.security.interfaces.DSAPublicKey; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; - -import de.thedevstack.conversationsplus.Config; -import de.thedevstack.conversationsplus.ConversationsPlusPreferences; -import de.thedevstack.conversationsplus.xmpp.chatstate.ChatState; -import de.thedevstack.conversationsplus.xmpp.jid.InvalidJidException; -import de.thedevstack.conversationsplus.xmpp.jid.Jid; - -public class Conversation extends AbstractEntity implements Blockable { - public static final String TABLENAME = "conversations"; - - public static final int STATUS_AVAILABLE = 0; - public static final int STATUS_ARCHIVED = 1; - public static final int STATUS_DELETED = 2; - - public static final int MODE_MULTI = 1; - public static final int MODE_SINGLE = 0; - - public static final String NAME = "name"; - public static final String ACCOUNT = "accountUuid"; - public static final String CONTACT = "contactUuid"; - public static final String CONTACTJID = "contactJid"; - public static final String STATUS = "status"; - public static final String CREATED = "created"; - public static final String MODE = "mode"; - public static final String ATTRIBUTES = "attributes"; - - public static final String ATTRIBUTE_NEXT_ENCRYPTION = "next_encryption"; - public static final String ATTRIBUTE_MUC_PASSWORD = "muc_password"; - public static final String ATTRIBUTE_MUTED_TILL = "muted_till"; - public static final String ATTRIBUTE_LAST_MESSAGE_TRANSMITTED = "last_message_transmitted"; - - private String name; - private String contactUuid; - private String accountUuid; - private Jid contactJid; - private int status; - private long created; - private int mode; - - private JSONObject attributes = new JSONObject(); - - private Jid nextCounterpart; - - protected final ArrayList<Message> messages = new ArrayList<>(); - protected Account account = null; - - private transient SessionImpl otrSession; - - private transient String otrFingerprint = null; - private Smp mSmp = new Smp(); - - private String nextMessage; - - private transient MucOptions mucOptions = null; - - private byte[] symmetricKey; - - private Bookmark bookmark; - - private boolean messagesLeftOnServer = true; - private ChatState mOutgoingChatState = Config.DEFAULT_CHATSTATE; - private ChatState mIncomingChatState = Config.DEFAULT_CHATSTATE; - private String mLastReceivedOtrMessageId = null; - - public boolean hasMessagesLeftOnServer() { - return messagesLeftOnServer; - } - - public void setHasMessagesLeftOnServer(boolean value) { - this.messagesLeftOnServer = value; - } - - public Message findUnsentMessageWithUuid(String uuid) { - synchronized(this.messages) { - for (final Message message : this.messages) { - final int s = message.getStatus(); - if ((s == Message.STATUS_UNSEND || s == Message.STATUS_WAITING) && message.getUuid().equals(uuid)) { - return message; - } - } - } - return null; - } - - public void findWaitingMessages(OnMessageFound onMessageFound) { - synchronized (this.messages) { - for(Message message : this.messages) { - if (message.getStatus() == Message.STATUS_WAITING) { - onMessageFound.onMessageFound(message); - } - } - } - } - - public void findMessagesWithFiles(final OnMessageFound onMessageFound) { - synchronized (this.messages) { - for (final Message message : this.messages) { - if ((message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) - && message.getEncryption() != Message.ENCRYPTION_PGP) { - onMessageFound.onMessageFound(message); - } - } - } - } - - public Message findMessageWithFileAndUuid(final String uuid) { - synchronized (this.messages) { - for (final Message message : this.messages) { - if ((message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE) - && message.getEncryption() != Message.ENCRYPTION_PGP - && message.getUuid().equals(uuid)) { - return message; - } - } - } - return null; - } - - public void clearMessages() { - synchronized (this.messages) { - this.messages.clear(); - } - } - - public boolean setIncomingChatState(ChatState state) { - if (this.mIncomingChatState == state) { - return false; - } - this.mIncomingChatState = state; - return true; - } - - public ChatState getIncomingChatState() { - return this.mIncomingChatState; - } - - public boolean setOutgoingChatState(ChatState state) { - if (mode == MODE_MULTI) { - return false; - } - if (this.mOutgoingChatState != state) { - this.mOutgoingChatState = state; - return true; - } else { - return false; - } - } - - public ChatState getOutgoingChatState() { - return this.mOutgoingChatState; - } - - public void trim() { - synchronized (this.messages) { - final int size = messages.size(); - final int maxsize = Config.PAGE_SIZE * Config.MAX_NUM_PAGES; - if (size > maxsize) { - this.messages.subList(0, size - maxsize).clear(); - } - } - } - - public void findUnsentMessagesWithOtrEncryption(OnMessageFound onMessageFound) { - synchronized (this.messages) { - for (Message message : this.messages) { - if ((message.getStatus() == Message.STATUS_UNSEND || message.getStatus() == Message.STATUS_WAITING) - && (message.getEncryption() == Message.ENCRYPTION_OTR)) { - onMessageFound.onMessageFound(message); - } - } - } - } - - public void findUnsentTextMessages(OnMessageFound onMessageFound) { - synchronized (this.messages) { - for (Message message : this.messages) { - if (message.getType() != Message.TYPE_IMAGE - && message.getStatus() == Message.STATUS_UNSEND) { - onMessageFound.onMessageFound(message); - } - } - } - } - - public Message findSentMessageWithUuid(String uuid) { - synchronized (this.messages) { - for (Message message : this.messages) { - if (uuid.equals(message.getUuid()) - || (message.getStatus() >= Message.STATUS_SEND && uuid - .equals(message.getRemoteMsgId()))) { - return message; - } - } - } - return null; - } - - public void populateWithMessages(final List<Message> messages) { - synchronized (this.messages) { - messages.clear(); - messages.addAll(this.messages); - } - for(Iterator<Message> iterator = messages.iterator(); iterator.hasNext();) { - if (iterator.next().wasMergedIntoPrevious()) { - iterator.remove(); - } - } - } - - @Override - public boolean isBlocked() { - return getContact().isBlocked(); - } - - @Override - public boolean isDomainBlocked() { - return getContact().isDomainBlocked(); - } - - @Override - public Jid getBlockedJid() { - return getContact().getBlockedJid(); - } - - public String getLastReceivedOtrMessageId() { - return this.mLastReceivedOtrMessageId; - } - - public void setLastReceivedOtrMessageId(String id) { - this.mLastReceivedOtrMessageId = id; - } - - public int countMessages() { - synchronized (this.messages) { - return this.messages.size(); - } - } - - - public interface OnMessageFound { - public void onMessageFound(final Message message); - } - - public Conversation(final String name, final Account account, final Jid contactJid, - final int mode) { - this(java.util.UUID.randomUUID().toString(), name, null, account - .getUuid(), contactJid, System.currentTimeMillis(), - STATUS_AVAILABLE, mode, ""); - this.account = account; - } - - public Conversation(final String uuid, final String name, final String contactUuid, - final String accountUuid, final Jid contactJid, final long created, final int status, - final int mode, final String attributes) { - this.uuid = uuid; - this.name = name; - this.contactUuid = contactUuid; - this.accountUuid = accountUuid; - this.contactJid = contactJid; - this.created = created; - this.status = status; - this.mode = mode; - try { - this.attributes = new JSONObject(attributes == null ? "" : attributes); - } catch (JSONException e) { - this.attributes = new JSONObject(); - } - } - - public boolean isRead() { - return (this.messages.size() == 0) || this.messages.get(this.messages.size() - 1).isRead(); - } - - public void markRead() { - for (int i = this.messages.size() - 1; i >= 0; --i) { - if (messages.get(i).isRead()) { - break; - } - this.messages.get(i).markRead(); - } - } - - public Message getLatestMarkableMessage() { - for (int i = this.messages.size() - 1; i >= 0; --i) { - if (this.messages.get(i).getStatus() <= Message.STATUS_RECEIVED - && this.messages.get(i).markable) { - if (this.messages.get(i).isRead()) { - return null; - } else { - return this.messages.get(i); - } - } - } - return null; - } - - public Message getLatestMessage() { - if (this.messages.size() == 0) { - Message message = new Message(this, "", Message.ENCRYPTION_NONE); - message.setTime(getCreated()); - return message; - } else { - Message message = this.messages.get(this.messages.size() - 1); - message.setConversation(this); - return message; - } - } - - public String getName() { - if (getMode() == MODE_MULTI) { - if (getMucOptions().getSubject() != null) { - return getMucOptions().getSubject(); - } else if (bookmark != null && bookmark.getName() != null) { - return bookmark.getName(); - } else { - String generatedName = getMucOptions().createNameFromParticipants(); - if (generatedName != null) { - return generatedName; - } else { - return getJid().getLocalpart(); - } - } - } else { - return this.getContact().getDisplayName(); - } - } - - public String getAccountUuid() { - return this.accountUuid; - } - - public Account getAccount() { - return this.account; - } - - public Contact getContact() { - return this.account.getRoster().getContact(this.contactJid); - } - - public void setAccount(final Account account) { - this.account = account; - } - - @Override - public Jid getJid() { - return this.contactJid; - } - - public int getStatus() { - return this.status; - } - - public long getCreated() { - return this.created; - } - - public ContentValues getContentValues() { - ContentValues values = new ContentValues(); - values.put(UUID, uuid); - values.put(NAME, name); - values.put(CONTACT, contactUuid); - values.put(ACCOUNT, accountUuid); - values.put(CONTACTJID, contactJid.toString()); - values.put(CREATED, created); - values.put(STATUS, status); - values.put(MODE, mode); - values.put(ATTRIBUTES, attributes.toString()); - return values; - } - - public static Conversation fromCursor(Cursor cursor) { - Jid jid; - try { - jid = Jid.fromString(cursor.getString(cursor.getColumnIndex(CONTACTJID)), true); - } catch (final InvalidJidException e) { - // Borked DB.. - jid = null; - } - return new Conversation(cursor.getString(cursor.getColumnIndex(UUID)), - cursor.getString(cursor.getColumnIndex(NAME)), - cursor.getString(cursor.getColumnIndex(CONTACT)), - cursor.getString(cursor.getColumnIndex(ACCOUNT)), - jid, - cursor.getLong(cursor.getColumnIndex(CREATED)), - cursor.getInt(cursor.getColumnIndex(STATUS)), - cursor.getInt(cursor.getColumnIndex(MODE)), - cursor.getString(cursor.getColumnIndex(ATTRIBUTES))); - } - - public void setStatus(int status) { - this.status = status; - } - - public int getMode() { - return this.mode; - } - - public void setMode(int mode) { - this.mode = mode; - } - - public SessionImpl startOtrSession(String presence, boolean sendStart) { - if (this.otrSession != null) { - return this.otrSession; - } else { - final SessionID sessionId = new SessionID(this.getJid().toBareJid().toString(), - presence, - "xmpp"); - this.otrSession = new SessionImpl(sessionId, getAccount().getOtrService()); - try { - if (sendStart) { - this.otrSession.startSession(); - return this.otrSession; - } - return this.otrSession; - } catch (OtrException e) { - return null; - } - } - - } - - public SessionImpl getOtrSession() { - return this.otrSession; - } - - public void resetOtrSession() { - this.otrFingerprint = null; - this.otrSession = null; - this.mSmp.hint = null; - this.mSmp.secret = null; - this.mSmp.status = Smp.STATUS_NONE; - } - - public Smp smp() { - return mSmp; - } - - public void startOtrIfNeeded() { - if (this.otrSession != null - && this.otrSession.getSessionStatus() != SessionStatus.ENCRYPTED) { - try { - this.otrSession.startSession(); - } catch (OtrException e) { - this.resetOtrSession(); - } - } - } - - public boolean endOtrIfNeeded() { - if (this.otrSession != null) { - if (this.otrSession.getSessionStatus() == SessionStatus.ENCRYPTED) { - try { - this.otrSession.endSession(); - this.resetOtrSession(); - return true; - } catch (OtrException e) { - this.resetOtrSession(); - return false; - } - } else { - this.resetOtrSession(); - return false; - } - } else { - return false; - } - } - - public boolean hasValidOtrSession() { - return this.otrSession != null; - } - - public synchronized String getOtrFingerprint() { - if (this.otrFingerprint == null) { - try { - if (getOtrSession() == null || getOtrSession().getSessionStatus() != SessionStatus.ENCRYPTED) { - return null; - } - DSAPublicKey remotePubKey = (DSAPublicKey) getOtrSession().getRemotePublicKey(); - this.otrFingerprint = getAccount().getOtrService().getFingerprint(remotePubKey); - } catch (final OtrCryptoException | UnsupportedOperationException ignored) { - return null; - } - } - return this.otrFingerprint; - } - - public boolean verifyOtrFingerprint() { - final String fingerprint = getOtrFingerprint(); - if (fingerprint != null) { - getContact().addOtrFingerprint(fingerprint); - return true; - } else { - return false; - } - } - - public boolean isOtrFingerprintVerified() { - return getContact().getOtrFingerprints().contains(getOtrFingerprint()); - } - - public synchronized MucOptions getMucOptions() { - if (this.mucOptions == null) { - this.mucOptions = new MucOptions(this); - } - return this.mucOptions; - } - - public void resetMucOptions() { - this.mucOptions = null; - } - - public void setContactJid(final Jid jid) { - this.contactJid = jid; - } - - public void setNextCounterpart(Jid jid) { - this.nextCounterpart = jid; - } - - public Jid getNextCounterpart() { - return this.nextCounterpart; - } - - public int getLatestEncryption() { - int latestEncryption = this.getLatestMessage().getEncryption(); - if ((latestEncryption == Message.ENCRYPTION_DECRYPTED) - || (latestEncryption == Message.ENCRYPTION_DECRYPTION_FAILED)) { - return Message.ENCRYPTION_PGP; - } else { - return latestEncryption; - } - } - - public int getNextEncryption(boolean force) { - int next = this.getIntAttribute(ATTRIBUTE_NEXT_ENCRYPTION, -1); - if (next == -1) { - int latest = this.getLatestEncryption(); - if (latest == Message.ENCRYPTION_NONE) { - if (force && getMode() == MODE_SINGLE) { - return Message.ENCRYPTION_OTR; - } else if (getContact().getPresences().size() == 1) { - if (getContact().getOtrFingerprints().size() >= 1) { - return Message.ENCRYPTION_OTR; - } else { - return latest; - } - } else { - return latest; - } - } else { - return latest; - } - } - if (next == Message.ENCRYPTION_NONE && force - && getMode() == MODE_SINGLE) { - return Message.ENCRYPTION_OTR; - } else { - return next; - } - } - - public void setNextEncryption(int encryption) { - this.setAttribute(ATTRIBUTE_NEXT_ENCRYPTION, String.valueOf(encryption)); - } - - public String getNextMessage() { - if (this.nextMessage == null) { - return ""; - } else { - return this.nextMessage; - } - } - - public boolean smpRequested() { - return smp().status == Smp.STATUS_CONTACT_REQUESTED; - } - - public void setNextMessage(String message) { - this.nextMessage = message; - } - - public void setSymmetricKey(byte[] key) { - this.symmetricKey = key; - } - - public byte[] getSymmetricKey() { - return this.symmetricKey; - } - - public void setBookmark(Bookmark bookmark) { - this.bookmark = bookmark; - this.bookmark.setConversation(this); - } - - public void deregisterWithBookmark() { - if (this.bookmark != null) { - this.bookmark.setConversation(null); - } - } - - public Bookmark getBookmark() { - return this.bookmark; - } - - public boolean hasDuplicateMessage(Message message) { - synchronized (this.messages) { - for (int i = this.messages.size() - 1; i >= 0; --i) { - if (this.messages.get(i).equals(message)) { - return true; - } - } - } - return false; - } - - public Message findSentMessageWithBody(String body) { - synchronized (this.messages) { - for (int i = this.messages.size() - 1; i >= 0; --i) { - Message message = this.messages.get(i); - if ((message.getStatus() == Message.STATUS_UNSEND || message.getStatus() == Message.STATUS_SEND) && message.getBody() != null && message.getBody().equals(body)) { - return message; - } - } - return null; - } - } - - public boolean setLastMessageTransmitted(long value) { - long before = getLastMessageTransmitted(); - if (value - before > 1000) { - this.setAttribute(ATTRIBUTE_LAST_MESSAGE_TRANSMITTED, String.valueOf(value)); - return true; - } else { - return false; - } - } - - public long getLastMessageTransmitted() { - long timestamp = getLongAttribute(ATTRIBUTE_LAST_MESSAGE_TRANSMITTED,0); - if (timestamp == 0) { - synchronized (this.messages) { - for(int i = this.messages.size() - 1; i >= 0; --i) { - Message message = this.messages.get(i); - if (message.getStatus() == Message.STATUS_RECEIVED) { - return message.getTimeSent(); - } - } - } - } - return timestamp; - } - - public void setMutedTill(long value) { - this.setAttribute(ATTRIBUTE_MUTED_TILL, String.valueOf(value)); - } - - public boolean isMuted() { - return System.currentTimeMillis() < this.getLongAttribute(ATTRIBUTE_MUTED_TILL, 0); - } - - public boolean setAttribute(String key, String value) { - try { - this.attributes.put(key, value); - return true; - } catch (JSONException e) { - return false; - } - } - - public String getAttribute(String key) { - try { - return this.attributes.getString(key); - } catch (JSONException e) { - return null; - } - } - - public int getIntAttribute(String key, int defaultValue) { - String value = this.getAttribute(key); - if (value == null) { - return defaultValue; - } else { - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - return defaultValue; - } - } - } - - public long getLongAttribute(String key, long defaultValue) { - String value = this.getAttribute(key); - if (value == null) { - return defaultValue; - } else { - try { - return Long.parseLong(value); - } catch (NumberFormatException e) { - return defaultValue; - } - } - } - - public void add(Message message) { - message.setConversation(this); - synchronized (this.messages) { - this.messages.add(message); - } - } - - public void addAll(int index, List<Message> messages) { - synchronized (this.messages) { - this.messages.addAll(index, messages); - } - } - - public void sort() { - synchronized (this.messages) { - Collections.sort(this.messages, new Comparator<Message>() { - @Override - public int compare(Message left, Message right) { - if (left.getTimeSent() < right.getTimeSent()) { - return -1; - } else if (left.getTimeSent() > right.getTimeSent()) { - return 1; - } else { - return 0; - } - } - }); - for(Message message : this.messages) { - message.untie(); - } - } - } - - public int unreadCount() { - synchronized (this.messages) { - int count = 0; - for(int i = this.messages.size() - 1; i >= 0; --i) { - Message message = this.messages.get(i); - if (message.isRead()) { - return count; - } - if (getMode() == Conversation.MODE_SINGLE - || ConversationsPlusPreferences.alwaysNotifyInConference() - || account.getXmppConnectionService().getNotificationService().wasHighlightedOrPrivate(message) - ) { - ++count; - } - } - return count; - } - } - - public class Smp { - public static final int STATUS_NONE = 0; - public static final int STATUS_CONTACT_REQUESTED = 1; - public static final int STATUS_WE_REQUESTED = 2; - public static final int STATUS_FAILED = 3; - public static final int STATUS_VERIFIED = 4; - - public String secret = null; - public String hint = null; - public int status = 0; - } -} diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/DownloadableFile.java b/src/main/java/de/thedevstack/conversationsplus/entities/DownloadableFile.java deleted file mode 100644 index 4031e546..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/entities/DownloadableFile.java +++ /dev/null @@ -1,168 +0,0 @@ -package de.thedevstack.conversationsplus.entities; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URLConnection; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.NoSuchAlgorithmException; - -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.CipherOutputStream; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; - -import de.thedevstack.android.logcat.Logging; -import de.thedevstack.conversationsplus.Config; -import de.thedevstack.conversationsplus.utils.MimeUtils; - -public class DownloadableFile extends File { - - private static final long serialVersionUID = 2247012619505115863L; - - private long expectedSize = 0; - private String sha1sum; - private Key aeskey; - private String mime; - - private byte[] iv = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xf }; - - public DownloadableFile(String path) { - super(path); - } - - public long getSize() { - return super.length(); - } - - public long getExpectedSize() { - if (this.aeskey != null) { - if (this.expectedSize == 0) { - return 0; - } else { - return (this.expectedSize / 16 + 1) * 16; - } - } else { - return this.expectedSize; - } - } - - public String getMimeType() { - String path = this.getAbsolutePath(); - int start = path.lastIndexOf('.') + 1; - if (start < path.length()) { - String mime = MimeUtils.guessMimeTypeFromExtension(path.substring(start)); - return mime == null ? "" : mime; - } else { - return ""; - } - } - - public void setExpectedSize(long size) { - this.expectedSize = size; - } - - public String getSha1Sum() { - return this.sha1sum; - } - - public void setSha1Sum(String sum) { - this.sha1sum = sum; - } - - public void setKey(byte[] key) { - if (key.length == 48) { - byte[] secretKey = new byte[32]; - byte[] iv = new byte[16]; - System.arraycopy(key, 0, iv, 0, 16); - System.arraycopy(key, 16, secretKey, 0, 32); - this.aeskey = new SecretKeySpec(secretKey, "AES"); - this.iv = iv; - } else if (key.length >= 32) { - byte[] secretKey = new byte[32]; - System.arraycopy(key, 0, secretKey, 0, 32); - this.aeskey = new SecretKeySpec(secretKey, "AES"); - } else if (key.length >= 16) { - byte[] secretKey = new byte[16]; - System.arraycopy(key, 0, secretKey, 0, 16); - this.aeskey = new SecretKeySpec(secretKey, "AES"); - } - } - - public Key getKey() { - return this.aeskey; - } - - public InputStream createInputStream() { - if (this.getKey() == null) { - try { - return new FileInputStream(this); - } catch (FileNotFoundException e) { - return null; - } - } else { - try { - IvParameterSpec ips = new IvParameterSpec(iv); - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - cipher.init(Cipher.ENCRYPT_MODE, this.getKey(), ips); - Logging.d(Config.LOGTAG, "opening encrypted input stream"); - return new CipherInputStream(new FileInputStream(this), cipher); - } catch (NoSuchAlgorithmException e) { - Logging.d(Config.LOGTAG, "no such algo: " + e.getMessage()); - return null; - } catch (NoSuchPaddingException e) { - Logging.d(Config.LOGTAG, "no such padding: " + e.getMessage()); - return null; - } catch (InvalidKeyException e) { - Logging.d(Config.LOGTAG, "invalid key: " + e.getMessage()); - return null; - } catch (InvalidAlgorithmParameterException e) { - Logging.d(Config.LOGTAG, "invavid iv:" + e.getMessage()); - return null; - } catch (FileNotFoundException e) { - return null; - } - } - } - - public OutputStream createOutputStream() { - if (this.getKey() == null) { - try { - return new FileOutputStream(this); - } catch (FileNotFoundException e) { - return null; - } - } else { - try { - IvParameterSpec ips = new IvParameterSpec(this.iv); - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - cipher.init(Cipher.DECRYPT_MODE, this.getKey(), ips); - Logging.d(Config.LOGTAG, "opening encrypted output stream"); - return new CipherOutputStream(new FileOutputStream(this), - cipher); - } catch (NoSuchAlgorithmException e) { - Logging.d(Config.LOGTAG, "no such algo: " + e.getMessage()); - return null; - } catch (NoSuchPaddingException e) { - Logging.d(Config.LOGTAG, "no such padding: " + e.getMessage()); - return null; - } catch (InvalidKeyException e) { - Logging.d(Config.LOGTAG, "invalid key: " + e.getMessage()); - return null; - } catch (InvalidAlgorithmParameterException e) { - Logging.d(Config.LOGTAG, "invavid iv:" + e.getMessage()); - return null; - } catch (FileNotFoundException e) { - return null; - } - } - } -} diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/ListItem.java b/src/main/java/de/thedevstack/conversationsplus/entities/ListItem.java deleted file mode 100644 index 9daf90d1..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/entities/ListItem.java +++ /dev/null @@ -1,35 +0,0 @@ -package de.thedevstack.conversationsplus.entities; - -import java.util.List; - -import de.thedevstack.conversationsplus.xmpp.jid.Jid; - -public interface ListItem extends Comparable<ListItem> { - public String getDisplayName(); - - public Jid getJid(); - - public List<Tag> getTags(); - - public int getStatusColor(); - - public final class Tag { - private final String name; - private final int color; - - public Tag(final String name, final int color) { - this.name = name; - this.color = color; - } - - public int getColor() { - return this.color; - } - - public String getName() { - return this.name; - } - } - - public boolean match(final String needle); -} diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Message.java b/src/main/java/de/thedevstack/conversationsplus/entities/Message.java deleted file mode 100644 index a5d06f46..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/entities/Message.java +++ /dev/null @@ -1,676 +0,0 @@ -package de.thedevstack.conversationsplus.entities; - -import android.content.ContentValues; -import android.database.Cursor; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Arrays; - -import de.thedevstack.conversationsplus.Config; -import de.thedevstack.conversationsplus.utils.GeoHelper; -import de.thedevstack.conversationsplus.utils.MimeUtils; -import de.thedevstack.conversationsplus.utils.UIHelper; -import de.thedevstack.conversationsplus.xmpp.jid.InvalidJidException; -import de.thedevstack.conversationsplus.xmpp.jid.Jid; - -public class Message extends AbstractEntity { - - public static final String TABLENAME = "messages"; - - public static final String MERGE_SEPARATOR = " \u200B\n\n"; - - public static final int STATUS_RECEIVED = 0; - public static final int STATUS_UNSEND = 1; - public static final int STATUS_SEND = 2; - public static final int STATUS_SEND_FAILED = 3; - public static final int STATUS_WAITING = 5; - public static final int STATUS_OFFERED = 6; - public static final int STATUS_SEND_RECEIVED = 7; - public static final int STATUS_SEND_DISPLAYED = 8; - - public static final int ENCRYPTION_NONE = 0; - public static final int ENCRYPTION_PGP = 1; - public static final int ENCRYPTION_OTR = 2; - public static final int ENCRYPTION_DECRYPTED = 3; - public static final int ENCRYPTION_DECRYPTION_FAILED = 4; - - public static final int TYPE_TEXT = 0; - public static final int TYPE_IMAGE = 1; - public static final int TYPE_FILE = 2; - public static final int TYPE_STATUS = 3; - public static final int TYPE_PRIVATE = 4; - - public static final String CONVERSATION = "conversationUuid"; - public static final String COUNTERPART = "counterpart"; - public static final String TRUE_COUNTERPART = "trueCounterpart"; - public static final String BODY = "body"; - public static final String TIME_SENT = "timeSent"; - public static final String ENCRYPTION = "encryption"; - public static final String STATUS = "status"; - public static final String TYPE = "type"; - public static final String REMOTE_MSG_ID = "remoteMsgId"; - public static final String SERVER_MSG_ID = "serverMsgId"; - public static final String RELATIVE_FILE_PATH = "relativeFilePath"; - public static final String ME_COMMAND = "/me "; - - - public boolean markable = false; - protected String conversationUuid; - protected Jid counterpart; - protected Jid trueCounterpart; - private String body; - protected String encryptedBody; - protected long timeSent; - protected int encryption; - protected int status; - protected int type; - protected String relativeFilePath; - protected boolean read = true; - protected String remoteMsgId = null; - protected String serverMsgId = null; - protected Conversation conversation = null; - protected Transferable transferable = null; - private Message mNextMessage = null; - private Message mPreviousMessage = null; - - private Message() { - - } - - public Message(Conversation conversation, String body, int encryption) { - this(conversation, body, encryption, STATUS_UNSEND); - } - - public Message(Conversation conversation, String body, int encryption, int status) { - this(java.util.UUID.randomUUID().toString(), - conversation.getUuid(), - conversation.getJid() == null ? null : conversation.getJid().toBareJid(), - null, - body, - System.currentTimeMillis(), - encryption, - status, - TYPE_TEXT, - null, - null, - null); - this.conversation = conversation; - } - - private Message(final String uuid, final String conversationUUid, final Jid counterpart, - final Jid trueCounterpart, final String body, final long timeSent, - final int encryption, final int status, final int type, final String remoteMsgId, - final String relativeFilePath, final String serverMsgId) { - this.uuid = uuid; - this.conversationUuid = conversationUUid; - this.counterpart = counterpart; - this.trueCounterpart = trueCounterpart; - this.body = body; - this.timeSent = timeSent; - this.encryption = encryption; - this.status = status; - this.type = type; - this.remoteMsgId = remoteMsgId; - this.relativeFilePath = relativeFilePath; - this.serverMsgId = serverMsgId; - } - - public static Message fromCursor(Cursor cursor) { - Jid jid; - try { - String value = cursor.getString(cursor.getColumnIndex(COUNTERPART)); - if (value != null) { - jid = Jid.fromString(value, true); - } else { - jid = null; - } - } catch (InvalidJidException e) { - jid = null; - } - Jid trueCounterpart; - try { - String value = cursor.getString(cursor.getColumnIndex(TRUE_COUNTERPART)); - if (value != null) { - trueCounterpart = Jid.fromString(value, true); - } else { - trueCounterpart = null; - } - } catch (InvalidJidException e) { - trueCounterpart = null; - } - return new Message(cursor.getString(cursor.getColumnIndex(UUID)), - cursor.getString(cursor.getColumnIndex(CONVERSATION)), - jid, - trueCounterpart, - cursor.getString(cursor.getColumnIndex(BODY)), - cursor.getLong(cursor.getColumnIndex(TIME_SENT)), - cursor.getInt(cursor.getColumnIndex(ENCRYPTION)), - cursor.getInt(cursor.getColumnIndex(STATUS)), - cursor.getInt(cursor.getColumnIndex(TYPE)), - cursor.getString(cursor.getColumnIndex(REMOTE_MSG_ID)), - cursor.getString(cursor.getColumnIndex(RELATIVE_FILE_PATH)), - cursor.getString(cursor.getColumnIndex(SERVER_MSG_ID))); - } - - public static Message createStatusMessage(Conversation conversation, String body) { - Message message = new Message(); - message.setType(Message.TYPE_STATUS); - message.setConversation(conversation); - message.setBody(body); - return message; - } - - @Override - public ContentValues getContentValues() { - ContentValues values = new ContentValues(); - values.put(UUID, uuid); - values.put(CONVERSATION, conversationUuid); - if (counterpart == null) { - values.putNull(COUNTERPART); - } else { - values.put(COUNTERPART, counterpart.toString()); - } - if (trueCounterpart == null) { - values.putNull(TRUE_COUNTERPART); - } else { - values.put(TRUE_COUNTERPART, trueCounterpart.toString()); - } - values.put(BODY, body); - values.put(TIME_SENT, timeSent); - values.put(ENCRYPTION, encryption); - values.put(STATUS, status); - values.put(TYPE, type); - values.put(REMOTE_MSG_ID, remoteMsgId); - values.put(RELATIVE_FILE_PATH, relativeFilePath); - values.put(SERVER_MSG_ID, serverMsgId); - return values; - } - - public String getConversationUuid() { - return conversationUuid; - } - - public Conversation getConversation() { - return this.conversation; - } - - public void setConversation(Conversation conv) { - this.conversation = conv; - } - - public Jid getCounterpart() { - return counterpart; - } - - public void setCounterpart(final Jid counterpart) { - this.counterpart = counterpart; - } - - public Contact getContact() { - if (this.conversation.getMode() == Conversation.MODE_SINGLE) { - return this.conversation.getContact(); - } else { - if (this.trueCounterpart == null) { - return null; - } else { - return this.conversation.getAccount().getRoster() - .getContactFromRoster(this.trueCounterpart); - } - } - } - - public String getBody() { - return body; - } - - public void setBody(String body) { - this.body = body; - } - - public long getTimeSent() { - return timeSent; - } - - public int getEncryption() { - return encryption; - } - - public void setEncryption(int encryption) { - this.encryption = encryption; - } - - public int getStatus() { - return status; - } - - public void setStatus(int status) { - this.status = status; - } - - public String getRelativeFilePath() { - return this.relativeFilePath; - } - - public void setRelativeFilePath(String path) { - this.relativeFilePath = path; - } - - public String getRemoteMsgId() { - return this.remoteMsgId; - } - - public void setRemoteMsgId(String id) { - this.remoteMsgId = id; - } - - public String getServerMsgId() { - return this.serverMsgId; - } - - public void setServerMsgId(String id) { - this.serverMsgId = id; - } - - public boolean isRead() { - return this.read; - } - - public void markRead() { - this.read = true; - } - - public void markUnread() { - this.read = false; - } - - public void setTime(long time) { - this.timeSent = time; - } - - public String getEncryptedBody() { - return this.encryptedBody; - } - - public void setEncryptedBody(String body) { - this.encryptedBody = body; - } - - public int getType() { - return this.type; - } - - public void setType(int type) { - this.type = type; - } - - public void setTrueCounterpart(Jid trueCounterpart) { - this.trueCounterpart = trueCounterpart; - } - - public Transferable getTransferable() { - return this.transferable; - } - - public void setTransferable(Transferable transferable) { - this.transferable = transferable; - } - - public boolean equals(Message message) { - if (this.serverMsgId != null && message.getServerMsgId() != null) { - return this.serverMsgId.equals(message.getServerMsgId()); - } else if (this.getBody() == null || this.counterpart == null) { - return false; - } else { - String body, otherBody; - if (this.hasFileOnRemoteHost()) { - body = getFileParams().url.toString(); - otherBody = message.getBody() == null ? null : message.getBody(); - } else { - body = this.getBody(); - otherBody = message.getBody(); - } - if (message.getRemoteMsgId() != null) { - return (message.getRemoteMsgId().equals(this.remoteMsgId) || message.getRemoteMsgId().equals(this.uuid)) - && this.counterpart.equals(message.getCounterpart()) - && body.equals(otherBody); - } else { - return this.remoteMsgId == null - && this.counterpart.equals(message.getCounterpart()) - && body.equals(otherBody) - && Math.abs(this.getTimeSent() - message.getTimeSent()) < Config.MESSAGE_MERGE_WINDOW * 1000; - } - } - } - - public Message next() { - synchronized (this.conversation.messages) { - if (this.mNextMessage == null) { - int index = this.conversation.messages.indexOf(this); - if (index < 0 || index >= this.conversation.messages.size() - 1) { - this.mNextMessage = null; - } else { - this.mNextMessage = this.conversation.messages.get(index + 1); - } - } - return this.mNextMessage; - } - } - - public Message prev() { - synchronized (this.conversation.messages) { - if (this.mPreviousMessage == null) { - int index = this.conversation.messages.indexOf(this); - if (index <= 0 || index > this.conversation.messages.size()) { - this.mPreviousMessage = null; - } else { - this.mPreviousMessage = this.conversation.messages.get(index - 1); - } - } - return this.mPreviousMessage; - } - } - - public boolean mergeable(final Message message) { - return message != null && - (message.getType() == Message.TYPE_TEXT && - this.getTransferable() == null && - message.getTransferable() == null && - message.getEncryption() != Message.ENCRYPTION_PGP && - this.getType() == message.getType() && - //this.getStatus() == message.getStatus() && - isStatusMergeable(this.getStatus(), message.getStatus()) && - this.getEncryption() == message.getEncryption() && - this.getCounterpart() != null && - this.getCounterpart().equals(message.getCounterpart()) && - (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && - !GeoHelper.isGeoUri(message.getBody()) && - !GeoHelper.isGeoUri(this.getBody()) && - message.treatAsDownloadable() == Decision.NEVER && - this.treatAsDownloadable() == Decision.NEVER && - !message.getBody().startsWith(ME_COMMAND) && - !this.getBody().startsWith(ME_COMMAND) - ); - } - - private static boolean isStatusMergeable(int a, int b) { - return a == b || ( - (a == Message.STATUS_SEND_RECEIVED && b == Message.STATUS_UNSEND) - || (a == Message.STATUS_SEND_RECEIVED && b == Message.STATUS_SEND) - || (a == Message.STATUS_UNSEND && b == Message.STATUS_SEND) - || (a == Message.STATUS_UNSEND && b == Message.STATUS_SEND_RECEIVED) - || (a == Message.STATUS_SEND && b == Message.STATUS_UNSEND) - || (a == Message.STATUS_SEND && b == Message.STATUS_SEND_RECEIVED) - ); - } - - public String getMergedBody() { - final Message next = this.next(); - if (this.mergeable(next)) { - return getBody() + MERGE_SEPARATOR + next.getMergedBody(); - } - return getBody(); - } - - public boolean hasMeCommand() { - return getMergedBody().startsWith(ME_COMMAND); - } - - public int getMergedStatus() { - final Message next = this.next(); - if (this.mergeable(next)) { - return next.getStatus(); - } - return getStatus(); - } - - public long getMergedTimeSent() { - Message next = this.next(); - if (this.mergeable(next)) { - return next.getMergedTimeSent(); - } else { - return getTimeSent(); - } - } - - public boolean wasMergedIntoPrevious() { - Message prev = this.prev(); - return prev != null && prev.mergeable(this); - } - - public boolean trusted() { - Contact contact = this.getContact(); - return (status > STATUS_RECEIVED || (contact != null && contact.trusted())); - } - - public boolean fixCounterpart() { - Presences presences = conversation.getContact().getPresences(); - if (counterpart != null && presences.has(counterpart.getResourcepart())) { - return true; - } else if (presences.size() >= 1) { - try { - counterpart = Jid.fromParts(conversation.getJid().getLocalpart(), - conversation.getJid().getDomainpart(), - presences.asStringArray()[0]); - return true; - } catch (InvalidJidException e) { - counterpart = null; - return false; - } - } else { - counterpart = null; - return false; - } - } - - public enum Decision { - MUST, - SHOULD, - NEVER, - } - - private static String extractRelevantExtension(URL url) { - String path = url.getPath(); - return extractRelevantExtension(path); - } - - private static String extractRelevantExtension(String path) { - if (path == null || path.isEmpty()) { - return null; - } - - String filename = path.substring(path.lastIndexOf('/') + 1).toLowerCase(); - - int dotPosition = filename.lastIndexOf("."); - - if (dotPosition != -1) - { - String extension = filename.substring(dotPosition + 1); - - // we want the real file extension, not the crypto one - if (Arrays.asList(Transferable.VALID_CRYPTO_EXTENSIONS).contains(extension)) { - return extractRelevantExtension(path.substring(0,dotPosition)); - } else { - return extension; - } - } - return null; - } - - public String getMimeType() { - if (relativeFilePath != null) { - int start = relativeFilePath.lastIndexOf('.') + 1; - if (start < relativeFilePath.length()) { - return MimeUtils.guessMimeTypeFromExtension(relativeFilePath.substring(start)); - } else { - return null; - } - } else { - try { - return MimeUtils.guessMimeTypeFromExtension(extractRelevantExtension(new URL(this.getBody()))); - } catch (MalformedURLException e) { - return null; - } - } - } - - public Decision treatAsDownloadable() { - /** - * there are a few cases where spaces result in an unwanted behavior, e.g. - * "http://example.com/image.jpg" text that will not be shown /abc.png" - * or more than one image link in one message. - */ - if (getBody().contains(" ")) { - return Decision.NEVER; - } - try { - URL url = new URL(body); - if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { - return Decision.NEVER; - } - String extension = extractRelevantExtension(url); - if (extension == null) { - return Decision.NEVER; - } - String ref = url.getRef(); - boolean encrypted = ref != null && ref.matches("([A-Fa-f0-9]{2}){48}"); - - if (encrypted) { - if (MimeUtils.guessMimeTypeFromExtension(extension) != null) { - return Decision.MUST; - } else { - return Decision.NEVER; - } - } else if (Arrays.asList(Transferable.VALID_IMAGE_EXTENSIONS).contains(extension) - || Arrays.asList(Transferable.WELL_KNOWN_EXTENSIONS).contains(extension)) { - return Decision.SHOULD; - } else { - return Decision.NEVER; - } - - } catch (MalformedURLException e) { - return Decision.NEVER; - } - } - - public FileParams getFileParams() { - FileParams params = getLegacyFileParams(); - if (params != null) { - return params; - } - params = new FileParams(); - if (this.transferable != null) { - params.size = this.transferable.getFileSize(); - } - if (this.getBody() == null) { - return params; - } - String parts[] = this.getBody().split("\\|"); - switch (parts.length) { - case 1: - try { - params.size = Long.parseLong(parts[0]); - } catch (NumberFormatException e) { - try { - params.url = new URL(parts[0]); - } catch (MalformedURLException e1) { - params.url = null; - } - } - break; - case 2: - case 4: - try { - params.url = new URL(parts[0]); - } catch (MalformedURLException e1) { - params.url = null; - } - try { - params.size = Long.parseLong(parts[1]); - } catch (NumberFormatException e) { - params.size = 0; - } - try { - params.width = Integer.parseInt(parts[2]); - } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) { - params.width = 0; - } - try { - params.height = Integer.parseInt(parts[3]); - } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) { - params.height = 0; - } - break; - case 3: - try { - params.size = Long.parseLong(parts[0]); - } catch (NumberFormatException e) { - params.size = 0; - } - try { - params.width = Integer.parseInt(parts[1]); - } catch (NumberFormatException e) { - params.width = 0; - } - try { - params.height = Integer.parseInt(parts[2]); - } catch (NumberFormatException e) { - params.height = 0; - } - break; - } - return params; - } - - public FileParams getLegacyFileParams() { - FileParams params = new FileParams(); - if (this.getBody() == null) { - return params; - } - String parts[] = this.getBody().split(","); - if (parts.length == 3) { - try { - params.size = Long.parseLong(parts[0]); - } catch (NumberFormatException e) { - return null; - } - try { - params.width = Integer.parseInt(parts[1]); - } catch (NumberFormatException e) { - return null; - } - try { - params.height = Integer.parseInt(parts[2]); - } catch (NumberFormatException e) { - return null; - } - return params; - } else { - return null; - } - } - - public void untie() { - this.mNextMessage = null; - this.mPreviousMessage = null; - } - - public boolean isFileOrImage() { - return type == TYPE_FILE || type == TYPE_IMAGE; - } - - public boolean hasFileOnRemoteHost() { - return isFileOrImage() && getFileParams().url != null; - } - - public boolean needsUploading() { - return isFileOrImage() && getFileParams().url == null; - } - - public class FileParams { - public URL url; - public long size = 0; - public int width = 0; - public int height = 0; - } -} diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/MucOptions.java b/src/main/java/de/thedevstack/conversationsplus/entities/MucOptions.java deleted file mode 100644 index 22155f3e..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/entities/MucOptions.java +++ /dev/null @@ -1,528 +0,0 @@ -package de.thedevstack.conversationsplus.entities; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import de.thedevstack.conversationsplus.R; -import de.thedevstack.conversationsplus.crypto.PgpEngine; -import de.thedevstack.conversationsplus.xml.Element; -import de.thedevstack.conversationsplus.xmpp.jid.InvalidJidException; -import de.thedevstack.conversationsplus.xmpp.jid.Jid; -import de.thedevstack.conversationsplus.xmpp.stanzas.PresencePacket; - -import android.annotation.SuppressLint; - -@SuppressLint("DefaultLocale") -public class MucOptions { - - public enum Affiliation { - OWNER("owner", 4, R.string.owner), - ADMIN("admin", 3, R.string.admin), - MEMBER("member", 2, R.string.member), - OUTCAST("outcast", 0, R.string.outcast), - NONE("none", 1, R.string.no_affiliation); - - private Affiliation(String string, int rank, int resId) { - this.string = string; - this.resId = resId; - this.rank = rank; - } - - private String string; - private int resId; - private int rank; - - public int getResId() { - return resId; - } - - @Override - public String toString() { - return this.string; - } - - public boolean outranks(Affiliation affiliation) { - return rank > affiliation.rank; - } - - public boolean ranks(Affiliation affiliation) { - return rank >= affiliation.rank; - } - } - - public enum Role { - MODERATOR("moderator", R.string.moderator), - VISITOR("visitor", R.string.visitor), - PARTICIPANT("participant", R.string.participant), - NONE("none", R.string.no_role); - - private Role(String string, int resId) { - this.string = string; - this.resId = resId; - } - - private String string; - private int resId; - - public int getResId() { - return resId; - } - - @Override - public String toString() { - return this.string; - } - } - - public static final int ERROR_NO_ERROR = 0; - public static final int ERROR_NICK_IN_USE = 1; - public static final int ERROR_UNKNOWN = 2; - public static final int ERROR_PASSWORD_REQUIRED = 3; - public static final int ERROR_BANNED = 4; - public static final int ERROR_MEMBERS_ONLY = 5; - - public static final int KICKED_FROM_ROOM = 9; - - public static final String STATUS_CODE_ROOM_CONFIG_CHANGED = "104"; - public static final String STATUS_CODE_SELF_PRESENCE = "110"; - public static final String STATUS_CODE_BANNED = "301"; - public static final String STATUS_CODE_CHANGED_NICK = "303"; - public static final String STATUS_CODE_KICKED = "307"; - public static final String STATUS_CODE_LOST_MEMBERSHIP = "321"; - - private interface OnEventListener { - public void onSuccess(); - - public void onFailure(); - } - - public interface OnRenameListener extends OnEventListener { - - } - - public interface OnJoinListener extends OnEventListener { - - } - - public class User { - private Role role = Role.NONE; - private Affiliation affiliation = Affiliation.NONE; - private String name; - private Jid jid; - private long pgpKeyId = 0; - - public String getName() { - return name; - } - - public void setName(String user) { - this.name = user; - } - - public void setJid(Jid jid) { - this.jid = jid; - } - - public Jid getJid() { - return this.jid; - } - - public Role getRole() { - return this.role; - } - - public void setRole(String role) { - role = role.toLowerCase(); - switch (role) { - case "moderator": - this.role = Role.MODERATOR; - break; - case "participant": - this.role = Role.PARTICIPANT; - break; - case "visitor": - this.role = Role.VISITOR; - break; - default: - this.role = Role.NONE; - break; - } - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } else if (!(other instanceof User)) { - return false; - } else { - User o = (User) other; - return name != null && name.equals(o.name) - && jid != null && jid.equals(o.jid) - && affiliation == o.affiliation - && role == o.role; - } - } - - public Affiliation getAffiliation() { - return this.affiliation; - } - - public void setAffiliation(String affiliation) { - affiliation = affiliation.toLowerCase(); - switch (affiliation) { - case "admin": - this.affiliation = Affiliation.ADMIN; - break; - case "owner": - this.affiliation = Affiliation.OWNER; - break; - case "member": - this.affiliation = Affiliation.MEMBER; - break; - case "outcast": - this.affiliation = Affiliation.OUTCAST; - break; - default: - this.affiliation = Affiliation.NONE; - } - } - - public void setPgpKeyId(long id) { - this.pgpKeyId = id; - } - - public long getPgpKeyId() { - return this.pgpKeyId; - } - - public Contact getContact() { - return account.getRoster().getContactFromRoster(getJid()); - } - } - - private Account account; - private List<User> users = new CopyOnWriteArrayList<>(); - private List<String> features = new ArrayList<>(); - private Conversation conversation; - private boolean isOnline = false; - private int error = ERROR_UNKNOWN; - private OnRenameListener onRenameListener = null; - private OnJoinListener onJoinListener = null; - private User self = new User(); - private String subject = null; - private String password = null; - private boolean mNickChangingInProgress = false; - - public MucOptions(Conversation conversation) { - this.account = conversation.getAccount(); - this.conversation = conversation; - } - - public void updateFeatures(ArrayList<String> features) { - this.features.clear(); - this.features.addAll(features); - } - - public boolean hasFeature(String feature) { - return this.features.contains(feature); - } - - public boolean canInvite() { - return !membersOnly() || self.getAffiliation().ranks(Affiliation.ADMIN); - } - - public boolean membersOnly() { - return hasFeature("muc_membersonly"); - } - - public boolean nonanonymous() { - return hasFeature("muc_nonanonymous"); - } - - public boolean persistent() { - return hasFeature("muc_persistent"); - } - - public void deleteUser(String name) { - for (int i = 0; i < users.size(); ++i) { - if (users.get(i).getName().equals(name)) { - users.remove(i); - return; - } - } - } - - public void addUser(User user) { - for (int i = 0; i < users.size(); ++i) { - if (users.get(i).getName().equals(user.getName())) { - users.set(i, user); - return; - } - } - users.add(user); - } - - public void processPacket(PresencePacket packet, PgpEngine pgp) { - final Jid from = packet.getFrom(); - if (!from.isBareJid()) { - final String name = from.getResourcepart(); - final String type = packet.getAttribute("type"); - final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user"); - final List<String> codes = getStatusCodes(x); - if (type == null) { - User user = new User(); - if (x != null) { - Element item = x.findChild("item"); - if (item != null && name != null) { - user.setName(name); - user.setAffiliation(item.getAttribute("affiliation")); - user.setRole(item.getAttribute("role")); - user.setJid(item.getAttributeAsJid("jid")); - if (codes.contains(STATUS_CODE_SELF_PRESENCE) || packet.getFrom().equals(this.conversation.getJid())) { - this.isOnline = true; - this.error = ERROR_NO_ERROR; - self = user; - if (mNickChangingInProgress) { - onRenameListener.onSuccess(); - mNickChangingInProgress = false; - } else if (this.onJoinListener != null) { - this.onJoinListener.onSuccess(); - this.onJoinListener = null; - } - } else { - addUser(user); - } - if (pgp != null) { - Element signed = packet.findChild("x", "jabber:x:signed"); - if (signed != null) { - Element status = packet.findChild("status"); - String msg; - if (status != null) { - msg = status.getContent(); - } else { - msg = ""; - } - user.setPgpKeyId(pgp.fetchKeyId(account, msg, - signed.getContent())); - } - } - } - } - } else if (type.equals("unavailable")) { - if (codes.contains(STATUS_CODE_SELF_PRESENCE) || - packet.getFrom().equals(this.conversation.getJid())) { - if (codes.contains(STATUS_CODE_CHANGED_NICK)) { - this.mNickChangingInProgress = true; - } else if (codes.contains(STATUS_CODE_KICKED)) { - setError(KICKED_FROM_ROOM); - } else if (codes.contains(STATUS_CODE_BANNED)) { - setError(ERROR_BANNED); - } else if (codes.contains(STATUS_CODE_LOST_MEMBERSHIP)) { - setError(ERROR_MEMBERS_ONLY); - } else { - setError(ERROR_UNKNOWN); - } - } else { - deleteUser(name); - } - } else if (type.equals("error")) { - Element error = packet.findChild("error"); - if (error != null && error.hasChild("conflict")) { - if (isOnline) { - if (onRenameListener != null) { - onRenameListener.onFailure(); - } - } else { - setError(ERROR_NICK_IN_USE); - } - } else if (error != null && error.hasChild("not-authorized")) { - setError(ERROR_PASSWORD_REQUIRED); - } else if (error != null && error.hasChild("forbidden")) { - setError(ERROR_BANNED); - } else if (error != null && error.hasChild("registration-required")) { - setError(ERROR_MEMBERS_ONLY); - } - } - } - } - - private void setError(int error) { - this.isOnline = false; - this.error = error; - if (onJoinListener != null) { - onJoinListener.onFailure(); - onJoinListener = null; - } - } - - private List<String> getStatusCodes(Element x) { - List<String> codes = new ArrayList<>(); - if (x != null) { - for (Element child : x.getChildren()) { - if (child.getName().equals("status")) { - String code = child.getAttribute("code"); - if (code != null) { - codes.add(code); - } - } - } - } - return codes; - } - - public List<User> getUsers() { - return this.users; - } - - public String getProposedNick() { - if (conversation.getBookmark() != null - && conversation.getBookmark().getNick() != null - && !conversation.getBookmark().getNick().isEmpty()) { - return conversation.getBookmark().getNick(); - } else if (!conversation.getJid().isBareJid()) { - return conversation.getJid().getResourcepart(); - } else { - return account.getUsername(); - } - } - - public String getActualNick() { - if (this.self.getName() != null) { - return this.self.getName(); - } else { - return this.getProposedNick(); - } - } - - public boolean online() { - return this.isOnline; - } - - public int getError() { - return this.error; - } - - public void setOnRenameListener(OnRenameListener listener) { - this.onRenameListener = listener; - } - - public void setOnJoinListener(OnJoinListener listener) { - this.onJoinListener = listener; - } - - public void setOffline() { - this.users.clear(); - this.error = 0; - this.isOnline = false; - } - - public User getSelf() { - return self; - } - - public void setSubject(String content) { - this.subject = content; - } - - public String getSubject() { - return this.subject; - } - - public String createNameFromParticipants() { - if (users.size() >= 2) { - List<String> names = new ArrayList<String>(); - for (User user : users) { - Contact contact = user.getContact(); - if (contact != null && !contact.getDisplayName().isEmpty()) { - names.add(contact.getDisplayName().split("\\s+")[0]); - } else { - names.add(user.getName()); - } - } - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < names.size(); ++i) { - builder.append(names.get(i)); - if (i != names.size() - 1) { - builder.append(", "); - } - } - return builder.toString(); - } else { - return null; - } - } - - public long[] getPgpKeyIds() { - List<Long> ids = new ArrayList<>(); - for (User user : getUsers()) { - if (user.getPgpKeyId() != 0) { - ids.add(user.getPgpKeyId()); - } - } - long[] primitivLongArray = new long[ids.size()]; - for (int i = 0; i < ids.size(); ++i) { - primitivLongArray[i] = ids.get(i); - } - return primitivLongArray; - } - - public boolean pgpKeysInUse() { - for (User user : getUsers()) { - if (user.getPgpKeyId() != 0) { - return true; - } - } - return false; - } - - public boolean everybodyHasKeys() { - for (User user : getUsers()) { - if (user.getPgpKeyId() == 0) { - return false; - } - } - return true; - } - - public Jid createJoinJid(String nick) { - try { - return Jid.fromString(this.conversation.getJid().toBareJid().toString() + "/" + nick); - } catch (final InvalidJidException e) { - return null; - } - } - - public Jid getTrueCounterpart(String counterpart) { - for (User user : this.getUsers()) { - if (user.getName().equals(counterpart)) { - return user.getJid(); - } - } - return null; - } - - public String getPassword() { - this.password = conversation.getAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD); - if (this.password == null && conversation.getBookmark() != null - && conversation.getBookmark().getPassword() != null) { - return conversation.getBookmark().getPassword(); - } else { - return this.password; - } - } - - public void setPassword(String password) { - if (conversation.getBookmark() != null) { - conversation.getBookmark().setPassword(password); - } else { - this.password = password; - } - conversation.setAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD, password); - } - - public Conversation getConversation() { - return this.conversation; - } -} diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Presences.java b/src/main/java/de/thedevstack/conversationsplus/entities/Presences.java deleted file mode 100644 index cb984648..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/entities/Presences.java +++ /dev/null @@ -1,90 +0,0 @@ -package de.thedevstack.conversationsplus.entities; - -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map.Entry; - -import de.thedevstack.conversationsplus.xml.Element; - -public class Presences { - - public static final int CHAT = -1; - public static final int ONLINE = 0; - public static final int AWAY = 1; - public static final int XA = 2; - public static final int DND = 3; - public static final int OFFLINE = 4; - - private Hashtable<String, Integer> presences = new Hashtable<String, Integer>(); - - public Hashtable<String, Integer> getPresences() { - return this.presences; - } - - public void updatePresence(String resource, int status) { - synchronized (this.presences) { - this.presences.put(resource, status); - } - } - - public void removePresence(String resource) { - synchronized (this.presences) { - this.presences.remove(resource); - } - } - - public void clearPresences() { - synchronized (this.presences) { - this.presences.clear(); - } - } - - public int getMostAvailableStatus() { - int status = OFFLINE; - synchronized (this.presences) { - Iterator<Entry<String, Integer>> it = presences.entrySet().iterator(); - while (it.hasNext()) { - Entry<String, Integer> entry = it.next(); - if (entry.getValue() < status) - status = entry.getValue(); - } - } - return status; - } - - public static int parseShow(Element show) { - if ((show == null) || (show.getContent() == null)) { - return Presences.ONLINE; - } else if (show.getContent().equals("away")) { - return Presences.AWAY; - } else if (show.getContent().equals("xa")) { - return Presences.XA; - } else if (show.getContent().equals("chat")) { - return Presences.CHAT; - } else if (show.getContent().equals("dnd")) { - return Presences.DND; - } else { - return Presences.OFFLINE; - } - } - - public int size() { - synchronized (this.presences) { - return presences.size(); - } - } - - public String[] asStringArray() { - synchronized (this.presences) { - final String[] presencesArray = new String[presences.size()]; - presences.keySet().toArray(presencesArray); - return presencesArray; - } - } - - public boolean has(String presence) { - synchronized (this.presences) { - return presences.containsKey(presence); - } - } -} diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Roster.java b/src/main/java/de/thedevstack/conversationsplus/entities/Roster.java deleted file mode 100644 index b1cb78b4..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/entities/Roster.java +++ /dev/null @@ -1,98 +0,0 @@ -package de.thedevstack.conversationsplus.entities; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; - -import de.thedevstack.conversationsplus.xmpp.jid.Jid; - -public class Roster { - final Account account; - final HashMap<String, Contact> contacts = new HashMap<>(); - private String version = null; - - public Roster(Account account) { - this.account = account; - } - - public Contact getContactFromRoster(Jid jid) { - if (jid == null) { - return null; - } - synchronized (this.contacts) { - Contact contact = contacts.get(jid.toBareJid().toString()); - if (contact != null && contact.showInRoster()) { - return contact; - } else { - return null; - } - } - } - - public Contact getContact(final Jid jid) { - synchronized (this.contacts) { - final Jid bareJid = jid.toBareJid(); - if (contacts.containsKey(bareJid.toString())) { - return contacts.get(bareJid.toString()); - } else { - Contact contact = new Contact(bareJid); - contact.setAccount(account); - contacts.put(bareJid.toString(), contact); - return contact; - } - } - } - - public void clearPresences() { - for (Contact contact : getContacts()) { - contact.clearPresences(); - } - } - - public void markAllAsNotInRoster() { - for (Contact contact : getContacts()) { - contact.resetOption(Contact.Options.IN_ROSTER); - } - } - - public List<Contact> getWithSystemAccounts() { - List<Contact> with = getContacts(); - for(Iterator<Contact> iterator = with.iterator(); iterator.hasNext();) { - Contact contact = iterator.next(); - if (contact.getSystemAccount() == null) { - iterator.remove(); - } - } - return with; - } - - public List<Contact> getContacts() { - synchronized (this.contacts) { - return new ArrayList<>(this.contacts.values()); - } - } - - public void initContact(final Contact contact) { - if (contact == null) { - return; - } - contact.setAccount(account); - contact.setOption(Contact.Options.IN_ROSTER); - synchronized (this.contacts) { - contacts.put(contact.getJid().toBareJid().toString(), contact); - } - } - - public void setVersion(String version) { - this.version = version; - } - - public String getVersion() { - return this.version; - } - - public Account getAccount() { - return this.account; - } -} diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/Transferable.java b/src/main/java/de/thedevstack/conversationsplus/entities/Transferable.java deleted file mode 100644 index a5bdb5d7..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/entities/Transferable.java +++ /dev/null @@ -1,28 +0,0 @@ -package de.thedevstack.conversationsplus.entities; - -public interface Transferable { - - String[] VALID_IMAGE_EXTENSIONS = {"webp", "jpeg", "jpg", "png", "jpe"}; - String[] VALID_CRYPTO_EXTENSIONS = {"pgp", "gpg", "otr"}; - String[] WELL_KNOWN_EXTENSIONS = {"pdf","m4a"}; - - int STATUS_UNKNOWN = 0x200; - int STATUS_CHECKING = 0x201; - int STATUS_FAILED = 0x202; - int STATUS_OFFER = 0x203; - int STATUS_DOWNLOADING = 0x204; - int STATUS_DELETED = 0x205; - int STATUS_OFFER_CHECK_FILESIZE = 0x206; - int STATUS_UPLOADING = 0x207; - - - boolean start(); - - int getStatus(); - - long getFileSize(); - - int getProgress(); - - void cancel(); -} diff --git a/src/main/java/de/thedevstack/conversationsplus/entities/TransferablePlaceholder.java b/src/main/java/de/thedevstack/conversationsplus/entities/TransferablePlaceholder.java deleted file mode 100644 index c51320d1..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/entities/TransferablePlaceholder.java +++ /dev/null @@ -1,34 +0,0 @@ -package de.thedevstack.conversationsplus.entities; - -public class TransferablePlaceholder implements Transferable { - - private int status; - - public TransferablePlaceholder(int status) { - this.status = status; - } - @Override - public boolean start() { - return false; - } - - @Override - public int getStatus() { - return status; - } - - @Override - public long getFileSize() { - return 0; - } - - @Override - public int getProgress() { - return 0; - } - - @Override - public void cancel() { - - } -} |