Merge pull request #639 from SamWhited/issue631
Use JID class instead of strings
This commit is contained in:
		
						commit
						f65a2188cc
					
				| @ -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' | ||||
| } | ||||
|  | ||||
| @ -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"); | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @ -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)); | ||||
| 	} | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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; | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -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(); | ||||
| } | ||||
|  | ||||
| @ -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() { | ||||
|  | ||||
| @ -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()) { | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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); | ||||
| 		} | ||||
|  | ||||
| @ -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()); | ||||
|  | ||||
| @ -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"); | ||||
|  | ||||
| @ -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; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @ -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); | ||||
| 			} | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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) }; | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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", | ||||
|  | ||||
| @ -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()) { | ||||
|  | ||||
| @ -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())); | ||||
|  | ||||
| @ -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) { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -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(); | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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); | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -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()); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
| @ -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); | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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) { | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @ -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); | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
| @ -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, | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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))); | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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()); | ||||
|  | ||||
| @ -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) { | ||||
|         } | ||||
| 
 | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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; | ||||
| 	} | ||||
|  | ||||
| @ -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() { | ||||
|  | ||||
| @ -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); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										180
									
								
								src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								src/main/java/eu/siacs/conversations/xmpp/jid/Jid.java
									
									
									
									
									
										Normal 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(); | ||||
|     } | ||||
| } | ||||
| @ -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"); | ||||
|  | ||||
| @ -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; | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -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, | ||||
|  | ||||
| @ -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, | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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); | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch