Merge pull request #639 from SamWhited/issue631

Use JID class instead of strings
This commit is contained in:
Daniel Gultsch 2014-11-09 15:20:06 +01:00
commit f65a2188cc
51 changed files with 1152 additions and 782 deletions

View file

@ -20,11 +20,14 @@ allprojects {
apply plugin: 'com.android.application'
repositories {
jcenter()
mavenCentral()
maven {
url "http://jitsi.github.com/otr4j/repository/"
}
maven {
url "https://oss.sonatype.org/content/repositories/releases/"
}
jcenter()
mavenCentral()
}
dependencies {
@ -34,6 +37,7 @@ dependencies {
compile 'com.android.support:support-v13:19.1.0'
compile 'org.bouncycastle:bcprov-jdk15on:1.50'
compile 'net.java:otr4j:0.21'
compile 'org.jxmpp:jxmpp-stringprep-libidn:0.4.0'
compile 'com.google.zxing:core:3.1.0'
compile 'com.google.zxing:android-integration:3.1.0'
}

View file

@ -85,13 +85,11 @@ public class OtrEngine implements OtrEngineHost {
this.account.setKey("otr_p", privateKeySpec.getP().toString(16));
this.account.setKey("otr_q", privateKeySpec.getQ().toString(16));
this.account.setKey("otr_y", publicKeySpec.getY().toString(16));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
} catch (final NoSuchAlgorithmException | InvalidKeySpecException e) {
e.printStackTrace();
}
}
}
@Override
public void askForSecret(SessionID arg0, InstanceTag arg1, String arg2) {
@ -157,9 +155,9 @@ public class OtrEngine implements OtrEngineHost {
MessagePacket packet = new MessagePacket();
packet.setFrom(account.getFullJid());
if (session.getUserID().isEmpty()) {
packet.setTo(session.getAccountID());
packet.setAttribute("to", session.getAccountID());
} else {
packet.setTo(session.getAccountID() + "/" + session.getUserID());
packet.setAttribute("to", session.getAccountID() + "/" + session.getUserID());
}
packet.setBody(body);
packet.addChild("private", "urn:xmpp:carbons:2");

View file

@ -41,7 +41,7 @@ public class PgpEngine {
Intent params = new Intent();
params.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY);
params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, message
.getConversation().getAccount().getJid());
.getConversation().getAccount().getJid().toString());
if (message.getType() == Message.TYPE_TEXT) {
InputStream is = new ByteArrayInputStream(message.getBody()
.getBytes());
@ -77,10 +77,7 @@ public class PgpEngine {
return;
case OpenPgpApi.RESULT_CODE_ERROR:
callback.error(R.string.openpgp_error, message);
return;
default:
return;
}
}
}
});
} else if (message.getType() == Message.TYPE_IMAGE) {
@ -135,15 +132,10 @@ public class PgpEngine {
return;
case OpenPgpApi.RESULT_CODE_ERROR:
callback.error(R.string.openpgp_error, message);
return;
default:
return;
}
}
});
} catch (FileNotFoundException e) {
callback.error(R.string.error_decrypting_file, message);
} catch (IOException e) {
} catch (final IOException e) {
callback.error(R.string.error_decrypting_file, message);
}
@ -164,7 +156,7 @@ public class PgpEngine {
.getMucOptions().getPgpKeyIds());
}
params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, message
.getConversation().getAccount().getJid());
.getConversation().getAccount().getJid().toString());
if (message.getType() == Message.TYPE_TEXT) {
params.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
@ -237,12 +229,8 @@ public class PgpEngine {
}
}
});
} catch (FileNotFoundException e) {
} catch (final IOException e) {
callback.error(R.string.openpgp_error, message);
return;
} catch (IOException e) {
callback.error(R.string.openpgp_error, message);
return;
}
}
}
@ -254,7 +242,7 @@ public class PgpEngine {
if (status == null) {
status = "";
}
StringBuilder pgpSig = new StringBuilder();
final StringBuilder pgpSig = new StringBuilder();
pgpSig.append("-----BEGIN PGP SIGNED MESSAGE-----");
pgpSig.append('\n');
pgpSig.append('\n');
@ -269,7 +257,7 @@ public class PgpEngine {
Intent params = new Intent();
params.setAction(OpenPgpApi.ACTION_DECRYPT_VERIFY);
params.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, account.getJid());
params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, account.getJid().toString());
InputStream is = new ByteArrayInputStream(pgpSig.toString().getBytes());
ByteArrayOutputStream os = new ByteArrayOutputStream();
Intent result = api.executeApi(params, is, os);
@ -296,7 +284,7 @@ public class PgpEngine {
Intent params = new Intent();
params.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
params.setAction(OpenPgpApi.ACTION_SIGN);
params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, account.getJid());
params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, account.getJid().toString());
InputStream is = new ByteArrayInputStream(status.getBytes());
final OutputStream os = new ByteArrayOutputStream();
api.executeApiAsync(params, is, os, new IOpenPgpCallback() {
@ -338,8 +326,7 @@ public class PgpEngine {
return;
case OpenPgpApi.RESULT_CODE_ERROR:
callback.error(R.string.openpgp_error, account);
return;
}
}
}
});
}
@ -349,7 +336,7 @@ public class PgpEngine {
params.setAction(OpenPgpApi.ACTION_GET_KEY);
params.putExtra(OpenPgpApi.EXTRA_KEY_ID, contact.getPgpKeyId());
params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, contact.getAccount()
.getJid());
.getJid().toString());
api.executeApiAsync(params, null, null, new IOpenPgpCallback() {
@Override
@ -365,8 +352,7 @@ public class PgpEngine {
return;
case OpenPgpApi.RESULT_CODE_ERROR:
callback.error(R.string.openpgp_error, contact);
return;
}
}
}
});
}
@ -376,7 +362,7 @@ public class PgpEngine {
params.setAction(OpenPgpApi.ACTION_GET_KEY);
params.putExtra(OpenPgpApi.EXTRA_KEY_ID, contact.getPgpKeyId());
params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, contact.getAccount()
.getJid());
.getJid().toString());
Intent result = api.executeApi(params, null, null);
return (PendingIntent) result
.getParcelableExtra(OpenPgpApi.RESULT_INTENT);
@ -386,7 +372,7 @@ public class PgpEngine {
Intent params = new Intent();
params.setAction(OpenPgpApi.ACTION_GET_KEY);
params.putExtra(OpenPgpApi.EXTRA_KEY_ID, pgpKeyId);
params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, account.getJid());
params.putExtra(OpenPgpApi.EXTRA_ACCOUNT_NAME, account.getJid().toString());
Intent result = api.executeApi(params, null, null);
return (PendingIntent) result
.getParcelableExtra(OpenPgpApi.RESULT_INTENT);

View file

@ -2,7 +2,6 @@ package eu.siacs.conversations.entities;
import java.security.interfaces.DSAPublicKey;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.CopyOnWriteArrayList;
import net.java.otr4j.crypto.OtrCryptoEngineImpl;
@ -16,6 +15,9 @@ import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.OtrEngine;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xmpp.XmppConnection;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
import android.content.ContentValues;
import android.database.Cursor;
import android.os.SystemClock;
@ -50,12 +52,10 @@ public class Account extends AbstractEntity {
public static final int STATUS_REGISTRATION_SUCCESSFULL = 9;
public static final int STATUS_REGISTRATION_NOT_SUPPORTED = 10;
protected String username;
protected String server;
protected Jid jid;
protected String password;
protected int options = 0;
protected String rosterVersion;
protected String resource = "mobile";
protected int status = -1;
protected JSONObject keys = new JSONObject();
protected String avatar;
@ -69,31 +69,33 @@ public class Account extends AbstractEntity {
private String otrFingerprint;
private Roster roster = null;
private List<Bookmark> bookmarks = new CopyOnWriteArrayList<Bookmark>();
public List<Conversation> pendingConferenceJoins = new CopyOnWriteArrayList<Conversation>();
public List<Conversation> pendingConferenceLeaves = new CopyOnWriteArrayList<Conversation>();
private List<Bookmark> bookmarks = new CopyOnWriteArrayList<>();
public List<Conversation> pendingConferenceJoins = new CopyOnWriteArrayList<>();
public List<Conversation> pendingConferenceLeaves = new CopyOnWriteArrayList<>();
public Account() {
this.uuid = "0";
}
public Account(String username, String server, String password) {
this(java.util.UUID.randomUUID().toString(), username, server,
public Account(final Jid jid, final String password) {
this(java.util.UUID.randomUUID().toString(), jid,
password, 0, null, "", null);
}
public Account(String uuid, String username, String server,
String password, int options, String rosterVersion, String keys,
String avatar) {
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.username = username;
this.server = server;
this.jid = jid;
if (jid.getResourcepart().isEmpty()) {
this.setResource("mobile");
}
this.password = password;
this.options = options;
this.rosterVersion = rosterVersion;
try {
this.keys = new JSONObject(keys);
} catch (JSONException e) {
} catch (final JSONException ignored) {
}
this.avatar = avatar;
@ -112,30 +114,30 @@ public class Account extends AbstractEntity {
}
public String getUsername() {
return username;
return jid.getLocalpart();
}
public void setUsername(String username) {
this.username = username;
public void setUsername(final String username) throws InvalidJidException {
jid = Jid.fromParts(username, jid.getDomainpart(), jid.getResourcepart());
}
public Jid getServer() {
return jid.toDomainJid();
}
public String getServer() {
return server;
}
public void setServer(String server) {
this.server = server;
public void setServer(final String server) throws InvalidJidException {
jid = Jid.fromParts(jid.getLocalpart(), server, jid.getResourcepart());
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
public void setPassword(final String password) {
this.password = password;
}
public void setStatus(int status) {
public void setStatus(final int status) {
this.status = status;
}
@ -156,25 +158,22 @@ public class Account extends AbstractEntity {
}
public boolean hasErrorStatus() {
if (getXmppConnection() == null) {
return false;
} else {
return getStatus() > STATUS_NO_INTERNET
&& (getXmppConnection().getAttempt() >= 2);
}
return getXmppConnection() != null && getStatus() > STATUS_NO_INTERNET && (getXmppConnection().getAttempt() >= 2);
}
public void setResource(String resource) {
this.resource = resource;
}
public void setResource(final String resource){
try {
jid = Jid.fromParts(jid.getLocalpart(), jid.getDomainpart(), resource);
} catch (final InvalidJidException ignored) {
}
}
public String getResource() {
return this.resource;
return jid.getResourcepart();
}
public String getJid() {
return username.toLowerCase(Locale.getDefault()) + "@"
+ server.toLowerCase(Locale.getDefault());
public Jid getJid() {
return jid.toBareJid();
}
public JSONObject getKeys() {
@ -210,8 +209,8 @@ public class Account extends AbstractEntity {
public ContentValues getContentValues() {
ContentValues values = new ContentValues();
values.put(UUID, uuid);
values.put(USERNAME, username);
values.put(SERVER, server);
values.put(USERNAME, jid.getLocalpart());
values.put(SERVER, jid.getDomainpart());
values.put(PASSWORD, password);
values.put(OPTIONS, options);
values.put(KEYS, this.keys.toString());
@ -221,9 +220,14 @@ public class Account extends AbstractEntity {
}
public static Account fromCursor(Cursor cursor) {
return new Account(cursor.getString(cursor.getColumnIndex(UUID)),
cursor.getString(cursor.getColumnIndex(USERNAME)),
cursor.getString(cursor.getColumnIndex(SERVER)),
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)),
@ -246,8 +250,8 @@ public class Account extends AbstractEntity {
this.xmppConnection = connection;
}
public String getFullJid() {
return this.getJid() + "/" + this.resource;
public Jid getFullJid() {
return this.getJid();
}
public String getOtrFingerprint() {
@ -265,7 +269,7 @@ public class Account extends AbstractEntity {
builder.insert(26, " ");
builder.insert(35, " ");
this.otrFingerprint = builder.toString();
} catch (OtrCryptoException e) {
} catch (final OtrCryptoException ignored) {
}
}
@ -332,9 +336,9 @@ public class Account extends AbstractEntity {
return this.bookmarks;
}
public boolean hasBookmarkFor(String conferenceJid) {
public boolean hasBookmarkFor(final Jid conferenceJid) {
for (Bookmark bmark : this.bookmarks) {
if (bmark.getJid().equals(conferenceJid)) {
if (bmark.getJid().equals(conferenceJid.toBareJid())) {
return true;
}
}

View file

@ -3,15 +3,17 @@ package eu.siacs.conversations.entities;
import java.util.Locale;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
public class Bookmark extends Element implements ListItem {
private Account account;
private Conversation mJoinedConversation;
public Bookmark(Account account, String jid) {
public Bookmark(final Account account, final Jid jid) {
super("conference");
this.setAttribute("jid", jid);
this.setAttribute("jid", jid.toString());
this.account = account;
}
@ -55,10 +57,10 @@ public class Bookmark extends Element implements ListItem {
}
@Override
public int compareTo(ListItem another) {
return this.getDisplayName().compareToIgnoreCase(
another.getDisplayName());
}
public int compareTo(final ListItem another) {
return this.getDisplayName().compareToIgnoreCase(
another.getDisplayName());
}
@Override
public String getDisplayName() {
@ -68,16 +70,20 @@ public class Bookmark extends Element implements ListItem {
} else if (getName() != null) {
return getName();
} else {
return this.getJid().split("@")[0];
return this.getJid().getLocalpart();
}
}
@Override
public String getJid() {
String jid = this.getAttribute("jid");
public Jid getJid() {
final String jid = this.getAttribute("jid");
if (jid != null) {
return jid.toLowerCase(Locale.US);
} else {
try {
return Jid.fromString(jid);
} catch (final InvalidJidException e) {
return null;
}
} else {
return null;
}
}
@ -108,7 +114,7 @@ public class Bookmark extends Element implements ListItem {
public boolean match(String needle) {
return needle == null
|| getJid().contains(needle.toLowerCase(Locale.US))
|| getJid().toString().toLowerCase(Locale.US).contains(needle.toLowerCase(Locale.US))
|| getDisplayName().toLowerCase(Locale.US).contains(
needle.toLowerCase(Locale.US));
}

View file

@ -1,16 +1,18 @@
package eu.siacs.conversations.entities;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import android.content.ContentValues;
import android.database.Cursor;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashSet;
import java.util.Set;
import eu.siacs.conversations.xml.Element;
import android.content.ContentValues;
import android.database.Cursor;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
public class Contact implements ListItem {
public static final String TABLENAME = "contacts";
@ -31,7 +33,7 @@ public class Contact implements ListItem {
protected String systemName;
protected String serverName;
protected String presenceName;
protected String jid;
protected Jid jid;
protected int subscription = 0;
protected String systemAccount;
protected String photoUri;
@ -41,12 +43,10 @@ public class Contact implements ListItem {
protected Account account;
protected boolean inRoster = true;
public Lastseen lastseen = new Lastseen();
public Contact(final String account, final String systemName, final String serverName,
final String jid, final int subscription, final String photoUri,
final Jid jid, final int subscription, final String photoUri,
final String systemAccount, final String keys, final String avatar,
final Lastseen lastseen) {
this(account, systemName, serverName, jid, subscription, photoUri, systemAccount, keys,
@ -55,7 +55,7 @@ public class Contact implements ListItem {
}
public Contact(final String account, final String systemName, final String serverName,
final String jid, final int subscription, final String photoUri,
final Jid jid, final int subscription, final String photoUri,
final String systemAccount, final String keys, final String avatar) {
this.accountUuid = account;
this.systemName = systemName;
@ -72,33 +72,35 @@ public class Contact implements ListItem {
this.avatar = avatar;
}
public Contact(final String jid) {
public Contact(final Jid jid) {
this.jid = jid;
}
public String getDisplayName() {
if (this.systemName != null) {
return this.systemName;
} else if (this.serverName != null) {
return this.serverName;
return this.systemName;
} else if (this.serverName != null) {
return this.serverName;
} else if (this.presenceName != null) {
return this.presenceName;
return this.presenceName;
} else if (jid.hasLocalpart()) {
return jid.getLocalpart();
} else {
return this.jid.split("@")[0];
}
return jid.getDomainpart();
}
}
public String getProfilePhoto() {
return this.photoUri;
}
public String getJid() {
return this.jid.toLowerCase(Locale.getDefault());
public Jid getJid() {
return jid;
}
public boolean match(String needle) {
return needle == null
|| jid.contains(needle.toLowerCase())
|| jid.toString().contains(needle.toLowerCase())
|| getDisplayName().toLowerCase()
.contains(needle.toLowerCase());
}
@ -108,7 +110,7 @@ public class Contact implements ListItem {
values.put(ACCOUNT, accountUuid);
values.put(SYSTEMNAME, systemName);
values.put(SERVERNAME, serverName);
values.put(JID, jid);
values.put(JID, jid.toString());
values.put(OPTIONS, subscription);
values.put(SYSTEMACCOUNT, systemAccount);
values.put(PHOTOURI, photoUri);
@ -123,10 +125,17 @@ public class Contact implements ListItem {
final Lastseen lastseen = new Lastseen(
cursor.getString(cursor.getColumnIndex(LAST_PRESENCE)),
cursor.getLong(cursor.getColumnIndex(LAST_TIME)));
return new Contact(cursor.getString(cursor.getColumnIndex(ACCOUNT)),
final Jid jid;
try {
jid = Jid.fromString(cursor.getString(cursor.getColumnIndex(JID)));
} 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)),
cursor.getString(cursor.getColumnIndex(JID)),
jid,
cursor.getInt(cursor.getColumnIndex(OPTIONS)),
cursor.getString(cursor.getColumnIndex(PHOTOURI)),
cursor.getString(cursor.getColumnIndex(SYSTEMACCOUNT)),
@ -198,7 +207,7 @@ public class Contact implements ListItem {
}
public Set<String> getOtrFingerprints() {
Set<String> set = new HashSet<String>();
Set<String> set = new HashSet<>();
try {
if (this.keys.has("otr_fingerprints")) {
JSONArray fingerprints = this.keys
@ -225,7 +234,7 @@ public class Contact implements ListItem {
}
fingerprints.put(print);
this.keys.put("otr_fingerprints", fingerprints);
} catch (JSONException e) {
} catch (final JSONException ignored) {
}
}
@ -233,7 +242,7 @@ public class Contact implements ListItem {
public void setPgpKeyId(long keyId) {
try {
this.keys.put("pgp_keyid", keyId);
} catch (JSONException e) {
} catch (final JSONException ignored) {
}
}
@ -273,21 +282,26 @@ public class Contact implements ListItem {
String subscription = item.getAttribute("subscription");
if (subscription != null) {
if (subscription.equals("to")) {
this.resetOption(Contact.Options.FROM);
this.setOption(Contact.Options.TO);
} else if (subscription.equals("from")) {
this.resetOption(Contact.Options.TO);
this.setOption(Contact.Options.FROM);
this.resetOption(Contact.Options.PREEMPTIVE_GRANT);
} else if (subscription.equals("both")) {
this.setOption(Contact.Options.TO);
this.setOption(Contact.Options.FROM);
this.resetOption(Contact.Options.PREEMPTIVE_GRANT);
} else if (subscription.equals("none")) {
this.resetOption(Contact.Options.FROM);
this.resetOption(Contact.Options.TO);
}
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
@ -301,8 +315,8 @@ public class Contact implements ListItem {
}
public Element asElement() {
Element item = new Element("item");
item.setAttribute("jid", this.jid);
final Element item = new Element("item");
item.setAttribute("jid", this.jid.toString());
if (this.serverName != null) {
item.setAttribute("name", this.serverName);
}
@ -335,18 +349,13 @@ public class Contact implements ListItem {
}
@Override
public int compareTo(ListItem another) {
public int compareTo(final ListItem another) {
return this.getDisplayName().compareToIgnoreCase(
another.getDisplayName());
}
public String getServer() {
String[] split = getJid().split("@");
if (split.length >= 2) {
return split[1];
} else {
return null;
}
public Jid getServer() {
return getJid().toDomainJid();
}
public boolean setAvatar(String filename) {

View file

@ -1,13 +1,8 @@
package eu.siacs.conversations.entities;
import java.security.interfaces.DSAPublicKey;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONException;
import org.json.JSONObject;
import eu.siacs.conversations.services.XmppConnectionService;
import android.content.ContentValues;
import android.database.Cursor;
import android.os.SystemClock;
import net.java.otr4j.OtrException;
import net.java.otr4j.crypto.OtrCryptoEngineImpl;
@ -15,9 +10,17 @@ 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 android.content.ContentValues;
import android.database.Cursor;
import android.os.SystemClock;
import org.json.JSONException;
import org.json.JSONObject;
import java.security.interfaces.DSAPublicKey;
import java.util.ArrayList;
import java.util.List;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
public class Conversation extends AbstractEntity {
public static final String TABLENAME = "conversations";
@ -45,7 +48,7 @@ public class Conversation extends AbstractEntity {
private String name;
private String contactUuid;
private String accountUuid;
private String contactJid;
private Jid contactJid;
private int status;
private long created;
private int mode;
@ -54,7 +57,7 @@ public class Conversation extends AbstractEntity {
private String nextPresence;
protected ArrayList<Message> messages = new ArrayList<Message>();
protected ArrayList<Message> messages = new ArrayList<>();
protected Account account = null;
private transient SessionImpl otrSession;
@ -71,17 +74,17 @@ public class Conversation extends AbstractEntity {
private Bookmark bookmark;
public Conversation(String name, Account account, String contactJid,
int mode) {
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(String uuid, String name, String contactUuid,
String accountUuid, String contactJid, long created, int status,
int mode, String attributes) {
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;
@ -91,10 +94,7 @@ public class Conversation extends AbstractEntity {
this.status = status;
this.mode = mode;
try {
if (attributes == null) {
attributes = new String();
}
this.attributes = new JSONObject(attributes);
this.attributes = new JSONObject(attributes == null ? "" : attributes);
} catch (JSONException e) {
this.attributes = new JSONObject();
}
@ -105,10 +105,8 @@ public class Conversation extends AbstractEntity {
}
public boolean isRead() {
if ((this.messages == null) || (this.messages.size() == 0))
return true;
return this.messages.get(this.messages.size() - 1).isRead();
}
return (this.messages == null) || (this.messages.size() == 0) || this.messages.get(this.messages.size() - 1).isRead();
}
public void markRead() {
if (this.messages == null) {
@ -186,7 +184,7 @@ public class Conversation extends AbstractEntity {
this.account = account;
}
public String getContactJid() {
public Jid getContactJid() {
return this.contactJid;
}
@ -204,7 +202,7 @@ public class Conversation extends AbstractEntity {
values.put(NAME, name);
values.put(CONTACT, contactUuid);
values.put(ACCOUNT, accountUuid);
values.put(CONTACTJID, contactJid);
values.put(CONTACTJID, contactJid.toString());
values.put(CREATED, created);
values.put(STATUS, status);
values.put(MODE, mode);
@ -213,11 +211,18 @@ public class Conversation extends AbstractEntity {
}
public static Conversation fromCursor(Cursor cursor) {
return new Conversation(cursor.getString(cursor.getColumnIndex(UUID)),
Jid jid;
try {
jid = Jid.fromString(cursor.getString(cursor.getColumnIndex(CONTACTJID)));
} 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)),
cursor.getString(cursor.getColumnIndex(CONTACTJID)),
jid,
cursor.getLong(cursor.getColumnIndex(CREATED)),
cursor.getInt(cursor.getColumnIndex(STATUS)),
cursor.getInt(cursor.getColumnIndex(MODE)),
@ -241,8 +246,9 @@ public class Conversation extends AbstractEntity {
if (this.otrSession != null) {
return this.otrSession;
} else {
SessionID sessionId = new SessionID(this.getContactJid().split("/",
2)[0], presence, "xmpp");
final SessionID sessionId = new SessionID(this.getContactJid().toBareJid().toString(),
presence,
"xmpp");
this.otrSession = new SessionImpl(sessionId, getAccount()
.getOtrEngine(service));
try {
@ -317,7 +323,7 @@ public class Conversation extends AbstractEntity {
builder.insert(26, " ");
builder.insert(35, " ");
this.otrFingerprint = builder.toString();
} catch (OtrCryptoException e) {
} catch (final OtrCryptoException ignored) {
}
}
@ -335,7 +341,7 @@ public class Conversation extends AbstractEntity {
this.mucOptions = null;
}
public void setContactJid(String jid) {
public void setContactJid(final Jid jid) {
this.contactJid = jid;
}

View file

@ -1,7 +1,9 @@
package eu.siacs.conversations.entities;
import eu.siacs.conversations.xmpp.jid.Jid;
public interface ListItem extends Comparable<ListItem> {
public String getDisplayName();
public String getJid();
public Jid getJid();
}

View file

@ -5,6 +5,9 @@ import java.net.URL;
import java.util.Arrays;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
import android.content.ContentValues;
import android.database.Cursor;
@ -44,7 +47,7 @@ public class Message extends AbstractEntity {
public static String REMOTE_MSG_ID = "remoteMsgId";
protected String conversationUuid;
protected String counterpart;
protected Jid counterpart;
protected String trueCounterpart;
protected String body;
protected String encryptedBody;
@ -74,17 +77,17 @@ public class Message extends AbstractEntity {
this.conversation = conversation;
}
public Message(Conversation conversation, String counterpart, String body,
int encryption, int status) {
public Message(final Conversation conversation, final Jid counterpart, final String body,
final int encryption, final int status) {
this(java.util.UUID.randomUUID().toString(), conversation.getUuid(),
counterpart, null, body, System.currentTimeMillis(),
encryption, status, TYPE_TEXT, null);
this.conversation = conversation;
}
public Message(String uuid, String conversationUUid, String counterpart,
String trueCounterpart, String body, long timeSent, int encryption,
int status, int type, String remoteMsgId) {
public Message(final String uuid, final String conversationUUid, final Jid counterpart,
final String trueCounterpart, final String body, final long timeSent,
final int encryption, final int status, final int type, final String remoteMsgId) {
this.uuid = uuid;
this.conversationUuid = conversationUUid;
this.counterpart = counterpart;
@ -102,7 +105,7 @@ public class Message extends AbstractEntity {
ContentValues values = new ContentValues();
values.put(UUID, uuid);
values.put(CONVERSATION, conversationUuid);
values.put(COUNTERPART, counterpart);
values.put(COUNTERPART, counterpart.toString());
values.put(TRUE_COUNTERPART, trueCounterpart);
values.put(BODY, body);
values.put(TIME_SENT, timeSent);
@ -121,7 +124,7 @@ public class Message extends AbstractEntity {
return this.conversation;
}
public String getCounterpart() {
public Jid getCounterpart() {
return counterpart;
}
@ -163,9 +166,15 @@ public class Message extends AbstractEntity {
}
public static Message fromCursor(Cursor cursor) {
return new Message(cursor.getString(cursor.getColumnIndex(UUID)),
Jid jid;
try {
jid = Jid.fromString(cursor.getString(cursor.getColumnIndex(COUNTERPART)));
} catch (InvalidJidException e) {
jid = null;
}
return new Message(cursor.getString(cursor.getColumnIndex(UUID)),
cursor.getString(cursor.getColumnIndex(CONVERSATION)),
cursor.getString(cursor.getColumnIndex(COUNTERPART)),
jid,
cursor.getString(cursor.getColumnIndex(TRUE_COUNTERPART)),
cursor.getString(cursor.getColumnIndex(BODY)),
cursor.getLong(cursor.getColumnIndex(TIME_SENT)),
@ -225,28 +234,23 @@ public class Message extends AbstractEntity {
public void setPresence(String presence) {
if (presence == null) {
this.counterpart = this.counterpart.split("/", 2)[0];
this.counterpart = this.counterpart.toBareJid();
} else {
this.counterpart = this.counterpart.split("/", 2)[0] + "/"
+ presence;
}
try {
this.counterpart = Jid.fromString(this.counterpart.toBareJid() + "/" + presence);
} catch (final InvalidJidException ignored) {
// TODO: Handle this?
}
}
}
public void setTrueCounterpart(String trueCounterpart) {
this.trueCounterpart = trueCounterpart;
}
public String getPresence() {
String[] counterparts = this.counterpart.split("/", 2);
if (counterparts.length == 2) {
return counterparts[1];
} else {
if (this.counterpart.contains("/")) {
return "";
} else {
return null;
}
}
public Jid getPresence() {
// TODO: This is now the same as getCounterpart()... find usages in code and remove one?
return counterpart;
}
public void setDownloadable(Downloadable downloadable) {
@ -264,7 +268,7 @@ public class Message extends AbstractEntity {
return message;
}
public void setCounterpart(String counterpart) {
public void setCounterpart(final Jid counterpart) {
this.counterpart = counterpart;
}
@ -359,11 +363,7 @@ public class Message extends AbstractEntity {
public boolean wasMergedIntoPrevious() {
Message prev = this.prev();
if (prev == null) {
return false;
} else {
return prev.mergeable(this);
}
return prev != null && prev.mergeable(this);
}
public boolean trusted() {

View file

@ -6,6 +6,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
import eu.siacs.conversations.crypto.PgpEngine;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
import android.annotation.SuppressLint;
@ -66,15 +68,20 @@ public class MucOptions {
public void setRole(String role) {
role = role.toLowerCase();
if (role.equals("moderator")) {
this.role = ROLE_MODERATOR;
} else if (role.equals("participant")) {
this.role = ROLE_PARTICIPANT;
} else if (role.equals("visitor")) {
this.role = ROLE_VISITOR;
} else {
this.role = ROLE_NONE;
}
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;
}
}
public int getAffiliation() {
@ -109,7 +116,7 @@ public class MucOptions {
}
private Account account;
private List<User> users = new CopyOnWriteArrayList<User>();
private List<User> users = new CopyOnWriteArrayList<>();
private Conversation conversation;
private boolean isOnline = false;
private int error = ERROR_ROOM_NOT_FOUND;
@ -145,9 +152,9 @@ public class MucOptions {
}
public void processPacket(PresencePacket packet, PgpEngine pgp) {
String[] fromParts = packet.getFrom().split("/", 2);
if (fromParts.length >= 2) {
String name = fromParts[1];
final Jid from = packet.getFrom();
if (!from.isBareJid()) {
final String name = from.getResourcepart();
String type = packet.getAttribute("type");
if (type == null) {
User user = new User();
@ -233,13 +240,12 @@ public class MucOptions {
}
public String getProposedNick() {
String[] mucParts = conversation.getContactJid().split("/", 2);
if (conversation.getBookmark() != null
&& conversation.getBookmark().getNick() != null) {
return conversation.getBookmark().getNick();
} else {
if (mucParts.length == 2) {
return mucParts[1];
if (!conversation.getContactJid().getResourcepart().isEmpty()) {
return conversation.getContactJid().getResourcepart();
} else {
return account.getUsername();
}
@ -297,7 +303,7 @@ public class MucOptions {
}
public long[] getPgpKeyIds() {
List<Long> ids = new ArrayList<Long>();
List<Long> ids = new ArrayList<>();
for (User user : getUsers()) {
if (user.getPgpKeyId() != 0) {
ids.add(user.getPgpKeyId());
@ -328,10 +334,14 @@ public class MucOptions {
return true;
}
public String getJoinJid() {
return this.conversation.getContactJid().split("/", 2)[0] + "/"
+ this.joinnick;
}
public Jid getJoinJid() {
try {
return Jid.fromString(this.conversation.getContactJid().toBareJid().toString() + "/"
+ this.joinnick);
} catch (final InvalidJidException e) {
return null;
}
}
public String getTrueCounterpart(String counterpart) {
for (User user : this.getUsers()) {

View file

@ -2,12 +2,13 @@ package eu.siacs.conversations.entities;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
import eu.siacs.conversations.xmpp.jid.Jid;
public class Roster {
Account account;
ConcurrentHashMap<String, Contact> contacts = new ConcurrentHashMap<String, Contact>();
final ConcurrentHashMap<String, Contact> contacts = new ConcurrentHashMap<>();
private String version = null;
public Roster(Account account) {
@ -27,14 +28,14 @@ public class Roster {
}
}
public Contact getContact(String jid) {
String cleanJid = jid.split("/", 2)[0].toLowerCase(Locale.getDefault());
if (contacts.containsKey(cleanJid)) {
return contacts.get(cleanJid);
public Contact getContact(final Jid jid) {
final Jid bareJid = jid.toBareJid();
if (contacts.containsKey(bareJid.toString())) {
return contacts.get(bareJid.toString());
} else {
Contact contact = new Contact(cleanJid);
Contact contact = new Contact(bareJid);
contact.setAccount(account);
contacts.put(cleanJid, contact);
contacts.put(bareJid.toString(), contact);
return contact;
}
}
@ -60,13 +61,13 @@ public class Roster {
}
public List<Contact> getContacts() {
return new ArrayList<Contact>(this.contacts.values());
return new ArrayList<>(this.contacts.values());
}
public void initContact(Contact contact) {
public void initContact(final Contact contact) {
contact.setAccount(account);
contact.setOption(Contact.Options.IN_ROSTER);
contacts.put(contact.getJid(), contact);
contacts.put(contact.getJid().toBareJid().toString(), contact);
}
public void setVersion(String version) {

View file

@ -6,6 +6,7 @@ import java.util.List;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.pep.Avatar;
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
@ -18,7 +19,7 @@ public class IqGenerator extends AbstractGenerator {
public IqPacket discoResponse(IqPacket request) {
IqPacket packet = new IqPacket(IqPacket.TYPE_RESULT);
packet.setId(request.getId());
packet.setTo(request.getFrom());
packet.setTo(request.getFrom());
Element query = packet.addChild("query",
"http://jabber.org/protocol/disco#info");
query.setAttribute("node", request.query().getAttribute("node"));
@ -86,8 +87,8 @@ public class IqGenerator extends AbstractGenerator {
return packet;
}
public IqPacket retrieveAvatarMetaData(String to) {
IqPacket packet = retrieve("urn:xmpp:avatar:metadata", null);
public IqPacket retrieveAvatarMetaData(final Jid to) {
final IqPacket packet = retrieve("urn:xmpp:avatar:metadata", null);
if (to != null) {
packet.setTo(to);
}

View file

@ -12,6 +12,7 @@ import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
public class MessageGenerator extends AbstractGenerator {
@ -34,7 +35,7 @@ public class MessageGenerator extends AbstractGenerator {
packet.setTo(message.getCounterpart());
packet.setType(MessagePacket.TYPE_CHAT);
} else {
packet.setTo(message.getCounterpart().split("/", 2)[0]);
packet.setTo(message.getCounterpart().toBareJid());
packet.setType(MessagePacket.TYPE_GROUPCHAT);
}
packet.setFrom(account.getFullJid());
@ -113,13 +114,13 @@ public class MessageGenerator extends AbstractGenerator {
private MessagePacket generateError(MessagePacket origin) {
MessagePacket packet = new MessagePacket();
packet.setId(origin.getId());
packet.setTo(origin.getFrom());
packet.setTo(origin.getFrom());
packet.setBody(origin.getBody());
packet.setType(MessagePacket.TYPE_ERROR);
return packet;
}
public MessagePacket confirm(Account account, String to, String id) {
public MessagePacket confirm(final Account account, final Jid to, final String id) {
MessagePacket packet = new MessagePacket();
packet.setType(MessagePacket.TYPE_NORMAL);
packet.setTo(to);
@ -134,7 +135,7 @@ public class MessageGenerator extends AbstractGenerator {
String subject) {
MessagePacket packet = new MessagePacket();
packet.setType(MessagePacket.TYPE_GROUPCHAT);
packet.setTo(conversation.getContactJid().split("/", 2)[0]);
packet.setTo(conversation.getContactJid().toBareJid());
Element subjectChild = new Element("subject");
subjectChild.setContent(subject);
packet.addChild(subjectChild);
@ -142,19 +143,19 @@ public class MessageGenerator extends AbstractGenerator {
return packet;
}
public MessagePacket directInvite(Conversation conversation, String contact) {
public MessagePacket directInvite(final Conversation conversation, final Jid contact) {
MessagePacket packet = new MessagePacket();
packet.setType(MessagePacket.TYPE_NORMAL);
packet.setTo(contact);
packet.setFrom(conversation.getAccount().getFullJid());
Element x = packet.addChild("x", "jabber:x:conference");
x.setAttribute("jid", conversation.getContactJid().split("/", 2)[0]);
x.setAttribute("jid", conversation.getContactJid().toBareJid().toString());
return packet;
}
public MessagePacket invite(Conversation conversation, String contact) {
MessagePacket packet = new MessagePacket();
packet.setTo(conversation.getContactJid().split("/", 2)[0]);
packet.setTo(conversation.getContactJid().toBareJid());
packet.setFrom(conversation.getAccount().getFullJid());
Element x = new Element("x");
x.setAttribute("xmlns", "http://jabber.org/protocol/muc#user");
@ -169,7 +170,7 @@ public class MessageGenerator extends AbstractGenerator {
MessagePacket originalMessage, String namespace) {
MessagePacket receivedPacket = new MessagePacket();
receivedPacket.setType(MessagePacket.TYPE_NORMAL);
receivedPacket.setTo(originalMessage.getFrom());
receivedPacket.setTo(originalMessage.getFrom());
receivedPacket.setFrom(account.getFullJid());
Element received = receivedPacket.addChild("received", namespace);
received.setAttribute("id", originalMessage.getId());

View file

@ -15,8 +15,8 @@ public class PresenceGenerator extends AbstractGenerator {
private PresencePacket subscription(String type, Contact contact) {
PresencePacket packet = new PresencePacket();
packet.setAttribute("type", type);
packet.setAttribute("to", contact.getJid());
packet.setAttribute("from", contact.getAccount().getJid());
packet.setTo(contact.getJid());
packet.setFrom(contact.getAccount().getJid());
return packet;
}
@ -38,7 +38,7 @@ public class PresenceGenerator extends AbstractGenerator {
public PresencePacket sendPresence(Account account) {
PresencePacket packet = new PresencePacket();
packet.setAttribute("from", account.getFullJid());
packet.setFrom(account.getFullJid());
String sig = account.getPgpSignature();
if (sig != null) {
packet.addChild("status").setContent("online");

View file

@ -11,6 +11,8 @@ import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
public abstract class AbstractParser {
@ -22,7 +24,7 @@ public abstract class AbstractParser {
protected long getTimestamp(Element packet) {
long now = System.currentTimeMillis();
ArrayList<String> stamps = new ArrayList<String>();
ArrayList<String> stamps = new ArrayList<>();
for (Element child : packet.getChildren()) {
if (child.getName().equals("delay")) {
stamps.add(child.getAttribute("stamp").replace("Z", "+0000"));
@ -58,21 +60,21 @@ public abstract class AbstractParser {
}
}
protected void updateLastseen(Element packet, Account account,
boolean presenceOverwrite) {
String[] fromParts = packet.getAttribute("from").split("/", 2);
String from = fromParts[0];
String presence = null;
if (fromParts.length >= 2) {
presence = fromParts[1];
} else {
presence = "";
}
protected void updateLastseen(final Element packet, final Account account,
final boolean presenceOverwrite) {
Jid from;
try {
from = Jid.fromString(packet.getAttribute("from")).toBareJid();
} catch (final InvalidJidException e) {
// TODO: Handle this?
from = null;
}
String presence = from == null || from.getResourcepart().isEmpty() ? "" : from.getResourcepart();
Contact contact = account.getRoster().getContact(from);
long timestamp = getTimestamp(packet);
if (timestamp >= contact.lastseen.time) {
contact.lastseen.time = timestamp;
if ((presence != null) && (presenceOverwrite)) {
if (!presence.isEmpty() && presenceOverwrite) {
contact.lastseen.presence = presence;
}
}

View file

@ -5,6 +5,8 @@ import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
public class IqParser extends AbstractParser implements OnIqPacketReceived {
@ -20,8 +22,14 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
}
for (Element item : query.getChildren()) {
if (item.getName().equals("item")) {
String jid = item.getAttribute("jid");
String name = item.getAttribute("name");
Jid jid;
try {
jid = Jid.fromString(item.getAttribute("jid"));
} catch (final InvalidJidException e) {
// TODO: Handle this?
jid = null;
}
String name = item.getAttribute("name");
String subscription = item.getAttribute("subscription");
Contact contact = account.getRoster().getContact(jid);
if (!contact.getOption(Contact.Options.DIRTY_PUSH)) {
@ -59,8 +67,8 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
if (packet.hasChild("query", "jabber:iq:roster")) {
String from = packet.getFrom();
if ((from == null) || (from.equals(account.getJid()))) {
final Jid from = packet.getFrom();
if ((from == null) || (from.equals(account.getJid()))) {
Element query = packet.findChild("query");
this.rosterItems(account, query);
}

View file

@ -11,6 +11,8 @@ import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnMessagePacketReceived;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.pep.Avatar;
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
@ -21,9 +23,9 @@ public class MessageParser extends AbstractParser implements
}
private Message parseChat(MessagePacket packet, Account account) {
String[] fromParts = packet.getFrom().split("/", 2);
final Jid jid = packet.getFrom().toBareJid();
Conversation conversation = mXmppConnectionService
.findOrCreateConversation(account, fromParts[0], false);
.findOrCreateConversation(account, jid.toBareJid(), false);
updateLastseen(packet, account, true);
String pgpBody = getPgpBody(packet);
Message finishedMessage;
@ -38,11 +40,11 @@ public class MessageParser extends AbstractParser implements
finishedMessage.setRemoteMsgId(packet.getId());
finishedMessage.markable = isMarkable(packet);
if (conversation.getMode() == Conversation.MODE_MULTI
&& fromParts.length >= 2) {
&& !jid.getResourcepart().isEmpty()) {
finishedMessage.setType(Message.TYPE_PRIVATE);
finishedMessage.setPresence(fromParts[1]);
finishedMessage.setPresence(jid.getResourcepart());
finishedMessage.setTrueCounterpart(conversation.getMucOptions()
.getTrueCounterpart(fromParts[1]));
.getTrueCounterpart(jid.getResourcepart()));
if (conversation.hasDuplicateMessage(finishedMessage)) {
return null;
}
@ -53,16 +55,16 @@ public class MessageParser extends AbstractParser implements
}
private Message parseOtrChat(MessagePacket packet, Account account) {
boolean properlyAddressed = (packet.getTo().split("/", 2).length == 2)
boolean properlyAddressed = (!packet.getTo().isBareJid())
|| (account.countPresences() == 1);
String[] fromParts = packet.getFrom().split("/", 2);
final Jid from = packet.getFrom();
Conversation conversation = mXmppConnectionService
.findOrCreateConversation(account, fromParts[0], false);
.findOrCreateConversation(account, from.toBareJid(), false);
String presence;
if (fromParts.length >= 2) {
presence = fromParts[1];
if (from.isBareJid()) {
presence = "";
} else {
presence = "";
presence = from.getResourcepart();
}
updateLastseen(packet, account, true);
String body = packet.getBody();
@ -127,24 +129,23 @@ public class MessageParser extends AbstractParser implements
private Message parseGroupchat(MessagePacket packet, Account account) {
int status;
String[] fromParts = packet.getFrom().split("/", 2);
final Jid from = packet.getFrom();
if (mXmppConnectionService.find(account.pendingConferenceLeaves,
account, fromParts[0]) != null) {
account, from.toBareJid()) != null) {
return null;
}
Conversation conversation = mXmppConnectionService
.findOrCreateConversation(account, fromParts[0], true);
.findOrCreateConversation(account, from.toBareJid(), true);
if (packet.hasChild("subject")) {
conversation.getMucOptions().setSubject(
packet.findChild("subject").getContent());
mXmppConnectionService.updateConversationUi();
return null;
}
if ((fromParts.length == 1)) {
if (from.isBareJid()) {
return null;
}
String counterPart = fromParts[1];
if (counterPart.equals(conversation.getMucOptions().getActualNick())) {
if (from.getResourcepart().equals(conversation.getMucOptions().getActualNick())) {
if (mXmppConnectionService.markMessage(conversation,
packet.getId(), Message.STATUS_SEND)) {
return null;
@ -157,17 +158,17 @@ public class MessageParser extends AbstractParser implements
String pgpBody = getPgpBody(packet);
Message finishedMessage;
if (pgpBody == null) {
finishedMessage = new Message(conversation, counterPart,
finishedMessage = new Message(conversation, from,
packet.getBody(), Message.ENCRYPTION_NONE, status);
} else {
finishedMessage = new Message(conversation, counterPart, pgpBody,
finishedMessage = new Message(conversation, from, pgpBody,
Message.ENCRYPTION_PGP, status);
}
finishedMessage.setRemoteMsgId(packet.getId());
finishedMessage.markable = isMarkable(packet);
if (status == Message.STATUS_RECEIVED) {
finishedMessage.setTrueCounterpart(conversation.getMucOptions()
.getTrueCounterpart(counterPart));
.getTrueCounterpart(from.getResourcepart()));
}
if (packet.hasChild("delay")
&& conversation.hasDuplicateMessage(finishedMessage)) {
@ -177,9 +178,9 @@ public class MessageParser extends AbstractParser implements
return finishedMessage;
}
private Message parseCarbonMessage(MessagePacket packet, Account account) {
private Message parseCarbonMessage(final MessagePacket packet, final Account account) {
int status;
String fullJid;
final Jid fullJid;
Element forwarded;
if (packet.hasChild("received", "urn:xmpp:carbons:2")) {
forwarded = packet.findChild("received", "urn:xmpp:carbons:2")
@ -205,11 +206,11 @@ public class MessageParser extends AbstractParser implements
parseNonMessage(message, account);
} else if (status == Message.STATUS_SEND
&& message.hasChild("displayed", "urn:xmpp:chat-markers:0")) {
String to = message.getAttribute("to");
final Jid to = message.getTo();
if (to != null) {
Conversation conversation = mXmppConnectionService.find(
final Conversation conversation = mXmppConnectionService.find(
mXmppConnectionService.getConversations(), account,
to.split("/")[0]);
to.toBareJid());
if (conversation != null) {
mXmppConnectionService.markRead(conversation, false);
}
@ -218,21 +219,20 @@ public class MessageParser extends AbstractParser implements
return null;
}
if (status == Message.STATUS_RECEIVED) {
fullJid = message.getAttribute("from");
fullJid = message.getFrom();
if (fullJid == null) {
return null;
} else {
updateLastseen(message, account, true);
}
} else {
fullJid = message.getAttribute("to");
fullJid = message.getTo();
if (fullJid == null) {
return null;
}
}
String[] parts = fullJid.split("/", 2);
Conversation conversation = mXmppConnectionService
.findOrCreateConversation(account, parts[0], false);
.findOrCreateConversation(account, fullJid.toBareJid(), false);
String pgpBody = getPgpBody(message);
Message finishedMessage;
if (pgpBody != null) {
@ -247,11 +247,11 @@ public class MessageParser extends AbstractParser implements
finishedMessage.setRemoteMsgId(message.getAttribute("id"));
finishedMessage.markable = isMarkable(message);
if (conversation.getMode() == Conversation.MODE_MULTI
&& parts.length >= 2) {
&& !fullJid.isBareJid()) {
finishedMessage.setType(Message.TYPE_PRIVATE);
finishedMessage.setPresence(parts[1]);
finishedMessage.setPresence(fullJid.getResourcepart());
finishedMessage.setTrueCounterpart(conversation.getMucOptions()
.getTrueCounterpart(parts[1]));
.getTrueCounterpart(fullJid.getResourcepart()));
if (conversation.hasDuplicateMessage(finishedMessage)) {
return null;
}
@ -259,39 +259,39 @@ public class MessageParser extends AbstractParser implements
return finishedMessage;
}
private void parseError(MessagePacket packet, Account account) {
String[] fromParts = packet.getFrom().split("/", 2);
mXmppConnectionService.markMessage(account, fromParts[0],
private void parseError(final MessagePacket packet, final Account account) {
final Jid from = packet.getFrom();
mXmppConnectionService.markMessage(account, from.toBareJid(),
packet.getId(), Message.STATUS_SEND_FAILED);
}
private void parseNonMessage(Element packet, Account account) {
String from = packet.getAttribute("from");
final Jid from = packet.getFrom();
if (packet.hasChild("event", "http://jabber.org/protocol/pubsub#event")) {
Element event = packet.findChild("event",
"http://jabber.org/protocol/pubsub#event");
parseEvent(event, packet.getAttribute("from"), account);
parseEvent(event, from, account);
} else if (from != null
&& packet.hasChild("displayed", "urn:xmpp:chat-markers:0")) {
String id = packet
.findChild("displayed", "urn:xmpp:chat-markers:0")
.getAttribute("id");
updateLastseen(packet, account, true);
mXmppConnectionService.markMessage(account, from.split("/", 2)[0],
mXmppConnectionService.markMessage(account, from.toBareJid(),
id, Message.STATUS_SEND_DISPLAYED);
} else if (from != null
&& packet.hasChild("received", "urn:xmpp:chat-markers:0")) {
String id = packet.findChild("received", "urn:xmpp:chat-markers:0")
.getAttribute("id");
updateLastseen(packet, account, false);
mXmppConnectionService.markMessage(account, from.split("/", 2)[0],
mXmppConnectionService.markMessage(account, from.toBareJid(),
id, Message.STATUS_SEND_RECEIVED);
} else if (from != null
&& packet.hasChild("received", "urn:xmpp:receipts")) {
String id = packet.findChild("received", "urn:xmpp:receipts")
.getAttribute("id");
updateLastseen(packet, account, false);
mXmppConnectionService.markMessage(account, from.split("/", 2)[0],
mXmppConnectionService.markMessage(account, from.toBareJid(),
id, Message.STATUS_SEND_RECEIVED);
} else if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
Element x = packet.findChild("x",
@ -299,7 +299,7 @@ public class MessageParser extends AbstractParser implements
if (x.hasChild("invite")) {
Conversation conversation = mXmppConnectionService
.findOrCreateConversation(account,
packet.getAttribute("from"), true);
packet.getFrom(), true);
if (!conversation.getMucOptions().online()) {
if (x.hasChild("password")) {
Element password = x.findChild("password");
@ -314,8 +314,13 @@ public class MessageParser extends AbstractParser implements
}
} else if (packet.hasChild("x", "jabber:x:conference")) {
Element x = packet.findChild("x", "jabber:x:conference");
String jid = x.getAttribute("jid");
String password = x.getAttribute("password");
Jid jid;
try {
jid = Jid.fromString(x.getAttribute("jid"));
} catch (InvalidJidException e) {
jid = null;
}
String password = x.getAttribute("password");
if (jid != null) {
Conversation conversation = mXmppConnectionService
.findOrCreateConversation(account, jid, true);
@ -332,7 +337,7 @@ public class MessageParser extends AbstractParser implements
}
}
private void parseEvent(Element event, String from, Account account) {
private void parseEvent(final Element event, final Jid from, final Account account) {
Element items = event.findChild("items");
String node = items.getAttribute("node");
if (node != null) {

View file

@ -9,6 +9,7 @@ import eu.siacs.conversations.generator.PresenceGenerator;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnPresencePacketReceived;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
public class PresenceParser extends AbstractParser implements
@ -21,8 +22,9 @@ public class PresenceParser extends AbstractParser implements
public void parseConferencePresence(PresencePacket packet, Account account) {
PgpEngine mPgpEngine = mXmppConnectionService.getPgpEngine();
if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
Conversation muc = mXmppConnectionService.find(account, packet
.getAttribute("from").split("/", 2)[0]);
final Conversation muc = packet.getFrom() == null ? null : mXmppConnectionService.find(
account,
packet.getFrom().toBareJid());
if (muc != null) {
boolean before = muc.getMucOptions().online();
muc.getMucOptions().processPacket(packet, mPgpEngine);
@ -32,8 +34,8 @@ public class PresenceParser extends AbstractParser implements
mXmppConnectionService.getAvatarService().clear(muc);
}
} else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
Conversation muc = mXmppConnectionService.find(account, packet
.getAttribute("from").split("/", 2)[0]);
final Conversation muc = mXmppConnectionService.find(account,
packet.getFrom().toBareJid());
if (muc != null) {
boolean before = muc.getMucOptions().online();
muc.getMucOptions().processPacket(packet, mPgpEngine);
@ -51,15 +53,15 @@ public class PresenceParser extends AbstractParser implements
if (packet.getFrom() == null) {
return;
}
String[] fromParts = packet.getFrom().split("/", 2);
final Jid from = packet.getFrom();
String type = packet.getAttribute("type");
if (fromParts[0].equals(account.getJid())) {
if (fromParts.length == 2) {
if (from.toBareJid().equals(account.getJid())) {
if (!from.getResourcepart().isEmpty()) {
if (type == null) {
account.updatePresence(fromParts[1],
account.updatePresence(from.getResourcepart(),
Presences.parseShow(packet.findChild("show")));
} else if (type.equals("unavailable")) {
account.removePresence(fromParts[1]);
account.removePresence(from.getResourcepart());
account.deactivateGracePeriod();
}
}
@ -67,8 +69,8 @@ public class PresenceParser extends AbstractParser implements
Contact contact = account.getRoster().getContact(packet.getFrom());
if (type == null) {
String presence;
if (fromParts.length >= 2) {
presence = fromParts[1];
if (!from.getResourcepart().isEmpty()) {
presence = from.getResourcepart();
} else {
presence = "";
}
@ -95,10 +97,10 @@ public class PresenceParser extends AbstractParser implements
mXmppConnectionService.onContactStatusChanged
.onContactStatusChanged(contact, online);
} else if (type.equals("unavailable")) {
if (fromParts.length != 2) {
if (from.isBareJid()) {
contact.clearPresences();
} else {
contact.removePresence(fromParts[1]);
contact.removePresence(from.getResourcepart());
}
mXmppConnectionService.onContactStatusChanged
.onContactStatusChanged(contact, false);

View file

@ -9,6 +9,8 @@ import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.entities.Roster;
import eu.siacs.conversations.xmpp.jid.Jid;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteCantOpenDatabaseException;
@ -147,7 +149,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
}
public CopyOnWriteArrayList<Conversation> getConversations(int status) {
CopyOnWriteArrayList<Conversation> list = new CopyOnWriteArrayList<Conversation>();
CopyOnWriteArrayList<Conversation> list = new CopyOnWriteArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
String[] selectionArgs = { Integer.toString(status) };
Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME
@ -165,7 +167,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
public ArrayList<Message> getMessages(Conversation conversation, int limit,
long timestamp) {
ArrayList<Message> list = new ArrayList<Message>();
ArrayList<Message> list = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor;
if (timestamp == -1) {
@ -192,9 +194,9 @@ public class DatabaseBackend extends SQLiteOpenHelper {
return list;
}
public Conversation findConversation(Account account, String contactJid) {
public Conversation findConversation(final Account account, final Jid contactJid) {
SQLiteDatabase db = this.getReadableDatabase();
String[] selectionArgs = { account.getUuid(), contactJid + "%" };
String[] selectionArgs = { account.getUuid(), contactJid.toBareJid().toString() + "%" };
Cursor cursor = db.query(Conversation.TABLENAME, null,
Conversation.ACCOUNT + "=? AND " + Conversation.CONTACTJID
+ " like ?", selectionArgs, null, null, null);
@ -212,7 +214,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
}
public List<Account> getAccounts() {
List<Account> list = new ArrayList<Account>();
List<Account> list = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(Account.TABLENAME, null, null, null, null,
null, null);
@ -276,15 +278,15 @@ public class DatabaseBackend extends SQLiteOpenHelper {
cursor.close();
}
public void writeRoster(Roster roster) {
Account account = roster.getAccount();
SQLiteDatabase db = this.getWritableDatabase();
public void writeRoster(final Roster roster) {
final Account account = roster.getAccount();
final SQLiteDatabase db = this.getWritableDatabase();
for (Contact contact : roster.getContacts()) {
if (contact.getOption(Contact.Options.IN_ROSTER)) {
db.insert(Contact.TABLENAME, null, contact.getContentValues());
} else {
String where = Contact.ACCOUNT + "=? AND " + Contact.JID + "=?";
String[] whereArgs = { account.getUuid(), contact.getJid() };
String[] whereArgs = { account.getUuid(), contact.getJid().toString() };
db.delete(Contact.TABLENAME, where, whereArgs);
}
}
@ -341,7 +343,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
}
public List<Message> getImageMessages(Conversation conversation) {
ArrayList<Message> list = new ArrayList<Message>();
ArrayList<Message> list = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor;
String[] selectionArgs = { conversation.getUuid(), String.valueOf(Message.TYPE_IMAGE) };

View file

@ -28,7 +28,7 @@ public class AvatarService {
private static final String PREFIX_ACCOUNT = "account";
private static final String PREFIX_GENERIC = "generic";
private ArrayList<Integer> sizes = new ArrayList<Integer>();
final private ArrayList<Integer> sizes = new ArrayList<>();
protected XmppConnectionService mXmppConnectionService = null;
@ -36,7 +36,7 @@ public class AvatarService {
this.mXmppConnectionService = service;
}
public Bitmap get(Contact contact, int size) {
public Bitmap get(final Contact contact, final int size) {
final String KEY = key(contact, size);
Bitmap avatar = this.mXmppConnectionService.getBitmapCache().get(KEY);
if (avatar != null) {
@ -49,7 +49,7 @@ public class AvatarService {
avatar = mXmppConnectionService.getFileBackend().getAvatar(contact.getAvatar(), size);
}
if (avatar == null) {
avatar = get(contact.getDisplayName(), size);
avatar = get(contact.getDisplayName(), size);
}
this.mXmppConnectionService.getBitmapCache().put(KEY, avatar);
return avatar;
@ -173,7 +173,7 @@ public class AvatarService {
avatar = mXmppConnectionService.getFileBackend().getAvatar(
account.getAvatar(), size);
if (avatar == null) {
avatar = get(account.getJid(), size);
avatar = get(account.getJid().toString(), size);
}
mXmppConnectionService.getBitmapCache().put(KEY, avatar);
return avatar;
@ -196,7 +196,7 @@ public class AvatarService {
+ String.valueOf(size);
}
public Bitmap get(String name, int size) {
public Bitmap get(final String name, final int size) {
final String KEY = key(name, size);
Bitmap bitmap = mXmppConnectionService.getBitmapCache().get(KEY);
if (bitmap != null) {

View file

@ -55,6 +55,8 @@ import eu.siacs.conversations.xmpp.OnIqPacketReceived;
import eu.siacs.conversations.xmpp.OnMessageAcknowledged;
import eu.siacs.conversations.xmpp.OnStatusChanged;
import eu.siacs.conversations.xmpp.XmppConnection;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.jingle.JingleConnectionManager;
import eu.siacs.conversations.xmpp.jingle.OnJinglePacketReceived;
import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket;
@ -91,8 +93,6 @@ public class XmppConnectionService extends Service {
public DatabaseBackend databaseBackend;
private FileBackend fileBackend = new FileBackend(this);
public long startDate;
private static String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts";
public static String ACTION_CLEAR_NOTIFICATION = "clear_notification";
@ -171,7 +171,6 @@ public class XmppConnectionService extends Service {
XmppConnection connection = account.getXmppConnection();
if (mOnAccountUpdate != null) {
mOnAccountUpdate.onAccountUpdate();
;
}
if (account.getStatus() == Account.STATUS_ONLINE) {
for (Conversation conversation : account.pendingConferenceLeaves) {
@ -182,12 +181,12 @@ public class XmppConnectionService extends Service {
}
mJingleConnectionManager.cancelInTransmission();
List<Conversation> conversations = getConversations();
for (int i = 0; i < conversations.size(); ++i) {
if (conversations.get(i).getAccount() == account) {
conversations.get(i).startOtrIfNeeded();
sendUnsendMessages(conversations.get(i));
}
}
for (Conversation conversation : conversations) {
if (conversation.getAccount() == account) {
conversation.startOtrIfNeeded();
sendUnsendMessages(conversation);
}
}
if (connection != null && connection.getFeatures().csi()) {
if (checkListeners()) {
Log.d(Config.LOGTAG, account.getJid()
@ -335,7 +334,7 @@ public class XmppConnectionService extends Service {
return find(bookmark.getAccount(), bookmark.getJid());
}
public Conversation find(Account account, String jid) {
public Conversation find(final Account account, final Jid jid) {
return find(getConversations(), account, jid);
}
@ -415,7 +414,7 @@ public class XmppConnectionService extends Service {
if (wakeLock.isHeld()) {
try {
wakeLock.release();
} catch (RuntimeException re) {
} catch (final RuntimeException ignored) {
}
}
return START_STICKY;
@ -536,9 +535,9 @@ public class XmppConnectionService extends Service {
public XmppConnection createConnection(Account account) {
SharedPreferences sharedPref = getPreferences();
account.setResource(sharedPref.getString("resource", "mobile")
.toLowerCase(Locale.getDefault()));
XmppConnection connection = new XmppConnection(account, this);
account.setResource(sharedPref.getString("resource", "mobile")
.toLowerCase(Locale.getDefault()));
XmppConnection connection = new XmppConnection(account, this);
connection.setOnMessagePacketReceivedListener(this.mMessageParser);
connection.setOnStatusChangedListener(this.statusListener);
connection.setOnPresencePacketReceivedListener(this.mPresenceParser);
@ -564,7 +563,7 @@ public class XmppConnectionService extends Service {
if (message.getEncryption() == Message.ENCRYPTION_OTR) {
if (!conv.hasValidOtrSession()
&& (message.getPresence() != null)) {
conv.startOtrSession(this, message.getPresence(),
conv.startOtrSession(this, message.getPresence().toString(),
true);
message.setStatus(Message.STATUS_WAITING);
} else if (conv.hasValidOtrSession()
@ -585,7 +584,7 @@ public class XmppConnectionService extends Service {
if (message.getEncryption() == Message.ENCRYPTION_OTR) {
if (!conv.hasValidOtrSession()
&& (message.getPresence() != null)) {
conv.startOtrSession(this, message.getPresence(), true);
conv.startOtrSession(this, message.getPresence().toString(), true);
message.setStatus(Message.STATUS_WAITING);
} else if (conv.hasValidOtrSession()
&& conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) {
@ -632,7 +631,7 @@ public class XmppConnectionService extends Service {
.getUserID());
} else if (!conv.hasValidOtrSession()
&& message.getPresence() != null) {
conv.startOtrSession(this, message.getPresence(), false);
conv.startOtrSession(this, message.getPresence().toString(), false);
}
}
}
@ -668,9 +667,9 @@ public class XmppConnectionService extends Service {
.getPresences();
if (!message.getConversation().hasValidOtrSession()) {
if ((message.getPresence() != null)
&& (presences.has(message.getPresence()))) {
&& (presences.has(message.getPresence().toString()))) {
message.getConversation().startOtrSession(this,
message.getPresence(), true);
message.getPresence().toString(), true);
} else {
if (presences.size() == 1) {
String presence = presences.asStringArray()[0];
@ -700,7 +699,7 @@ public class XmppConnectionService extends Service {
Presences presences = message.getConversation().getContact()
.getPresences();
if ((message.getPresence() != null)
&& (presences.has(message.getPresence()))) {
&& (presences.has(message.getPresence().toString()))) {
markMessage(message, Message.STATUS_OFFERED);
mJingleConnectionManager.createNewConnection(message);
} else {
@ -757,7 +756,7 @@ public class XmppConnectionService extends Service {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
Element query = packet.query();
List<Bookmark> bookmarks = new CopyOnWriteArrayList<Bookmark>();
List<Bookmark> bookmarks = new CopyOnWriteArrayList<>();
Element storage = query.findChild("storage",
"storage:bookmarks");
if (storage != null) {
@ -806,8 +805,14 @@ public class XmppConnectionService extends Service {
}
for (Bundle phoneContact : phoneContacts) {
for (Account account : accounts) {
String jid = phoneContact.getString("jid");
Contact contact = account.getRoster()
Jid jid;
try {
jid = Jid.fromString(phoneContact.getString("jid"));
} catch (final InvalidJidException e) {
// TODO: Warn if contact import fails here?
break;
}
final Contact contact = account.getRoster()
.getContact(jid);
String systemAccount = phoneContact
.getInt("phoneid")
@ -827,7 +832,7 @@ public class XmppConnectionService extends Service {
public List<Conversation> getConversations() {
if (this.conversations == null) {
Hashtable<String, Account> accountLookupTable = new Hashtable<String, Account>();
Hashtable<String, Account> accountLookupTable = new Hashtable<>();
for (Account account : this.accounts) {
accountLookupTable.put(account.getUuid(), account);
}
@ -925,20 +930,20 @@ public class XmppConnectionService extends Service {
return null;
}
public Conversation find(List<Conversation> haystack, Account account,
String jid) {
public Conversation find(final List<Conversation> haystack,
final Account account,
final Jid jid) {
for (Conversation conversation : haystack) {
if ((account == null || conversation.getAccount() == account)
&& (conversation.getContactJid().split("/", 2)[0]
.equalsIgnoreCase(jid))) {
&& (conversation.getContactJid().toBareJid().equals(jid.toBareJid()))) {
return conversation;
}
}
return null;
}
public Conversation findOrCreateConversation(Account account, String jid,
boolean muc) {
public Conversation findOrCreateConversation(final Account account, final Jid jid,
final boolean muc) {
Conversation conversation = find(account, jid);
if (conversation != null) {
return conversation;
@ -961,7 +966,7 @@ public class XmppConnectionService extends Service {
if (contact != null) {
conversationName = contact.getDisplayName();
} else {
conversationName = jid.split("@")[0];
conversationName = jid.getLocalpart();
}
if (muc) {
conversation = new Conversation(conversationName, account, jid,
@ -1163,13 +1168,12 @@ public class XmppConnectionService extends Service {
public void connectMultiModeConversations(Account account) {
List<Conversation> conversations = getConversations();
for (int i = 0; i < conversations.size(); i++) {
Conversation conversation = conversations.get(i);
if ((conversation.getMode() == Conversation.MODE_MULTI)
&& (conversation.getAccount() == account)) {
joinMuc(conversation);
}
}
for (Conversation conversation : conversations) {
if ((conversation.getMode() == Conversation.MODE_MULTI)
&& (conversation.getAccount() == account)) {
joinMuc(conversation);
}
}
}
public void joinMuc(Conversation conversation) {
@ -1182,8 +1186,8 @@ public class XmppConnectionService extends Service {
String nick = conversation.getMucOptions().getProposedNick();
conversation.getMucOptions().setJoinNick(nick);
PresencePacket packet = new PresencePacket();
String joinJid = conversation.getMucOptions().getJoinJid();
packet.setAttribute("to", conversation.getMucOptions().getJoinJid());
final Jid joinJid = conversation.getMucOptions().getJoinJid();
packet.setTo(conversation.getMucOptions().getJoinJid());
Element x = new Element("x");
x.setAttribute("xmlns", "http://jabber.org/protocol/muc");
if (conversation.getMucOptions().getPassword() != null) {
@ -1260,8 +1264,8 @@ public class XmppConnectionService extends Service {
});
options.flagAboutToRename();
PresencePacket packet = new PresencePacket();
packet.setAttribute("to", options.getJoinJid());
packet.setAttribute("from", conversation.getAccount().getFullJid());
packet.setTo(options.getJoinJid());
packet.setFrom(conversation.getAccount().getFullJid());
String sig = account.getPgpSignature();
if (sig != null) {
@ -1289,8 +1293,8 @@ public class XmppConnectionService extends Service {
account.pendingConferenceLeaves.remove(conversation);
if (account.getStatus() == Account.STATUS_ONLINE) {
PresencePacket packet = new PresencePacket();
packet.setAttribute("to", conversation.getMucOptions().getJoinJid());
packet.setAttribute("from", conversation.getAccount().getFullJid());
packet.setTo(conversation.getMucOptions().getJoinJid());
packet.setFrom(conversation.getAccount().getFullJid());
packet.setAttribute("type", "unavailable");
sendPresencePacket(conversation.getAccount(), packet);
conversation.getMucOptions().setOffline();
@ -1307,20 +1311,19 @@ public class XmppConnectionService extends Service {
|| (account.getStatus() == Account.STATUS_DISABLED)) {
if (!force) {
List<Conversation> conversations = getConversations();
for (int i = 0; i < conversations.size(); i++) {
Conversation conversation = conversations.get(i);
if (conversation.getAccount() == account) {
if (conversation.getMode() == Conversation.MODE_MULTI) {
leaveMuc(conversation);
} else {
if (conversation.endOtrIfNeeded()) {
Log.d(Config.LOGTAG, account.getJid()
+ ": ended otr session with "
+ conversation.getContactJid());
}
}
}
}
for (Conversation conversation : conversations) {
if (conversation.getAccount() == account) {
if (conversation.getMode() == Conversation.MODE_MULTI) {
leaveMuc(conversation);
} else {
if (conversation.endOtrIfNeeded()) {
Log.d(Config.LOGTAG, account.getJid()
+ ": ended otr session with "
+ conversation.getContactJid());
}
}
}
}
}
account.getXmppConnection().disconnect(force);
}
@ -1365,24 +1368,23 @@ public class XmppConnectionService extends Service {
account.getJid() + " otr session established with "
+ conversation.getContactJid() + "/"
+ otrSession.getSessionID().getUserID());
for (int i = 0; i < messages.size(); ++i) {
Message msg = messages.get(i);
if ((msg.getStatus() == Message.STATUS_UNSEND || msg.getStatus() == Message.STATUS_WAITING)
&& (msg.getEncryption() == Message.ENCRYPTION_OTR)) {
msg.setPresence(otrSession.getSessionID().getUserID());
if (msg.getType() == Message.TYPE_TEXT) {
MessagePacket outPacket = mMessageGenerator
.generateOtrChat(msg, true);
if (outPacket != null) {
msg.setStatus(Message.STATUS_SEND);
databaseBackend.updateMessage(msg);
sendMessagePacket(account, outPacket);
}
} else if (msg.getType() == Message.TYPE_IMAGE) {
mJingleConnectionManager.createNewConnection(msg);
}
}
}
for (Message msg : messages) {
if ((msg.getStatus() == Message.STATUS_UNSEND || msg.getStatus() == Message.STATUS_WAITING)
&& (msg.getEncryption() == Message.ENCRYPTION_OTR)) {
msg.setPresence(otrSession.getSessionID().getUserID());
if (msg.getType() == Message.TYPE_TEXT) {
MessagePacket outPacket = mMessageGenerator
.generateOtrChat(msg, true);
if (outPacket != null) {
msg.setStatus(Message.STATUS_SEND);
databaseBackend.updateMessage(msg);
sendMessagePacket(account, outPacket);
}
} else if (msg.getType() == Message.TYPE_IMAGE) {
mJingleConnectionManager.createNewConnection(msg);
}
}
}
updateConversationUi();
}
@ -1397,8 +1399,8 @@ public class XmppConnectionService extends Service {
packet.setFrom(account.getFullJid());
packet.addChild("private", "urn:xmpp:carbons:2");
packet.addChild("no-copy", "urn:xmpp:hints");
packet.setTo(otrSession.getSessionID().getAccountID() + "/"
+ otrSession.getSessionID().getUserID());
packet.setAttribute("to", otrSession.getSessionID().getAccountID() + "/"
+ otrSession.getSessionID().getUserID());
try {
packet.setBody(otrSession
.transformSending(CryptoHelper.FILETRANSFER
@ -1596,7 +1598,7 @@ public class XmppConnectionService extends Service {
if (account.getStatus() == Account.STATUS_ONLINE) {
IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
Element item = iq.query("jabber:iq:roster").addChild("item");
item.setAttribute("jid", contact.getJid());
item.setAttribute("jid", contact.getJid().toString());
item.setAttribute("subscription", "remove");
account.getXmppConnection().sendIqPacket(iq, null);
}
@ -1648,8 +1650,8 @@ public class XmppConnectionService extends Service {
}
}
public boolean markMessage(Account account, String recipient, String uuid,
int status) {
public boolean markMessage(final Account account, final Jid recipient, final String uuid,
final int status) {
if (uuid == null) {
return false;
} else {
@ -1730,7 +1732,7 @@ public class XmppConnectionService extends Service {
}
}
public Account findAccountByJid(String accountJid) {
public Account findAccountByJid(final Jid accountJid) {
for (Account account : this.accounts) {
if (account.getJid().equals(accountJid)) {
return account;
@ -1756,7 +1758,7 @@ public class XmppConnectionService extends Service {
Log.d(Config.LOGTAG, conversation.getAccount().getJid()
+ ": sending read marker for " + conversation.getName());
Account account = conversation.getAccount();
String to = conversation.getContactJid();
final Jid to = conversation.getContactJid();
this.sendMessagePacket(conversation.getAccount(),
mMessageGenerator.confirm(account, to, id));
}
@ -1810,14 +1812,14 @@ public class XmppConnectionService extends Service {
}
public List<String> getKnownHosts() {
List<String> hosts = new ArrayList<String>();
List<String> hosts = new ArrayList<>();
for (Account account : getAccounts()) {
if (!hosts.contains(account.getServer())) {
hosts.add(account.getServer());
if (!hosts.contains(account.getServer().toString())) {
hosts.add(account.getServer().toString());
}
for (Contact contact : account.getRoster().getContacts()) {
if (contact.showInRoster()) {
String server = contact.getServer();
final String server = contact.getServer().toString();
if (server != null && !hosts.contains(server)) {
hosts.add(server);
}
@ -1828,7 +1830,7 @@ public class XmppConnectionService extends Service {
}
public List<String> getKnownConferenceHosts() {
ArrayList<String> mucServers = new ArrayList<String>();
ArrayList<String> mucServers = new ArrayList<>();
for (Account account : accounts) {
if (account.getXmppConnection() != null) {
String server = account.getXmppConnection().getMucServer();
@ -1891,7 +1893,7 @@ public class XmppConnectionService extends Service {
}
public List<Contact> findContacts(String jid) {
ArrayList<Contact> contacts = new ArrayList<Contact>();
ArrayList<Contact> contacts = new ArrayList<>();
for (Account account : getAccounts()) {
if (!account.isOptionSet(Account.OPTION_DISABLED)) {
Contact contact = account.getRoster().getContactFromRoster(jid);
@ -1931,7 +1933,7 @@ public class XmppConnectionService extends Service {
}
public void resendFailedMessages(Message message) {
List<Message> messages = new ArrayList<Message>();
List<Message> messages = new ArrayList<>();
Message current = message;
while(current.getStatus() == Message.STATUS_SEND_FAILED) {
messages.add(current);

View file

@ -25,7 +25,7 @@ import eu.siacs.conversations.ui.adapter.ListItemAdapter;
public class ChooseContactActivity extends XmppActivity {
private ListView mListView;
private ArrayList<ListItem> contacts = new ArrayList<ListItem>();
private ArrayList<ListItem> contacts = new ArrayList<>();
private ArrayAdapter<ListItem> mContactsAdapter;
private EditText mSearchEditText;
@ -96,10 +96,10 @@ public class ChooseContactActivity extends XmppActivity {
Intent request = getIntent();
Intent data = new Intent();
ListItem mListItem = contacts.get(position);
data.putExtra("contact", mListItem.getJid());
data.putExtra("contact", mListItem.getJid().toString());
String account = request.getStringExtra("account");
if (account == null && mListItem instanceof Contact) {
account = ((Contact) mListItem).getAccount().getJid();
account = ((Contact) mListItem).getAccount().getJid().toString();
}
data.putExtra("account", account);
data.putExtra("conversation",

View file

@ -53,7 +53,7 @@ public class ConferenceDetailsActivity extends XmppActivity {
}
};
private List<User> users = new ArrayList<MucOptions.User>();
private List<User> users = new ArrayList<>();
private OnConversationUpdate onConvChanged = new OnConversationUpdate() {
@Override
@ -142,7 +142,7 @@ public class ConferenceDetailsActivity extends XmppActivity {
@Override
protected String getShareableUri() {
if (conversation!=null) {
return "xmpp:"+conversation.getContactJid().split("/")[0]+"?join";
return "xmpp:"+conversation.getContactJid().toBareJid().toString()+"?join";
} else {
return "";
}
@ -211,7 +211,7 @@ public class ConferenceDetailsActivity extends XmppActivity {
mYourPhoto.setImageBitmap(avatarService().get(
conversation.getAccount(), getPixel(48)));
setTitle(conversation.getName());
mFullJid.setText(conversation.getContactJid().split("/", 2)[0]);
mFullJid.setText(conversation.getContactJid().toBareJid().toString());
mYourNick.setText(conversation.getMucOptions().getActualNick());
mRoleAffiliaton = (TextView) findViewById(R.id.muc_role);
if (conversation.getMucOptions().online()) {

View file

@ -35,14 +35,16 @@ import eu.siacs.conversations.entities.Presences;
import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
public class ContactDetailsActivity extends XmppActivity {
public static final String ACTION_VIEW_CONTACT = "view_contact";
private Contact contact;
private String accountJid;
private String contactJid;
private Jid accountJid;
private Jid contactJid;
private TextView contactJidTv;
private TextView accountJidTv;
@ -68,7 +70,7 @@ public class ContactDetailsActivity extends XmppActivity {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
intent.setType(Contacts.CONTENT_ITEM_TYPE);
intent.putExtra(Intents.Insert.IM_HANDLE, contact.getJid());
intent.putExtra(Intents.Insert.IM_HANDLE, contact.getJid().toString());
intent.putExtra(Intents.Insert.IM_PROTOCOL,
CommonDataKinds.Im.PROTOCOL_JABBER);
intent.putExtra("finishActivityOnSaveCompleted", true);
@ -174,9 +176,15 @@ public class ContactDetailsActivity extends XmppActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getIntent().getAction().equals(ACTION_VIEW_CONTACT)) {
this.accountJid = getIntent().getExtras().getString("account");
this.contactJid = getIntent().getExtras().getString("contact");
}
try {
this.accountJid = Jid.fromString(getIntent().getExtras().getString("account"));
} catch (final InvalidJidException ignored) {
}
try {
this.contactJid = Jid.fromString(getIntent().getExtras().getString("contact"));
} catch (final InvalidJidException ignored) {
}
}
setContentView(R.layout.activity_contact_details);
contactJidTv = (TextView) findViewById(R.id.details_contactjid);
@ -318,7 +326,7 @@ public class ContactDetailsActivity extends XmppActivity {
contactJidTv.setText(contact.getJid() + " ("
+ contact.getPresences().size() + ")");
} else {
contactJidTv.setText(contact.getJid());
contactJidTv.setText(contact.getJid().toString());
}
accountJidTv.setText(getString(R.string.using_account, contact
.getAccount().getJid()));

View file

@ -69,7 +69,7 @@ public class ConversationActivity extends XmppActivity implements
private View mContentView;
private List<Conversation> conversationList = new ArrayList<Conversation>();
private List<Conversation> conversationList = new ArrayList<>();
private Conversation selectedConversation = null;
private ListView listView;
private ConversationFragment mConversationFragment;
@ -160,8 +160,10 @@ public class ConversationActivity extends XmppActivity implements
this.listAdapter = new ConversationAdapter(this, conversationList);
listView.setAdapter(this.listAdapter);
getActionBar().setDisplayHomeAsUpEnabled(false);
getActionBar().setHomeButtonEnabled(false);
if (getActionBar() != null) {
getActionBar().setDisplayHomeAsUpEnabled(false);
getActionBar().setHomeButtonEnabled(false);
}
listView.setOnItemClickListener(new OnItemClickListener() {
@ -228,8 +230,7 @@ public class ConversationActivity extends XmppActivity implements
.useSubjectToIdentifyConference()) {
ab.setTitle(getSelectedConversation().getName());
} else {
ab.setTitle(getSelectedConversation().getContactJid()
.split("/")[0]);
ab.setTitle(getSelectedConversation().getContactJid().toBareJid().toString());
}
}
invalidateOptionsMenu();
@ -600,7 +601,7 @@ public class ConversationActivity extends XmppActivity implements
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
public boolean onKeyDown(final int keyCode, final KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (!isConversationsOverviewVisable()) {
showConversationsOverview();
@ -611,7 +612,7 @@ public class ConversationActivity extends XmppActivity implements
}
@Override
protected void onNewIntent(Intent intent) {
protected void onNewIntent(final Intent intent) {
if (xmppConnectionServiceBound) {
if (intent != null && VIEW_CONVERSATION.equals(intent.getType())) {
handleViewConversationIntent(intent);
@ -645,7 +646,7 @@ public class ConversationActivity extends XmppActivity implements
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
public void onSaveInstanceState(final Bundle savedInstanceState) {
Conversation conversation = getSelectedConversation();
if (conversation != null) {
savedInstanceState.putString(STATE_OPEN_CONVERSATION,
@ -714,11 +715,11 @@ public class ConversationActivity extends XmppActivity implements
}
private void selectConversationByUuid(String uuid) {
for (int i = 0; i < conversationList.size(); ++i) {
if (conversationList.get(i).getUuid().equals(uuid)) {
setSelectedConversation(conversationList.get(i));
}
}
for (Conversation aConversationList : conversationList) {
if (aConversationList.getUuid().equals(uuid)) {
setSelectedConversation(aConversationList);
}
}
}
public void registerListener() {
@ -832,7 +833,7 @@ public class ConversationActivity extends XmppActivity implements
try {
this.startIntentSenderForResult(pi.getIntentSender(), requestCode,
null, 0, 0, 0);
} catch (SendIntentException e1) {
} catch (final SendIntentException ignored) {
}
}

View file

@ -54,6 +54,7 @@ import eu.siacs.conversations.ui.adapter.MessageAdapter;
import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureClicked;
import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureLongClicked;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.jid.Jid;
public class ConversationFragment extends Fragment {
@ -92,11 +93,9 @@ public class ConversationFragment extends Fragment {
}
};
protected ListView messagesView;
protected LayoutInflater inflater;
protected List<Message> messageList = new ArrayList<Message>();
protected List<Message> messageList = new ArrayList<>();
protected MessageAdapter messageListAdapter;
protected Contact contact;
protected String queuedPqpMessage = null;
private EditMessage mEditMessage;
private ImageButton mSendButton;
private RelativeLayout snackbar;
@ -147,7 +146,7 @@ public class ConversationFragment extends Fragment {
}
}
};
private ConcurrentLinkedQueue<Message> mEncryptedMessages = new ConcurrentLinkedQueue<Message>();
private ConcurrentLinkedQueue<Message> mEncryptedMessages = new ConcurrentLinkedQueue<>();
private boolean mDecryptJobRunning = false;
private OnEditorActionListener mEditorActionListener = new OnEditorActionListener() {
@ -281,10 +280,10 @@ public class ConversationFragment extends Fragment {
if (message.getStatus() <= Message.STATUS_RECEIVED) {
if (message.getConversation().getMode() == Conversation.MODE_MULTI) {
if (message.getPresence() != null) {
highlightInConference(message.getPresence());
highlightInConference(message.getPresence().getResourcepart());
} else {
highlightInConference(message
.getCounterpart());
.getContact().getDisplayName());
}
} else {
Contact contact = message.getConversation()
@ -299,7 +298,7 @@ public class ConversationFragment extends Fragment {
} else {
Account account = message.getConversation().getAccount();
Intent intent = new Intent(activity, EditAccountActivity.class);
intent.putExtra("jid", account.getJid());
intent.putExtra("jid", account.getJid().toString());
startActivity(intent);
}
}
@ -430,9 +429,9 @@ public class ConversationFragment extends Fragment {
.createNewConnection(message);
}
protected void privateMessageWith(String counterpart) {
protected void privateMessageWith(final Jid counterpart) {
this.mEditMessage.setText("");
this.conversation.setNextPresence(counterpart);
this.conversation.setNextPresence(counterpart.toString());
updateChatMsgHint();
}

View file

@ -1,15 +1,10 @@
package eu.siacs.conversations.ui;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@ -27,26 +22,15 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.util.Hashtable;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.utils.Validator;
import eu.siacs.conversations.xmpp.XmppConnection.Features;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.pep.Avatar;
public class EditAccountActivity extends XmppActivity {
@ -68,7 +52,7 @@ public class EditAccountActivity extends XmppActivity {
private RelativeLayout mOtrFingerprintBox;
private ImageButton mOtrFingerprintToClipboardButton;
private String jidToEdit;
private Jid jidToEdit;
private Account mAccount;
private boolean mFetchingAvatar = false;
@ -89,15 +73,14 @@ public class EditAccountActivity extends XmppActivity {
return;
}
boolean registerNewAccount = mRegisterNew.isChecked();
String[] jidParts = mAccountJid.getText().toString().split("@");
String username = jidParts[0];
String server;
if (jidParts.length >= 2) {
server = jidParts[1];
} else {
server = "";
}
String password = mPassword.getText().toString();
final Jid jid;
try {
jid = Jid.fromString(mAccountJid.getText().toString());
} catch (final InvalidJidException e) {
// TODO: Handle this error?
return;
}
String password = mPassword.getText().toString();
String passwordConfirm = mPasswordConfirm.getText().toString();
if (registerNewAccount) {
if (!password.equals(passwordConfirm)) {
@ -109,19 +92,25 @@ public class EditAccountActivity extends XmppActivity {
}
if (mAccount != null) {
mAccount.setPassword(password);
mAccount.setUsername(username);
mAccount.setServer(server);
try {
mAccount.setUsername(jid.hasLocalpart() ? jid.getLocalpart() : "");
mAccount.setServer(jid.getDomainpart());
} catch (final InvalidJidException ignored) {
}
mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
xmppConnectionService.updateAccount(mAccount);
} else {
if (xmppConnectionService.findAccountByJid(mAccountJid
.getText().toString()) != null) {
mAccountJid
.setError(getString(R.string.account_already_exists));
mAccountJid.requestFocus();
return;
}
mAccount = new Account(username, server, password);
try {
if (xmppConnectionService.findAccountByJid(Jid.fromString(mAccountJid.getText().toString())) != null) {
mAccountJid
.setError(getString(R.string.account_already_exists));
mAccountJid.requestFocus();
return;
}
} catch (InvalidJidException e) {
return;
}
mAccount = new Account(jid.toBareJid(), password);
mAccount.setOption(Account.OPTION_USETLS, true);
mAccount.setOption(Account.OPTION_USECOMPRESSION, true);
mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
@ -191,8 +180,7 @@ public class EditAccountActivity extends XmppActivity {
finishInitialSetup(avatar);
}
};
private KnownHostsAdapter mKnownHostsAdapter;
private TextWatcher mTextWatcher = new TextWatcher() {
private TextWatcher mTextWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
@ -217,7 +205,7 @@ public class EditAccountActivity extends XmppActivity {
if (mAccount!=null) {
Intent intent = new Intent(getApplicationContext(),
PublishProfilePictureActivity.class);
intent.putExtra("account", mAccount.getJid());
intent.putExtra("account", mAccount.getJid().toString());
startActivity(intent);
}
}
@ -235,7 +223,7 @@ public class EditAccountActivity extends XmppActivity {
} else {
intent = new Intent(getApplicationContext(),
PublishProfilePictureActivity.class);
intent.putExtra("account", mAccount.getJid());
intent.putExtra("account", mAccount.getJid().toString());
intent.putExtra("setup", true);
}
startActivity(intent);
@ -244,18 +232,6 @@ public class EditAccountActivity extends XmppActivity {
});
}
protected boolean inputDataDiffersFromAccount() {
if (mAccount == null) {
return true;
} else {
return (!mAccount.getJid().equals(mAccountJid.getText().toString()))
|| (!mAccount.getPassword().equals(
mPassword.getText().toString()) || mAccount
.isOptionSet(Account.OPTION_REGISTER) != mRegisterNew
.isChecked());
}
}
protected void updateSaveButton() {
if (mAccount != null
&& mAccount.getStatus() == Account.STATUS_CONNECTING) {
@ -358,8 +334,12 @@ public class EditAccountActivity extends XmppActivity {
protected void onStart() {
super.onStart();
if (getIntent() != null) {
this.jidToEdit = getIntent().getStringExtra("jid");
if (this.jidToEdit != null) {
try {
this.jidToEdit = Jid.fromString(getIntent().getStringExtra("jid"));
} catch (final InvalidJidException | NullPointerException ignored) {
this.jidToEdit = null;
}
if (this.jidToEdit != null) {
this.mRegisterNew.setVisibility(View.GONE);
getActionBar().setTitle(getString(R.string.account_details));
} else {
@ -379,9 +359,9 @@ public class EditAccountActivity extends XmppActivity {
@Override
protected void onBackendConnected() {
this.mKnownHostsAdapter = new KnownHostsAdapter(this,
android.R.layout.simple_list_item_1,
xmppConnectionService.getKnownHosts());
KnownHostsAdapter mKnownHostsAdapter = new KnownHostsAdapter(this,
android.R.layout.simple_list_item_1,
xmppConnectionService.getKnownHosts());
this.xmppConnectionService
.setOnAccountListChangedListener(this.mOnAccountUpdateListener);
if (this.jidToEdit != null) {
@ -393,12 +373,12 @@ public class EditAccountActivity extends XmppActivity {
this.mCancelButton.setEnabled(false);
this.mCancelButton.setTextColor(getSecondaryTextColor());
}
this.mAccountJid.setAdapter(this.mKnownHostsAdapter);
this.mAccountJid.setAdapter(mKnownHostsAdapter);
updateSaveButton();
}
private void updateAccountInformation() {
this.mAccountJid.setText(this.mAccount.getJid());
this.mAccountJid.setText(this.mAccount.getJid().toString());
this.mPassword.setText(this.mAccount.getPassword());
if (this.jidToEdit != null) {
this.mAvatar.setVisibility(View.VISIBLE);

View file

@ -81,7 +81,7 @@ public class ManageAccountActivity extends XmppActivity {
} else {
menu.findItem(R.id.mgmt_account_enable).setVisible(false);
}
menu.setHeaderTitle(this.selectedAccount.getJid());
menu.setHeaderTitle(this.selectedAccount.getJid().toString());
}
@Override
@ -166,7 +166,7 @@ public class ManageAccountActivity extends XmppActivity {
private void publishAvatar(Account account) {
Intent intent = new Intent(getApplicationContext(),
PublishProfilePictureActivity.class);
intent.putExtra("account", account.getJid());
intent.putExtra("account", account.getJid().toString());
startActivity(intent);
}

View file

@ -14,6 +14,8 @@ import android.widget.TextView;
import eu.siacs.conversations.R;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.utils.PhoneHelper;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.pep.Avatar;
public class PublishProfilePictureActivity extends XmppActivity {
@ -148,8 +150,13 @@ public class PublishProfilePictureActivity extends XmppActivity {
@Override
protected void onBackendConnected() {
if (getIntent() != null) {
String jid = getIntent().getStringExtra("account");
if (jid != null) {
Jid jid;
try {
jid = Jid.fromString(getIntent().getStringExtra("account"));
} catch (InvalidJidException e) {
jid = null;
}
if (jid != null) {
this.account = xmppConnectionService.findAccountByJid(jid);
if (this.account.getXmppConnection() != null) {
this.support = this.account.getXmppConnection()
@ -180,7 +187,7 @@ public class PublishProfilePictureActivity extends XmppActivity {
} else {
loadImageIntoPreview(avatarUri);
}
this.accountTextView.setText(this.account.getJid());
this.accountTextView.setText(this.account.getJid().toString());
}
}

View file

@ -5,6 +5,8 @@ import java.util.Arrays;
import java.util.Locale;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Build;
@ -62,8 +64,8 @@ public class SettingsActivity extends XmppActivity implements
.toLowerCase(Locale.US);
if (xmppConnectionServiceBound) {
for (Account account : xmppConnectionService.getAccounts()) {
account.setResource(resource);
if (!account.isOptionSet(Account.OPTION_DISABLED)) {
account.setResource(resource);
if (!account.isOptionSet(Account.OPTION_DISABLED)) {
xmppConnectionService.reconnectAccount(account, false);
}
}

View file

@ -9,6 +9,9 @@ import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.ui.adapter.ConversationAdapter;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
import android.app.PendingIntent;
import android.content.Intent;
import android.net.Uri;
@ -150,13 +153,23 @@ public class ShareWithActivity extends XmppActivity {
}
private void share() {
Account account = xmppConnectionService.findAccountByJid(share.account);
if (account == null) {
Account account;
try {
account = xmppConnectionService.findAccountByJid(Jid.fromString(share.account));
} catch (final InvalidJidException e) {
account = null;
}
if (account == null) {
return;
}
Conversation conversation = xmppConnectionService
.findOrCreateConversation(account, share.contact, false);
share(conversation);
final Conversation conversation;
try {
conversation = xmppConnectionService
.findOrCreateConversation(account, Jid.fromString(share.contact), false);
} catch (final InvalidJidException e) {
return;
}
share(conversation);
}
private void share(final Conversation conversation) {

View file

@ -63,6 +63,8 @@ import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate;
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
import eu.siacs.conversations.ui.adapter.ListItemAdapter;
import eu.siacs.conversations.utils.Validator;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
public class StartConversationActivity extends XmppActivity {
@ -71,7 +73,7 @@ public class StartConversationActivity extends XmppActivity {
private ViewPager mViewPager;
private MyListFragment mContactsListFragment = new MyListFragment();
private List<ListItem> contacts = new ArrayList<ListItem>();
private List<ListItem> contacts = new ArrayList<>();
private ArrayAdapter<ListItem> mContactsAdapter;
private MyListFragment mConferenceListFragment = new MyListFragment();
@ -359,17 +361,26 @@ public class StartConversationActivity extends XmppActivity {
return;
}
if (Validator.isValidJid(jid.getText().toString())) {
String accountJid = (String) spinner
.getSelectedItem();
String contactJid = jid.getText().toString();
Account account = xmppConnectionService
final Jid accountJid;
try {
accountJid = Jid.fromString((String) spinner
.getSelectedItem());
} catch (final InvalidJidException e) {
return;
}
final Jid contactJid;
try {
contactJid = Jid.fromString(jid.getText().toString());
} catch (final InvalidJidException e) {
return;
}
Account account = xmppConnectionService
.findAccountByJid(accountJid);
if (account == null) {
dialog.dismiss();
return;
}
Contact contact = account.getRoster().getContact(
contactJid);
Contact contact = account.getRoster().getContact(contactJid);
if (contact.showInRoster()) {
jid.setError(getString(R.string.contact_already_exists));
} else {
@ -416,10 +427,19 @@ public class StartConversationActivity extends XmppActivity {
return;
}
if (Validator.isValidJid(jid.getText().toString())) {
String accountJid = (String) spinner
.getSelectedItem();
String conferenceJid = jid.getText().toString();
Account account = xmppConnectionService
final Jid accountJid;
try {
accountJid = Jid.fromString((String) spinner.getSelectedItem());
} catch (final InvalidJidException e) {
return;
}
final Jid conferenceJid;
try {
conferenceJid = Jid.fromString(jid.getText().toString());
} catch (final InvalidJidException e) {
return; // TODO: Do some error handling...
}
Account account = xmppConnectionService
.findAccountByJid(accountJid);
if (account == null) {
dialog.dismiss();
@ -471,7 +491,7 @@ public class StartConversationActivity extends XmppActivity {
}
private void populateAccountSpinner(Spinner spinner) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_item, mActivatedAccounts);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
@ -554,7 +574,7 @@ public class StartConversationActivity extends XmppActivity {
this.mActivatedAccounts.clear();
for (Account account : xmppConnectionService.getAccounts()) {
if (account.getStatus() != Account.STATUS_DISABLED) {
this.mActivatedAccounts.add(account.getJid());
this.mActivatedAccounts.add(account.getJid().toString());
}
}
this.mKnownHosts = xmppConnectionService.getKnownHosts();
@ -779,7 +799,7 @@ public class StartConversationActivity extends XmppActivity {
// sample: imto://xmpp/jid@foo.com
try {
jid = URLDecoder.decode(uri.getEncodedPath(), "UTF-8").split("/")[1];
} catch (UnsupportedEncodingException e) {
} catch (final UnsupportedEncodingException ignored) {
}
}
}

View file

@ -65,6 +65,7 @@ import eu.siacs.conversations.services.AvatarService;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinder;
import eu.siacs.conversations.utils.ExceptionHelper;
import eu.siacs.conversations.xmpp.jid.Jid;
public abstract class XmppActivity extends Activity {
@ -275,14 +276,14 @@ public abstract class XmppActivity extends Activity {
public void switchToContactDetails(Contact contact) {
Intent intent = new Intent(this, ContactDetailsActivity.class);
intent.setAction(ContactDetailsActivity.ACTION_VIEW_CONTACT);
intent.putExtra("account", contact.getAccount().getJid());
intent.putExtra("contact", contact.getJid());
intent.putExtra("account", contact.getAccount().getJid().toString());
intent.putExtra("contact", contact.getJid().toString());
startActivity(intent);
}
public void switchToAccount(Account account) {
Intent intent = new Intent(this, EditAccountActivity.class);
intent.putExtra("jid", account.getJid());
intent.putExtra("jid", account.getJid().toString());
startActivity(intent);
}
@ -303,7 +304,7 @@ public abstract class XmppActivity extends Activity {
try {
startIntentSenderForResult(pi.getIntentSender(),
REQUEST_ANNOUNCE_PGP, null, 0, 0, 0);
} catch (SendIntentException e) {
} catch (final SendIntentException ignored) {
}
}
@ -347,9 +348,9 @@ public abstract class XmppActivity extends Activity {
}
protected void showAddToRosterDialog(final Conversation conversation) {
String jid = conversation.getContactJid();
final Jid jid = conversation.getContactJid();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(jid);
builder.setTitle(jid.toString());
builder.setMessage(getString(R.string.not_in_roster));
builder.setNegativeButton(getString(R.string.cancel), null);
builder.setPositiveButton(getString(R.string.add_contact),
@ -357,7 +358,7 @@ public abstract class XmppActivity extends Activity {
@Override
public void onClick(DialogInterface dialog, int which) {
String jid = conversation.getContactJid();
final Jid jid = conversation.getContactJid();
Account account = conversation.getAccount();
Contact contact = account.getRoster().getContact(jid);
xmppConnectionService.createContact(contact);
@ -369,7 +370,7 @@ public abstract class XmppActivity extends Activity {
private void showAskForPresenceDialog(final Contact contact) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(contact.getJid());
builder.setTitle(contact.getJid().toString());
builder.setMessage(R.string.request_presence_updates);
builder.setNegativeButton(R.string.cancel, null);
builder.setPositiveButton(R.string.request_now,
@ -391,7 +392,7 @@ public abstract class XmppActivity extends Activity {
private void warnMutalPresenceSubscription(final Conversation conversation,
final OnPresenceSelected listener) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(conversation.getContact().getJid());
builder.setTitle(conversation.getContact().getJid().toString());
builder.setMessage(R.string.without_mutual_presence_updates);
builder.setNegativeButton(R.string.cancel, null);
builder.setPositiveButton(R.string.ignore, new OnClickListener() {
@ -567,11 +568,10 @@ public abstract class XmppActivity extends Activity {
nfcAdapter.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() {
@Override
public NdefMessage createNdefMessage(NfcEvent nfcEvent) {
NdefMessage msg = new NdefMessage(new NdefRecord[]{
NdefRecord.createUri(getShareableUri()),
NdefRecord.createApplicationRecord("eu.siacs.conversations")
});
return msg;
return new NdefMessage(new NdefRecord[]{
NdefRecord.createUri(getShareableUri()),
NdefRecord.createApplicationRecord("eu.siacs.conversations")
});
}
}, this);
}
@ -620,7 +620,7 @@ public abstract class XmppActivity extends Activity {
protected Bitmap createQrCodeBitmap(String input, int size) {
try {
final QRCodeWriter QR_CODE_WRITER = new QRCodeWriter();
final Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
final Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
final BitMatrix result = QR_CODE_WRITER.encode(input, BarcodeFormat.QR_CODE, size, size, hints);
final int width = result.getWidth();
@ -649,7 +649,7 @@ public abstract class XmppActivity extends Activity {
private Message message = null;
public BitmapWorkerTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
imageViewReference = new WeakReference<>(imageView);
}
@Override
@ -665,7 +665,7 @@ public abstract class XmppActivity extends Activity {
@Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
if (bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
@ -695,9 +695,8 @@ public abstract class XmppActivity extends Activity {
imageView.setImageDrawable(asyncDrawable);
try {
task.execute(message);
} catch (RejectedExecutionException e) {
return;
}
} catch (final RejectedExecutionException ignored) {
}
}
}
}
@ -734,7 +733,7 @@ public abstract class XmppActivity extends Activity {
public AsyncDrawable(Resources res, Bitmap bitmap,
BitmapWorkerTask bitmapWorkerTask) {
super(res, bitmap);
bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(
bitmapWorkerTaskReference = new WeakReference<>(
bitmapWorkerTask);
}

View file

@ -31,7 +31,7 @@ public class AccountAdapter extends ArrayAdapter<Account> {
view = inflater.inflate(R.layout.account_row, parent, false);
}
TextView jid = (TextView) view.findViewById(R.id.account_jid);
jid.setText(account.getJid());
jid.setText(account.getJid().toString());
TextView statusView = (TextView) view.findViewById(R.id.account_status);
ImageView imageView = (ImageView) view.findViewById(R.id.account_image);
imageView.setImageBitmap(activity.avatarService().get(account,

View file

@ -58,7 +58,7 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
|| activity.useSubjectToIdentifyConference()) {
convName.setText(conversation.getName());
} else {
convName.setText(conversation.getContactJid().split("/")[0]);
convName.setText(conversation.getContactJid().toBareJid().toString());
}
TextView mLastMessage = (TextView) view
.findViewById(R.id.conversation_lastmsg);

View file

@ -34,7 +34,7 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
TextView jid = (TextView) view.findViewById(R.id.contact_jid);
ImageView picture = (ImageView) view.findViewById(R.id.contact_photo);
jid.setText(item.getJid());
jid.setText(item.getJid().toString());
name.setText(item.getDisplayName());
picture.setImageBitmap(activity.avatarService().get(item,
activity.getPixel(48)));

View file

@ -29,6 +29,7 @@ import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.entities.Message.ImageParams;
import eu.siacs.conversations.ui.ConversationActivity;
import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.jid.Jid;
public class MessageAdapter extends ArrayAdapter<Message> {
@ -136,9 +137,13 @@ public class MessageAdapter extends ArrayAdapter<Message> {
info = contact.getDisplayName();
} else {
if (message.getPresence() != null) {
info = message.getPresence();
if (message.getPresence().isBareJid()) {
info = message.getPresence().toString();
} else {
info = message.getPresence().getResourcepart();
}
} else {
info = message.getCounterpart();
info = message.getCounterpart().toString();
}
}
}
@ -227,14 +232,13 @@ public class MessageAdapter extends ArrayAdapter<Message> {
privateMarker = activity
.getString(R.string.private_message);
} else {
String to;
final Jid to;
if (message.getPresence() != null) {
to = message.getPresence();
} else {
to = message.getCounterpart();
}
privateMarker = activity.getString(
R.string.private_message_to, to);
privateMarker = activity.getString(R.string.private_message_to, to);
}
SpannableString span = new SpannableString(privateMarker + " "
+ message.getBody());
@ -413,17 +417,16 @@ public class MessageAdapter extends ArrayAdapter<Message> {
if (contact != null) {
viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(contact, activity.getPixel(48)));
} else if (item.getConversation().getMode() == Conversation.MODE_MULTI) {
String name = item.getPresence();
if (name == null) {
name = item.getCounterpart();
}
viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(name, activity.getPixel(48)));
final Jid name = item.getPresence() != null ? item.getPresence() : item.getCounterpart();
viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(
name.isBareJid() ? name.toString() : name.getResourcepart(),
activity.getPixel(48)));
}
} else if (type == SENT) {
viewHolder.contact_picture.setImageBitmap(activity.avatarService().get(item.getConversation().getAccount(), activity.getPixel(48)));
}
if (viewHolder.contact_picture != null) {
if (viewHolder != null && viewHolder.contact_picture != null) {
viewHolder.contact_picture
.setOnClickListener(new OnClickListener() {
@ -488,14 +491,16 @@ public class MessageAdapter extends ArrayAdapter<Message> {
} else {
displayInfoMessage(viewHolder,
R.string.install_openkeychain);
viewHolder.message_box
.setOnClickListener(new OnClickListener() {
if (viewHolder != null) {
viewHolder.message_box
.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
activity.showInstallPgpDialog();
}
});
@Override
public void onClick(View v) {
activity.showInstallPgpDialog();
}
});
}
}
} else if (item.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
displayDecryptionFailed(viewHolder);

View file

@ -11,6 +11,7 @@ import de.measite.minidns.record.AAAA;
import de.measite.minidns.record.Data;
import de.measite.minidns.util.NameUtil;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.xmpp.jid.Jid;
import java.io.IOException;
import java.net.InetAddress;
@ -26,7 +27,8 @@ import android.util.Log;
public class DNSHelper {
protected static Client client = new Client();
public static Bundle getSRVRecord(String host) throws IOException {
public static Bundle getSRVRecord(final Jid jid) throws IOException {
final String host = jid.getDomainpart();
String dns[] = client.findDNS();
if (dns != null) {
@ -62,9 +64,9 @@ public class DNSHelper {
// a random order respecting the weight, and dump that priority by
// priority
TreeMap<Integer, ArrayList<SRV>> priorities = new TreeMap<Integer, ArrayList<SRV>>();
TreeMap<String, ArrayList<String>> ips4 = new TreeMap<String, ArrayList<String>>();
TreeMap<String, ArrayList<String>> ips6 = new TreeMap<String, ArrayList<String>>();
TreeMap<Integer, ArrayList<SRV>> priorities = new TreeMap<>();
TreeMap<String, ArrayList<String>> ips4 = new TreeMap<>();
TreeMap<String, ArrayList<String>> ips6 = new TreeMap<>();
for (Record[] rrset : new Record[][] { message.getAnswers(),
message.getAdditionalResourceRecords() }) {
@ -97,7 +99,7 @@ public class DNSHelper {
}
Random rnd = new Random();
ArrayList<SRV> result = new ArrayList<SRV>(
ArrayList<SRV> result = new ArrayList<>(
priorities.size() * 2 + 1);
for (ArrayList<SRV> s : priorities.values()) {
@ -136,7 +138,7 @@ public class DNSHelper {
bundle.putString("error", "nosrv");
return bundle;
}
ArrayList<Bundle> values = new ArrayList<Bundle>();
ArrayList<Bundle> values = new ArrayList<>();
for (SRV srv : result) {
Bundle namePort = new Bundle();
namePort.putString("name", srv.getName());

View file

@ -13,6 +13,9 @@ import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
@ -89,10 +92,13 @@ public class ExceptionHelper {
Log.d(Config.LOGTAG, "using account="
+ finalAccount.getJid()
+ " to send in stack trace");
Conversation conversation = service
.findOrCreateConversation(finalAccount,
"bugs@siacs.eu", false);
Message message = new Message(conversation, report
Conversation conversation = null;
try {
conversation = service.findOrCreateConversation(finalAccount,
Jid.fromString("bugs@siacs.eu"), false);
} catch (final InvalidJidException ignored) {
}
Message message = new Message(conversation, report
.toString(), Message.ENCRYPTION_NONE);
service.sendMessage(message);
}
@ -103,15 +109,12 @@ public class ExceptionHelper {
@Override
public void onClick(DialogInterface dialog, int which) {
preferences.edit().putBoolean("never_send", true)
.commit();
.apply();
}
});
builder.create().show();
} catch (FileNotFoundException e) {
return;
} catch (IOException e) {
return;
}
} catch (final IOException ignored) {
}
}
}

View file

@ -110,7 +110,7 @@ public class UIHelper {
List<Account> accounts) {
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
List<Account> accountsWproblems = new ArrayList<Account>();
List<Account> accountsWproblems = new ArrayList<>();
for (Account account : accounts) {
if (account.hasErrorStatus()) {
accountsWproblems.add(account);
@ -124,7 +124,7 @@ public class UIHelper {
} else if (accountsWproblems.size() == 1) {
mBuilder.setContentTitle(context
.getString(R.string.problem_connecting_to_account));
mBuilder.setContentText(accountsWproblems.get(0).getJid());
mBuilder.setContentText(accountsWproblems.get(0).getJid().toString());
} else {
mBuilder.setContentTitle(context
.getString(R.string.problem_connecting_to_accounts));
@ -165,7 +165,7 @@ public class UIHelper {
TextView yourprint = (TextView) view
.findViewById(R.id.verify_otr_yourprint);
jid.setText(contact.getJid());
jid.setText(contact.getJid().toString());
fingerprint.setText(conversation.getOtrFingerprint());
yourprint.setText(account.getOtrFingerprint());
builder.setNegativeButton("Cancel", null);

View file

@ -5,12 +5,14 @@ import java.util.Hashtable;
import java.util.List;
import eu.siacs.conversations.utils.XmlHelper;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
public class Element {
protected String name;
protected Hashtable<String, String> attributes = new Hashtable<String, String>();
protected Hashtable<String, String> attributes = new Hashtable<>();
protected String content;
protected List<Element> children = new ArrayList<Element>();
protected List<Element> children = new ArrayList<>();
public Element(String name) {
this.name = name;
@ -103,6 +105,42 @@ public class Element {
}
}
public Jid getJid() {
final String jid = this.getAttribute("jid");
if (jid != null && !jid.isEmpty()) {
try {
return Jid.fromString(jid);
} catch (final InvalidJidException e) {
return null;
}
}
return null;
}
public Jid getTo() {
final String to = this.getAttribute("to");
if (to != null && !to.isEmpty()) {
try {
return Jid.fromString(to);
} catch (final InvalidJidException e) {
return null;
}
}
return null;
}
public Jid getFrom() {
final String from = this.getAttribute("from");
if (from != null && !from.isEmpty()) {
try {
return Jid.fromString(from);
} catch (final InvalidJidException e) {
return null;
}
}
return null;
}
public Hashtable<String, String> getAttributes() {
return this.attributes;
}

View file

@ -18,6 +18,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.IDN;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
@ -48,6 +49,8 @@ import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xml.Tag;
import eu.siacs.conversations.xml.TagWriter;
import eu.siacs.conversations.xml.XmlReader;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.jingle.OnJinglePacketReceived;
import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket;
import eu.siacs.conversations.xmpp.stanzas.AbstractStanza;
@ -76,10 +79,12 @@ public class XmppConnection implements Runnable {
private boolean shouldBind = true;
private boolean shouldAuthenticate = true;
private Element streamFeatures;
private HashMap<String, List<String>> disco = new HashMap<String, List<String>>();
private HashMap<String, List<String>> disco = new HashMap<>();
private String streamId = null;
private int smVersion = 3;
private SparseArray<String> messageReceipts = new SparseArray<String>();
private SparseArray<String> messageReceipts = new SparseArray<>();
private boolean usingCompression = false;
private boolean usingEncryption = false;
private int stanzasReceived = 0;
@ -89,7 +94,7 @@ public class XmppConnection implements Runnable {
private long lastConnect = 0;
private long lastSessionStarted = 0;
private int attempt = 0;
private Hashtable<String, PacketReceived> packetCallbacks = new Hashtable<String, PacketReceived>();
private Hashtable<String, PacketReceived> packetCallbacks = new Hashtable<>();
private OnPresencePacketReceived presenceListener = null;
private OnJinglePacketReceived jingleListener = null;
private OnIqPacketReceived unregisteredIqListener = null;
@ -102,7 +107,7 @@ public class XmppConnection implements Runnable {
public XmppConnection(Account account, XmppConnectionService service) {
this.account = account;
this.wakeLock = service.getPowerManager().newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, account.getJid());
PowerManager.PARTIAL_WAKE_LOCK, account.getJid().toString());
tagWriter = new TagWriter();
mXmppConnectionService = service;
applicationContext = service.getApplicationContext();
@ -127,7 +132,7 @@ public class XmppConnection implements Runnable {
}
protected void connect() {
Log.d(Config.LOGTAG, account.getJid() + ": connecting");
Log.d(Config.LOGTAG, account.getJid().toString() + ": connecting");
usingCompression = false;
usingEncryption = false;
lastConnect = SystemClock.elapsedRealtime();
@ -143,7 +148,7 @@ public class XmppConnection implements Runnable {
Bundle result = DNSHelper.getSRVRecord(account.getServer());
ArrayList<Parcelable> values = result.getParcelableArrayList("values");
if ("timeout".equals(result.getString("error"))) {
Log.d(Config.LOGTAG, account.getJid() + ": dns timeout");
Log.d(Config.LOGTAG, account.getJid().toString() + ": dns timeout");
this.changeStatus(Account.STATUS_OFFLINE);
return;
} else if (values != null) {
@ -152,18 +157,24 @@ public class XmppConnection implements Runnable {
while (socketError && values.size() > i) {
Bundle namePort = (Bundle) values.get(i);
try {
String srvRecordServer = namePort.getString("name");
String srvRecordServer;
try {
srvRecordServer=IDN.toASCII(namePort.getString("name"));
} catch (final IllegalArgumentException e) {
// TODO: Handle me?`
srvRecordServer = "";
}
int srvRecordPort = namePort.getInt("port");
String srvIpServer = namePort.getString("ipv4");
InetSocketAddress addr;
if (srvIpServer != null) {
addr = new InetSocketAddress(srvIpServer, srvRecordPort);
Log.d(Config.LOGTAG, account.getJid()
Log.d(Config.LOGTAG, account.getJid().toString()
+ ": using values from dns " + srvRecordServer
+ "[" + srvIpServer + "]:" + srvRecordPort);
} else {
addr = new InetSocketAddress(srvRecordServer, srvRecordPort);
Log.d(Config.LOGTAG, account.getJid()
Log.d(Config.LOGTAG, account.getJid().toString()
+ ": using values from dns "
+ srvRecordServer + ":" + srvRecordPort);
}
@ -171,10 +182,10 @@ public class XmppConnection implements Runnable {
socket.connect(addr, 20000);
socketError = false;
} catch (UnknownHostException e) {
Log.d(Config.LOGTAG, account.getJid() + ": " + e.getMessage());
Log.d(Config.LOGTAG, account.getJid().toString() + ": " + e.getMessage());
i++;
} catch (IOException e) {
Log.d(Config.LOGTAG, account.getJid() + ": " + e.getMessage());
Log.d(Config.LOGTAG, account.getJid().toString() + ": " + e.getMessage());
i++;
}
}
@ -183,16 +194,16 @@ public class XmppConnection implements Runnable {
if (wakeLock.isHeld()) {
try {
wakeLock.release();
} catch (RuntimeException re) {
} catch (final RuntimeException ignored) {
}
}
return;
}
} else if (result.containsKey("error")
&& "nosrv".equals(result.getString("error", null))) {
socket = new Socket(account.getServer(), 5222);
socket = new Socket(account.getServer().getDomainpart(), 5222);
} else {
Log.d(Config.LOGTAG, account.getJid()
Log.d(Config.LOGTAG, account.getJid().toString()
+ ": timeout in DNS resolution");
changeStatus(Account.STATUS_OFFLINE);
return;
@ -222,51 +233,38 @@ public class XmppConnection implements Runnable {
if (wakeLock.isHeld()) {
try {
wakeLock.release();
} catch (RuntimeException re) {
} catch (final RuntimeException ignored) {
}
}
return;
} catch (IOException e) {
Log.d(Config.LOGTAG, account.getJid() + ": " + e.getMessage());
} catch (final IOException | XmlPullParserException e) {
Log.d(Config.LOGTAG, account.getJid().toString() + ": " + e.getMessage());
this.changeStatus(Account.STATUS_OFFLINE);
if (wakeLock.isHeld()) {
try {
wakeLock.release();
} catch (RuntimeException re) {
} catch (final RuntimeException ignored) {
}
}
return;
} catch (NoSuchAlgorithmException e) {
Log.d(Config.LOGTAG, account.getJid() + ": " + e.getMessage());
} catch (NoSuchAlgorithmException e) {
Log.d(Config.LOGTAG, account.getJid().toString() + ": " + e.getMessage());
this.changeStatus(Account.STATUS_OFFLINE);
Log.d(Config.LOGTAG, "compression exception " + e.getMessage());
if (wakeLock.isHeld()) {
try {
wakeLock.release();
} catch (RuntimeException re) {
} catch (final RuntimeException ignored) {
}
}
return;
} catch (XmlPullParserException e) {
Log.d(Config.LOGTAG, account.getJid() + ": " + e.getMessage());
this.changeStatus(Account.STATUS_OFFLINE);
if (wakeLock.isHeld()) {
try {
wakeLock.release();
} catch (RuntimeException re) {
}
}
return;
}
}
}
}
@Override
public void run() {
connect();
}
private void processStream(Tag currentTag) throws XmlPullParserException,
private void processStream(final Tag currentTag) throws XmlPullParserException,
IOException, NoSuchAlgorithmException {
Tag nextTag = tagReader.readTag();
while ((nextTag != null) && (!nextTag.isEnd("stream"))) {
@ -279,7 +277,7 @@ public class XmppConnection implements Runnable {
} else if (nextTag.isStart("compressed")) {
switchOverToZLib(nextTag);
} else if (nextTag.isStart("success")) {
Log.d(Config.LOGTAG, account.getJid() + ": logged in");
Log.d(Config.LOGTAG, account.getJid().toString() + ": logged in");
tagReader.readTag();
tagReader.reset();
sendStartStream();
@ -300,11 +298,11 @@ public class XmppConnection implements Runnable {
Element enabled = tagReader.readElement(nextTag);
if ("true".equals(enabled.getAttribute("resume"))) {
this.streamId = enabled.getAttribute("id");
Log.d(Config.LOGTAG, account.getJid()
Log.d(Config.LOGTAG, account.getJid().toString()
+ ": stream managment(" + smVersion
+ ") enabled (resumable)");
} else {
Log.d(Config.LOGTAG, account.getJid()
Log.d(Config.LOGTAG, account.getJid().toString()
+ ": stream managment(" + smVersion + ") enabled");
}
this.lastSessionStarted = SystemClock.elapsedRealtime();
@ -318,11 +316,11 @@ public class XmppConnection implements Runnable {
try {
int serverCount = Integer.parseInt(h);
if (serverCount != stanzasSent) {
Log.d(Config.LOGTAG, account.getJid()
Log.d(Config.LOGTAG, account.getJid().toString()
+ ": session resumed with lost packages");
stanzasSent = serverCount;
} else {
Log.d(Config.LOGTAG, account.getJid()
Log.d(Config.LOGTAG, account.getJid().toString()
+ ": session resumed");
}
if (acknowledgedListener != null) {
@ -334,7 +332,7 @@ public class XmppConnection implements Runnable {
}
}
messageReceipts.clear();
} catch (NumberFormatException e) {
} catch (final NumberFormatException ignored) {
}
sendInitialPing();
@ -357,7 +355,7 @@ public class XmppConnection implements Runnable {
}
} else if (nextTag.isStart("failed")) {
tagReader.readElement(nextTag);
Log.d(Config.LOGTAG, account.getJid() + ": resumption failed");
Log.d(Config.LOGTAG, account.getJid().toString() + ": resumption failed");
streamId = null;
if (account.getStatus() != Account.STATUS_ONLINE) {
sendBindRequest();
@ -372,7 +370,7 @@ public class XmppConnection implements Runnable {
nextTag = tagReader.readTag();
}
if (account.getStatus() == Account.STATUS_ONLINE) {
account.setStatus(Account.STATUS_OFFLINE);
account. setStatus(Account.STATUS_OFFLINE);
if (statusListener != null) {
statusListener.onStatusChanged(account);
}
@ -380,7 +378,7 @@ public class XmppConnection implements Runnable {
}
private void sendInitialPing() {
Log.d(Config.LOGTAG, account.getJid() + ": sending intial ping");
Log.d(Config.LOGTAG, account.getJid().toString() + ": sending intial ping");
IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
iq.setFrom(account.getFullJid());
iq.addChild("ping", "urn:xmpp:ping");
@ -388,7 +386,7 @@ public class XmppConnection implements Runnable {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
Log.d(Config.LOGTAG, account.getJid()
Log.d(Config.LOGTAG, account.getJid().toString()
+ ": online with resource " + account.getResource());
changeStatus(Account.STATUS_ONLINE);
}
@ -507,7 +505,7 @@ public class XmppConnection implements Runnable {
tagWriter.writeElement(compress);
}
private void switchOverToZLib(Tag currentTag)
private void switchOverToZLib(final Tag currentTag)
throws XmlPullParserException, IOException,
NoSuchAlgorithmException {
tagReader.readTag(); // read tag close
@ -537,7 +535,7 @@ public class XmppConnection implements Runnable {
return getPreferences().getBoolean("enable_legacy_ssl", false);
}
private void switchOverToTls(Tag currentTag) throws XmlPullParserException,
private void switchOverToTls(final Tag currentTag) throws XmlPullParserException,
IOException {
tagReader.readTag();
try {
@ -551,24 +549,23 @@ public class XmppConnection implements Runnable {
throw new IOException("SSLSocketFactory was null");
}
HostnameVerifier verifier = this.mXmppConnectionService.getMemorizingTrustManager().wrapHostnameVerifier(new StrictHostnameVerifier());
final HostnameVerifier verifier = this.mXmppConnectionService.getMemorizingTrustManager().wrapHostnameVerifier(new StrictHostnameVerifier());
if (socket == null) {
throw new IOException("socket was null");
}
SSLSocket sslSocket = (SSLSocket) factory.createSocket(socket,
final SSLSocket sslSocket = (SSLSocket) factory.createSocket(socket,
socket.getInetAddress().getHostAddress(), socket.getPort(),
true);
// Support all protocols except legacy SSL.
// The min SDK version prevents us having to worry about SSLv2. In
// future, this may be
// true of SSLv3 as well.
// future, this may be true of SSLv3 as well.
final String[] supportProtocols;
if (enableLegacySSL()) {
supportProtocols = sslSocket.getSupportedProtocols();
} else {
final List<String> supportedProtocols = new LinkedList<String>(
final List<String> supportedProtocols = new LinkedList<>(
Arrays.asList(sslSocket.getSupportedProtocols()));
supportedProtocols.remove("SSLv3");
supportProtocols = new String[supportedProtocols.size()];
@ -577,7 +574,7 @@ public class XmppConnection implements Runnable {
sslSocket.setEnabledProtocols(supportProtocols);
if (verifier != null
&& !verifier.verify(account.getServer(),
&& !verifier.verify(account.getServer().getDomainpart(),
sslSocket.getSession())) {
sslSocket.close();
throw new IOException("host mismatch in TLS connection");
@ -590,12 +587,10 @@ public class XmppConnection implements Runnable {
usingEncryption = true;
processStream(tagReader.readTag());
sslSocket.close();
} catch (NoSuchAlgorithmException e1) {
} catch (final NoSuchAlgorithmException | KeyManagementException e1) {
e1.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
}
private void sendSaslAuthPlain() throws IOException {
String saslString = CryptoHelper.saslPlain(account.getUsername(),
@ -676,7 +671,7 @@ public class XmppConnection implements Runnable {
}
private List<String> extractMechanisms(Element stream) {
ArrayList<String> mechanisms = new ArrayList<String>(stream
ArrayList<String> mechanisms = new ArrayList<>(stream
.getChildren().size());
for (Element child : stream.getChildren()) {
mechanisms.add(child.getContent());
@ -742,10 +737,14 @@ public class XmppConnection implements Runnable {
public void onIqPacketReceived(Account account, IqPacket packet) {
Element bind = packet.findChild("bind");
if (bind != null) {
Element jid = bind.findChild("jid");
final Element jid = bind.findChild("jid");
if (jid != null && jid.getContent() != null) {
account.setResource(jid.getContent().split("/", 2)[1]);
if (streamFeatures.hasChild("sm", "urn:xmpp:sm:3")) {
try {
account.setResource(Jid.fromString(jid.getContent()).getResourcepart());
} catch (final InvalidJidException e) {
// TODO: Handle the case where an external JID is technically invalid?
}
if (streamFeatures.hasChild("sm", "urn:xmpp:sm:3")) {
smVersion = 3;
EnablePacket enable = new EnablePacket(smVersion);
tagWriter.writeStanzaAsync(enable);
@ -783,24 +782,24 @@ public class XmppConnection implements Runnable {
}
}
private void sendServiceDiscoveryInfo(final String server) {
IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
iq.setTo(server);
private void sendServiceDiscoveryInfo(final Jid server) {
final IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
iq.setTo(server.toDomainJid());
iq.query("http://jabber.org/protocol/disco#info");
this.sendIqPacket(iq, new OnIqPacketReceived() {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
List<Element> elements = packet.query().getChildren();
List<String> features = new ArrayList<String>();
for (int i = 0; i < elements.size(); ++i) {
if (elements.get(i).getName().equals("feature")) {
features.add(elements.get(i).getAttribute("var"));
}
}
disco.put(server, features);
final List<Element> elements = packet.query().getChildren();
final List<String> features = new ArrayList<>();
for (Element element : elements) {
if (element.getName().equals("feature")) {
features.add(element.getAttribute("var"));
}
}
disco.put(server.toDomainJid().toString(), features);
if (account.getServer().equals(server)) {
if (account.getServer().equals(server.toDomainJid())) {
enableAdvancedStreamFeatures();
}
}
@ -813,21 +812,25 @@ public class XmppConnection implements Runnable {
}
}
private void sendServiceDiscoveryItems(final String server) {
IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
iq.setTo(server);
private void sendServiceDiscoveryItems(final Jid server) {
final IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
iq.setTo(server.toDomainJid());
iq.query("http://jabber.org/protocol/disco#items");
this.sendIqPacket(iq, new OnIqPacketReceived() {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
List<Element> elements = packet.query().getChildren();
for (int i = 0; i < elements.size(); ++i) {
if (elements.get(i).getName().equals("item")) {
String jid = elements.get(i).getAttribute("jid");
sendServiceDiscoveryInfo(jid);
}
}
for (Element element : elements) {
if (element.getName().equals("item")) {
final String jid = element.getAttribute("jid");
try {
sendServiceDiscoveryInfo(Jid.fromString(jid).toDomainJid());
} catch (final InvalidJidException ignored) {
// TODO: Handle the case where an external JID is technically invalid?
}
}
}
}
});
}
@ -854,9 +857,9 @@ public class XmppConnection implements Runnable {
throws XmlPullParserException, IOException {
Element streamError = tagReader.readElement(currentTag);
if (streamError != null && streamError.hasChild("conflict")) {
String resource = account.getResource().split("\\.")[0];
account.setResource(resource + "." + nextRandomId());
Log.d(Config.LOGTAG,
final String resource = account.getResource().split("\\.")[0];
account.setResource(resource + "." + nextRandomId());
Log.d(Config.LOGTAG,
account.getJid() + ": switching resource due to conflict ("
+ account.getResource() + ")");
}
@ -864,8 +867,8 @@ public class XmppConnection implements Runnable {
private void sendStartStream() throws IOException {
Tag stream = Tag.start("stream:stream");
stream.setAttribute("from", account.getJid());
stream.setAttribute("to", account.getServer());
stream.setAttribute("from", account.getJid().toString());
stream.setAttribute("to", account.getServer().toString());
stream.setAttribute("version", "1.0");
stream.setAttribute("xml:lang", "en");
stream.setAttribute("xmlns", "jabber:client");
@ -1003,7 +1006,7 @@ public class XmppConnection implements Runnable {
}
public List<String> findDiscoItemsByFeature(String feature) {
List<String> items = new ArrayList<String>();
final List<String> items = new ArrayList<>();
for (Entry<String, List<String>> cursor : disco.entrySet()) {
if (cursor.getValue().contains(feature)) {
items.add(cursor.getKey());
@ -1079,12 +1082,10 @@ public class XmppConnection implements Runnable {
this.connection = connection;
}
private boolean hasDiscoFeature(String server, String feature) {
if (!connection.disco.containsKey(server)) {
return false;
}
return connection.disco.get(server).contains(feature);
}
private boolean hasDiscoFeature(final Jid server, final String feature) {
return connection.disco.containsKey(server.toDomainJid().toString()) &&
connection.disco.get(server.toDomainJid().toString()).contains(feature);
}
public boolean carbons() {
return hasDiscoFeature(account.getServer(), "urn:xmpp:carbons:2");
@ -1095,12 +1096,7 @@ public class XmppConnection implements Runnable {
}
public boolean csi() {
if (connection.streamFeatures == null) {
return false;
} else {
return connection.streamFeatures.hasChild("csi",
"urn:xmpp:csi:0");
}
return connection.streamFeatures != null && connection.streamFeatures.hasChild("csi", "urn:xmpp:csi:0");
}
public boolean pubsub() {
@ -1113,11 +1109,7 @@ public class XmppConnection implements Runnable {
}
public boolean rosterVersioning() {
if (connection.streamFeatures == null) {
return false;
} else {
return connection.streamFeatures.hasChild("ver");
}
return connection.streamFeatures != null && connection.streamFeatures.hasChild("ver");
}
public boolean streamhost() {

View file

@ -0,0 +1,48 @@
package eu.siacs.conversations.xmpp.jid;
public class InvalidJidException extends Exception {
// This is probably not the "Java way", but the "Java way" means we'd have a ton of extra tiny,
// annoying classes floating around. I like this.
public final static String INVALID_LENGTH = "JID must be between 0 and 3071 characters";
public final static String INVALID_PART_LENGTH = "JID part must be between 0 and 1023 characters";
public final static String INVALID_CHARACTER = "JID contains an invalid character";
public final static String STRINGPREP_FAIL = "The STRINGPREP operation has failed for the given JID";
/**
* Constructs a new {@code Exception} that includes the current stack trace.
*/
public InvalidJidException() {
}
/**
* Constructs a new {@code Exception} with the current stack trace and the
* specified detail message.
*
* @param detailMessage the detail message for this exception.
*/
public InvalidJidException(final String detailMessage) {
super(detailMessage);
}
/**
* Constructs a new {@code Exception} with the current stack trace, the
* specified detail message and the specified cause.
*
* @param detailMessage the detail message for this exception.
* @param throwable the cause of this exception.
*/
public InvalidJidException(final String detailMessage, final Throwable throwable) {
super(detailMessage, throwable);
}
/**
* Constructs a new {@code Exception} with the current stack trace and the
* specified cause.
*
* @param throwable the cause of this exception.
*/
public InvalidJidException(final Throwable throwable) {
super(throwable);
}
}

View file

@ -0,0 +1,180 @@
package eu.siacs.conversations.xmpp.jid;
import java.net.IDN;
import gnu.inet.encoding.Stringprep;
import gnu.inet.encoding.StringprepException;
/**
* The `Jid' class provides an immutable representation of a JID.
*/
public final class Jid {
private final String localpart;
private final String domainpart;
private final String resourcepart;
// It's much more efficient to store the ful JID as well as the parts instead of figuring them
// all out every time (since some characters are displayed but aren't used for comparisons).
private final String displayjid;
public String getLocalpart() {
return localpart;
}
public String getDomainpart() {
return IDN.toUnicode(domainpart);
}
public String getResourcepart() {
return resourcepart;
}
public static Jid fromString(final String jid) throws InvalidJidException {
return new Jid(jid);
}
public static Jid fromParts(final String localpart,
final String domainpart,
final String resourcepart) throws InvalidJidException {
String out;
if (localpart == null || localpart.isEmpty()) {
out = domainpart;
} else {
out = localpart + "@" + domainpart;
}
if (resourcepart != null && !resourcepart.isEmpty()) {
out = out + "/" + resourcepart;
}
return new Jid(out);
}
private Jid(final String jid) throws InvalidJidException {
// Hackish Android way to count the number of chars in a string... should work everywhere.
final int atCount = jid.length() - jid.replace("@", "").length();
final int slashCount = jid.length() - jid.replace("/", "").length();
// Throw an error if there's anything obvious wrong with the JID...
if (jid.isEmpty() || jid.length() > 3071) {
throw new InvalidJidException(InvalidJidException.INVALID_LENGTH);
}
if (atCount > 1 || slashCount > 1 ||
jid.startsWith("@") || jid.endsWith("@") ||
jid.startsWith("/") || jid.endsWith("/")) {
throw new InvalidJidException(InvalidJidException.INVALID_CHARACTER);
}
String finaljid;
final int domainpartStart;
if (atCount == 1) {
final int atLoc = jid.indexOf("@");
final String lp = jid.substring(0, atLoc);
try {
localpart = Stringprep.nodeprep(lp);
} catch (final StringprepException e) {
throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e);
}
if (localpart.isEmpty() || localpart.length() > 1023) {
throw new InvalidJidException(InvalidJidException.INVALID_PART_LENGTH);
}
domainpartStart = atLoc + 1;
finaljid = lp + "@";
} else {
localpart = "";
finaljid = "";
domainpartStart = 0;
}
final String dp;
if (slashCount == 1) {
final int slashLoc = jid.indexOf("/");
final String rp = jid.substring(slashLoc + 1, jid.length());
try {
resourcepart = Stringprep.resourceprep(rp);
} catch (final StringprepException e) {
throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e);
}
if (resourcepart.isEmpty() || resourcepart.length() > 1023) {
throw new InvalidJidException(InvalidJidException.INVALID_PART_LENGTH);
}
dp = jid.substring(domainpartStart, slashLoc);
finaljid = finaljid + dp + "/" + rp;
} else {
resourcepart = "";
dp = jid.substring(domainpartStart, jid.length());
finaljid = finaljid + dp;
}
// Remove trailling "." before storing the domain part.
if (dp.endsWith(".")) {
try {
domainpart = IDN.toASCII(dp.substring(0, dp.length() - 1), IDN.USE_STD3_ASCII_RULES);
} catch (final IllegalArgumentException e) {
throw new InvalidJidException(e);
}
} else {
try {
domainpart = IDN.toASCII(dp, IDN.USE_STD3_ASCII_RULES);
} catch (final IllegalArgumentException e) {
throw new InvalidJidException(e);
}
}
// TODO: Find a proper domain validation library; validate individual parts, separators, etc.
if (domainpart.isEmpty() || domainpart.length() > 1023) {
throw new InvalidJidException(InvalidJidException.INVALID_PART_LENGTH);
}
this.displayjid = finaljid;
}
public Jid toBareJid() {
try {
return resourcepart.isEmpty() ? this : fromParts(localpart, domainpart, "");
} catch (final InvalidJidException e) {
// This should never happen.
return null;
}
}
public Jid toDomainJid() {
try {
return resourcepart.isEmpty() && localpart.isEmpty() ? this : fromString(getDomainpart());
} catch (final InvalidJidException e) {
// This should never happen.
return null;
}
}
@Override
public String toString() {
return displayjid;
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final Jid jid = (Jid) o;
return jid.hashCode() == this.hashCode();
}
@Override
public int hashCode() {
int result = localpart.hashCode();
result = 31 * result + domainpart.hashCode();
result = 31 * result + resourcepart.hashCode();
return result;
}
public boolean hasLocalpart() {
return !localpart.isEmpty();
}
public boolean isBareJid() {
return this.resourcepart.isEmpty();
}
}

View file

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.jid.Jid;
public class JingleCandidate {
@ -17,7 +18,7 @@ public class JingleCandidate {
private String host;
private int port;
private int type;
private String jid;
private Jid jid;
private int priority;
public JingleCandidate(String cid, boolean ours) {
@ -37,11 +38,11 @@ public class JingleCandidate {
return this.host;
}
public void setJid(String jid) {
public void setJid(final Jid jid) {
this.jid = jid;
}
public String getJid() {
public Jid getJid() {
return this.jid;
}
@ -58,13 +59,17 @@ public class JingleCandidate {
}
public void setType(String type) {
if ("proxy".equals(type)) {
this.type = TYPE_PROXY;
} else if ("direct".equals(type)) {
this.type = TYPE_DIRECT;
} else {
this.type = TYPE_UNKNOWN;
}
switch (type) {
case "proxy":
this.type = TYPE_PROXY;
break;
case "direct":
this.type = TYPE_DIRECT;
break;
default:
this.type = TYPE_UNKNOWN;
break;
}
}
public void setPriority(int i) {
@ -93,7 +98,7 @@ public class JingleCandidate {
}
public static List<JingleCandidate> parse(List<Element> canditates) {
List<JingleCandidate> parsedCandidates = new ArrayList<JingleCandidate>();
List<JingleCandidate> parsedCandidates = new ArrayList<>();
for (Element c : canditates) {
parsedCandidates.add(JingleCandidate.parse(c));
}
@ -104,7 +109,7 @@ public class JingleCandidate {
JingleCandidate parsedCandidate = new JingleCandidate(
candidate.getAttribute("cid"), false);
parsedCandidate.setHost(candidate.getAttribute("host"));
parsedCandidate.setJid(candidate.getAttribute("jid"));
parsedCandidate.setJid(candidate.getJid());
parsedCandidate.setType(candidate.getAttribute("type"));
parsedCandidate.setPriority(Integer.parseInt(candidate
.getAttribute("priority")));
@ -118,7 +123,7 @@ public class JingleCandidate {
element.setAttribute("cid", this.getCid());
element.setAttribute("host", this.getHost());
element.setAttribute("port", Integer.toString(this.getPort()));
element.setAttribute("jid", this.getJid());
element.setAttribute("jid", this.getJid().toString());
element.setAttribute("priority", Integer.toString(this.getPriority()));
if (this.getType() == TYPE_DIRECT) {
element.setAttribute("type", "direct");

View file

@ -21,6 +21,7 @@ import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.jingle.stanzas.Content;
import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket;
import eu.siacs.conversations.xmpp.jingle.stanzas.Reason;
@ -49,10 +50,10 @@ public class JingleConnection implements Downloadable {
private Message message;
private String sessionId;
private Account account;
private String initiator;
private String responder;
private List<JingleCandidate> candidates = new ArrayList<JingleCandidate>();
private ConcurrentHashMap<String, JingleSocks5Transport> connections = new ConcurrentHashMap<String, JingleSocks5Transport>();
private Jid initiator;
private Jid responder;
private List<JingleCandidate> candidates = new ArrayList<>();
private ConcurrentHashMap<String, JingleSocks5Transport> connections = new ConcurrentHashMap<>();
private String transportId;
private Element fileOffer;
@ -150,7 +151,7 @@ public class JingleConnection implements Downloadable {
return this.account;
}
public String getCounterPart() {
public Jid getCounterPart() {
return this.message.getCounterpart();
}
@ -254,14 +255,14 @@ public class JingleConnection implements Downloadable {
this.mJingleStatus = JINGLE_STATUS_INITIATED;
Conversation conversation = this.mXmppConnectionService
.findOrCreateConversation(account,
packet.getFrom().split("/", 2)[0], false);
packet.getFrom().toBareJid(), false);
this.message = new Message(conversation, "", Message.ENCRYPTION_NONE);
this.message.setStatus(Message.STATUS_RECEIVED);
this.message.setType(Message.TYPE_IMAGE);
this.mStatus = Downloadable.STATUS_OFFER;
this.message.setDownloadable(this);
String[] fromParts = packet.getFrom().split("/", 2);
this.message.setPresence(fromParts[1]);
final Jid from = packet.getFrom();
this.message.setPresence(from.isBareJid() ? "" : from.getResourcepart());
this.account = account;
this.initiator = packet.getFrom();
this.responder = this.account.getFullJid();
@ -375,7 +376,7 @@ public class JingleConnection implements Downloadable {
}
private List<Element> getCandidatesAsElements() {
List<Element> elements = new ArrayList<Element>();
List<Element> elements = new ArrayList<>();
for (JingleCandidate c : this.candidates) {
elements.add(c.toElement());
}
@ -547,7 +548,7 @@ public class JingleConnection implements Downloadable {
activation.query("http://jabber.org/protocol/bytestreams")
.setAttribute("sid", this.getSessionId());
activation.query().addChild("activate")
.setContent(this.getCounterPart());
.setContent(this.getCounterPart().toString());
this.account.getXmppConnection().sendIqPacket(activation,
new OnIqPacketReceived() {
@ -810,11 +811,11 @@ public class JingleConnection implements Downloadable {
this.sendJinglePacket(packet);
}
public String getInitiator() {
public Jid getInitiator() {
return this.initiator;
}
public String getResponder() {
public Jid getResponder() {
return this.responder;
}

View file

@ -14,13 +14,15 @@ import eu.siacs.conversations.services.AbstractConnectionManager;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.jingle.stanzas.JinglePacket;
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
public class JingleConnectionManager extends AbstractConnectionManager {
private List<JingleConnection> connections = new CopyOnWriteArrayList<JingleConnection>();
private List<JingleConnection> connections = new CopyOnWriteArrayList<>();
private HashMap<String, JingleCandidate> primaryCandidates = new HashMap<String, JingleCandidate>();
private HashMap<Jid, JingleCandidate> primaryCandidates = new HashMap<>();
@SuppressLint("TrulyRandom")
private SecureRandom random = new SecureRandom();
@ -61,7 +63,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
return connection;
}
public JingleConnection createNewConnection(JinglePacket packet) {
public JingleConnection createNewConnection(final JinglePacket packet) {
JingleConnection connection = new JingleConnection(this);
this.connections.add(connection);
return connection;
@ -79,7 +81,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
.findDiscoItemByFeature(xmlns);
if (proxy != null) {
IqPacket iq = new IqPacket(IqPacket.TYPE_GET);
iq.setTo(proxy);
iq.setAttribute("to", proxy);
iq.query(xmlns);
account.getXmppConnection().sendIqPacket(iq,
new OnIqPacketReceived() {
@ -101,8 +103,12 @@ public class JingleConnectionManager extends AbstractConnectionManager {
.getAttribute("port")));
candidate
.setType(JingleCandidate.TYPE_PROXY);
candidate.setJid(proxy);
candidate.setPriority(655360 + 65535);
try {
candidate.setJid(Jid.fromString(proxy));
} catch (final InvalidJidException e) {
candidate.setJid(null);
}
candidate.setPriority(655360 + 65535);
primaryCandidates.put(account.getJid(),
candidate);
listener.onPrimaryCandidateFound(true,

View file

@ -13,12 +13,13 @@ import eu.siacs.conversations.entities.DownloadableFile;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
public class JingleInbandTransport extends JingleTransport {
private Account account;
private String counterpart;
private Jid counterpart;
private int blockSize;
private int bufferSize;
private int seq = 0;
@ -44,8 +45,8 @@ public class JingleInbandTransport extends JingleTransport {
}
};
public JingleInbandTransport(Account account, String counterpart,
String sid, int blocksize) {
public JingleInbandTransport(final Account account, final Jid counterpart,
final String sid, final int blocksize) {
this.account = account;
this.counterpart = counterpart;
this.blockSize = blocksize;
@ -92,12 +93,10 @@ public class JingleInbandTransport extends JingleTransport {
return;
}
this.remainingSize = file.getExpectedSize();
} catch (NoSuchAlgorithmException e) {
callback.onFileTransferAborted();
} catch (IOException e) {
} catch (final NoSuchAlgorithmException | IOException e) {
callback.onFileTransferAborted();
}
}
}
@Override
public void send(DownloadableFile file,

View file

@ -1,6 +1,7 @@
package eu.siacs.conversations.xmpp.jingle.stanzas;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
public class JinglePacket extends IqPacket {
@ -85,8 +86,8 @@ public class JinglePacket extends IqPacket {
return this.jingle.getAttribute("action");
}
public void setInitiator(String initiator) {
this.jingle.setAttribute("initiator", initiator);
public void setInitiator(final Jid initiator) {
this.jingle.setAttribute("initiator", initiator.toString());
}
public boolean isAction(String action) {

View file

@ -1,6 +1,8 @@
package eu.siacs.conversations.xmpp.pep;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.jid.Jid;
import android.util.Base64;
public class Avatar {
@ -10,7 +12,7 @@ public class Avatar {
public int height;
public int width;
public long size;
public String owner;
public Jid owner;
public byte[] getImageAsBytes() {
return Base64.decode(image, Base64.DEFAULT);

View file

@ -1,6 +1,8 @@
package eu.siacs.conversations.xmpp.stanzas;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
import eu.siacs.conversations.xmpp.jid.Jid;
public class AbstractStanza extends Element {
@ -8,27 +10,35 @@ public class AbstractStanza extends Element {
super(name);
}
public String getTo() {
return getAttribute("to");
}
public Jid getTo() {
try {
return Jid.fromString(getAttribute("to"));
} catch (final InvalidJidException e) {
return null;
}
}
public String getFrom() {
return getAttribute("from");
}
public Jid getFrom() {
try {
return Jid.fromString(getAttribute("from"));
} catch (final InvalidJidException e) {
return null;
}
}
public String getId() {
return this.getAttribute("id");
}
public void setTo(String to) {
setAttribute("to", to);
public void setTo(final Jid to) {
setAttribute("to", to.toString());
}
public void setFrom(String from) {
setAttribute("from", from);
public void setFrom(final Jid from) {
setAttribute("from", from.toString());
}
public void setId(String id) {
public void setId(final String id) {
setAttribute("id", id);
}
}