diff options
Diffstat (limited to 'src/de/gultsch/chat')
42 files changed, 0 insertions, 6406 deletions
diff --git a/src/de/gultsch/chat/crypto/OtrEngine.java b/src/de/gultsch/chat/crypto/OtrEngine.java deleted file mode 100644 index cdd71d61..00000000 --- a/src/de/gultsch/chat/crypto/OtrEngine.java +++ /dev/null @@ -1,232 +0,0 @@ -package de.gultsch.chat.crypto; - -import java.math.BigInteger; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.spec.DSAPrivateKeySpec; -import java.security.spec.DSAPublicKeySpec; -import java.security.spec.InvalidKeySpecException; - -import org.json.JSONException; -import org.json.JSONObject; - -import android.content.Context; -import android.util.Log; - -import de.gultsch.chat.entities.Account; -import de.gultsch.chat.persistance.DatabaseBackend; -import de.gultsch.chat.xml.Element; -import de.gultsch.chat.xmpp.MessagePacket; - -import net.java.otr4j.OtrEngineHost; -import net.java.otr4j.OtrException; -import net.java.otr4j.OtrPolicy; -import net.java.otr4j.OtrPolicyImpl; -import net.java.otr4j.session.InstanceTag; -import net.java.otr4j.session.SessionID; - -public class OtrEngine implements OtrEngineHost { - - private static final String LOGTAG = "xmppService"; - - private Account account; - private OtrPolicy otrPolicy; - private KeyPair keyPair; - private Context context; - - public OtrEngine(Context context, Account account) { - this.account = account; - this.otrPolicy = new OtrPolicyImpl(); - this.otrPolicy.setAllowV1(false); - this.otrPolicy.setAllowV2(true); - this.otrPolicy.setAllowV3(true); - this.keyPair = loadKey(account.getKeys()); - } - - private KeyPair loadKey(JSONObject keys) { - if (keys == null) { - return null; - } - try { - BigInteger x = new BigInteger(keys.getString("otr_x"),16); - BigInteger y = new BigInteger(keys.getString("otr_y"),16); - BigInteger p = new BigInteger(keys.getString("otr_p"),16); - BigInteger q = new BigInteger(keys.getString("otr_q"),16); - BigInteger g = new BigInteger(keys.getString("otr_g"),16); - KeyFactory keyFactory = KeyFactory.getInstance("DSA"); - DSAPublicKeySpec pubKeySpec = new DSAPublicKeySpec(y, p, q, g); - DSAPrivateKeySpec privateKeySpec = new DSAPrivateKeySpec(x, p, q, g); - PublicKey publicKey = keyFactory.generatePublic(pubKeySpec); - PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec); - return new KeyPair(publicKey, privateKey); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InvalidKeySpecException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return null; - } - - private void saveKey() { - PublicKey publicKey = keyPair.getPublic(); - PrivateKey privateKey = keyPair.getPrivate(); - KeyFactory keyFactory; - try { - keyFactory = KeyFactory.getInstance("DSA"); - DSAPrivateKeySpec privateKeySpec = keyFactory.getKeySpec(privateKey, DSAPrivateKeySpec.class); - DSAPublicKeySpec publicKeySpec = keyFactory.getKeySpec(publicKey, DSAPublicKeySpec.class); - this.account.setKey("otr_x",privateKeySpec.getX().toString(16)); - this.account.setKey("otr_g",privateKeySpec.getG().toString(16)); - 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) { - e.printStackTrace(); - } - - } - - @Override - public void askForSecret(SessionID arg0, InstanceTag arg1, String arg2) { - // TODO Auto-generated method stub - - } - - @Override - public void finishedSessionMessage(SessionID arg0, String arg1) - throws OtrException { - // TODO Auto-generated method stub - - } - - @Override - public String getFallbackMessage(SessionID arg0) { - // TODO Auto-generated method stub - return null; - } - - @Override - public byte[] getLocalFingerprintRaw(SessionID arg0) { - // TODO Auto-generated method stub - return null; - } - - public PublicKey getPublicKey() { - return this.keyPair.getPublic(); - } - - @Override - public KeyPair getLocalKeyPair(SessionID arg0) throws OtrException { - if (this.keyPair==null) { - KeyPairGenerator kg; - try { - kg = KeyPairGenerator.getInstance("DSA"); - this.keyPair = kg.genKeyPair(); - this.saveKey(); - DatabaseBackend.getInstance(context).updateAccount(account); - } catch (NoSuchAlgorithmException e) { - Log.d(LOGTAG,"error generating key pair "+e.getMessage()); - } - } - return this.keyPair; - } - - @Override - public String getReplyForUnreadableMessage(SessionID arg0) { - // TODO Auto-generated method stub - return null; - } - - @Override - public OtrPolicy getSessionPolicy(SessionID arg0) { - return otrPolicy; - } - - @Override - public void injectMessage(SessionID session, String body) throws OtrException { - MessagePacket packet = new MessagePacket(); - packet.setFrom(account.getFullJid()); //sender - packet.setTo(session.getAccountID()+"/"+session.getUserID()); //reciepient - packet.setBody(body); - Element privateTag = new Element("private"); - privateTag.setAttribute("xmlns","urn:xmpp:carbons:2"); - packet.addChild(privateTag); - packet.setType(MessagePacket.TYPE_CHAT); - account.getXmppConnection().sendMessagePacket(packet); - } - - @Override - public void messageFromAnotherInstanceReceived(SessionID arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void multipleInstancesDetected(SessionID arg0) { - // TODO Auto-generated method stub - - } - - @Override - public void requireEncryptedMessage(SessionID arg0, String arg1) - throws OtrException { - // TODO Auto-generated method stub - - } - - @Override - public void showError(SessionID arg0, String arg1) throws OtrException { - // TODO Auto-generated method stub - - } - - @Override - public void smpAborted(SessionID arg0) throws OtrException { - // TODO Auto-generated method stub - - } - - @Override - public void smpError(SessionID arg0, int arg1, boolean arg2) - throws OtrException { - // TODO Auto-generated method stub - - } - - @Override - public void unencryptedMessageReceived(SessionID arg0, String arg1) - throws OtrException { - // TODO Auto-generated method stub - - } - - @Override - public void unreadableMessageReceived(SessionID arg0) throws OtrException { - // TODO Auto-generated method stub - - } - - @Override - public void unverify(SessionID arg0, String arg1) { - // TODO Auto-generated method stub - - } - - @Override - public void verify(SessionID arg0, String arg1, boolean arg2) { - // TODO Auto-generated method stub - - } - -} diff --git a/src/de/gultsch/chat/crypto/PgpEngine.java b/src/de/gultsch/chat/crypto/PgpEngine.java deleted file mode 100644 index 6d94e577..00000000 --- a/src/de/gultsch/chat/crypto/PgpEngine.java +++ /dev/null @@ -1,148 +0,0 @@ -package de.gultsch.chat.crypto; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; - -import org.openintents.openpgp.OpenPgpError; -import org.openintents.openpgp.OpenPgpSignatureResult; -import org.openintents.openpgp.util.OpenPgpApi; -import org.openintents.openpgp.util.OpenPgpConstants; - -import android.app.PendingIntent; -import android.os.Bundle; -import android.util.Log; - -public class PgpEngine { - private OpenPgpApi api; - - public PgpEngine(OpenPgpApi api) { - this.api = api; - } - - public String decrypt(String message) throws UserInputRequiredException, - OpenPgpException { - InputStream is = new ByteArrayInputStream(message.getBytes()); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - Bundle result = api.decryptAndVerify(is, os); - switch (result.getInt(OpenPgpConstants.RESULT_CODE)) { - case OpenPgpConstants.RESULT_CODE_SUCCESS: - return os.toString(); - case OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED: - throw new UserInputRequiredException( - (PendingIntent) result - .getParcelable(OpenPgpConstants.RESULT_INTENT)); - case OpenPgpConstants.RESULT_CODE_ERROR: - throw new OpenPgpException( - (OpenPgpError) result - .getParcelable(OpenPgpConstants.RESULT_ERRORS)); - default: - return null; - } - } - - public String encrypt(long keyId, String message) { - Bundle params = new Bundle(); - params.putBoolean(OpenPgpConstants.PARAMS_REQUEST_ASCII_ARMOR, true); - long[] keyIds = { keyId }; - params.putLongArray(OpenPgpConstants.PARAMS_KEY_IDS, keyIds); - - InputStream is = new ByteArrayInputStream(message.getBytes()); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - Bundle result = api.encrypt(params, is, os); - StringBuilder encryptedMessageBody = new StringBuilder(); - String[] lines = os.toString().split("\n"); - for (int i = 3; i < lines.length - 1; ++i) { - encryptedMessageBody.append(lines[i].trim()); - } - return encryptedMessageBody.toString(); - } - - public long fetchKeyId(String status, String signature) - throws OpenPgpException { - StringBuilder pgpSig = new StringBuilder(); - pgpSig.append("-----BEGIN PGP SIGNED MESSAGE-----"); - pgpSig.append('\n'); - pgpSig.append("Hash: SHA1"); - pgpSig.append('\n'); - pgpSig.append('\n'); - pgpSig.append(status); - pgpSig.append('\n'); - pgpSig.append("-----BEGIN PGP SIGNATURE-----"); - pgpSig.append('\n'); - pgpSig.append('\n'); - pgpSig.append(signature.replace("\n", "").trim()); - pgpSig.append('\n'); - pgpSig.append("-----END PGP SIGNATURE-----"); - Bundle params = new Bundle(); - params.putBoolean(OpenPgpConstants.PARAMS_REQUEST_ASCII_ARMOR, true); - InputStream is = new ByteArrayInputStream(pgpSig.toString().getBytes()); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - Bundle result = api.decryptAndVerify(params, is, os); - switch (result.getInt(OpenPgpConstants.RESULT_CODE)) { - case OpenPgpConstants.RESULT_CODE_SUCCESS: - OpenPgpSignatureResult sigResult = result - .getParcelable(OpenPgpConstants.RESULT_SIGNATURE); - return sigResult.getKeyId(); - case OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED: - break; - case OpenPgpConstants.RESULT_CODE_ERROR: - throw new OpenPgpException( - (OpenPgpError) result - .getParcelable(OpenPgpConstants.RESULT_ERRORS)); - } - return 0; - } - - public String generateSignature(String status) - throws UserInputRequiredException { - Bundle params = new Bundle(); - params.putBoolean(OpenPgpConstants.PARAMS_REQUEST_ASCII_ARMOR, true); - InputStream is = new ByteArrayInputStream(status.getBytes()); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - Bundle result = api.sign(params, is, os); - StringBuilder signatureBuilder = new StringBuilder(); - switch (result.getInt(OpenPgpConstants.RESULT_CODE)) { - case OpenPgpConstants.RESULT_CODE_SUCCESS: - String[] lines = os.toString().split("\n"); - for (int i = 7; i < lines.length - 1; ++i) { - signatureBuilder.append(lines[i].trim()); - } - break; - case OpenPgpConstants.RESULT_CODE_USER_INTERACTION_REQUIRED: - UserInputRequiredException exception = new UserInputRequiredException( - (PendingIntent) result - .getParcelable(OpenPgpConstants.RESULT_INTENT)); - throw exception; - case OpenPgpConstants.RESULT_CODE_ERROR: - break; - } - return signatureBuilder.toString(); - } - - public class UserInputRequiredException extends Exception { - private static final long serialVersionUID = -6913480043269132016L; - private PendingIntent pi; - - public UserInputRequiredException(PendingIntent pi) { - this.pi = pi; - } - - public PendingIntent getPendingIntent() { - return this.pi; - } - } - - public class OpenPgpException extends Exception { - private static final long serialVersionUID = -7324789703473056077L; - private OpenPgpError error; - - public OpenPgpException(OpenPgpError openPgpError) { - this.error = openPgpError; - } - - public OpenPgpError getOpenPgpError() { - return this.error; - } - } -} diff --git a/src/de/gultsch/chat/entities/AbstractEntity.java b/src/de/gultsch/chat/entities/AbstractEntity.java deleted file mode 100644 index 31a19fc0..00000000 --- a/src/de/gultsch/chat/entities/AbstractEntity.java +++ /dev/null @@ -1,25 +0,0 @@ -package de.gultsch.chat.entities; - -import java.io.Serializable; - -import android.content.ContentValues; - -public abstract class AbstractEntity implements Serializable { - - private static final long serialVersionUID = -1895605706690653719L; - - public static final String UUID = "uuid"; - - protected String uuid; - - public String getUuid() { - return this.uuid; - } - - public abstract ContentValues getContentValues(); - - public boolean equals(AbstractEntity entity) { - return this.getUuid().equals(entity.getUuid()); - } - -} diff --git a/src/de/gultsch/chat/entities/Account.java b/src/de/gultsch/chat/entities/Account.java deleted file mode 100644 index c8f6d063..00000000 --- a/src/de/gultsch/chat/entities/Account.java +++ /dev/null @@ -1,221 +0,0 @@ -package de.gultsch.chat.entities; - -import java.security.interfaces.DSAPublicKey; - -import net.java.otr4j.crypto.OtrCryptoEngineImpl; -import net.java.otr4j.crypto.OtrCryptoException; - -import org.json.JSONException; -import org.json.JSONObject; - -import de.gultsch.chat.crypto.OtrEngine; -import de.gultsch.chat.xmpp.XmppConnection; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.util.JsonReader; -import android.util.Log; - -public class Account extends AbstractEntity{ - - private static final long serialVersionUID = 6174825093869578035L; - - public static final String TABLENAME = "accounts"; - - public static final String USERNAME = "username"; - public static final String SERVER = "server"; - public static final String PASSWORD = "password"; - public static final String OPTIONS = "options"; - public static final String ROSTERVERSION = "rosterversion"; - public static final String KEYS = "keys"; - - public static final int OPTION_USETLS = 0; - public static final int OPTION_DISABLED = 1; - - public static final int STATUS_DISABLED = -1; - public static final int STATUS_OFFLINE = 0; - public static final int STATUS_ONLINE = 1; - public static final int STATUS_UNAUTHORIZED = 2; - public static final int STATUS_NOINTERNET = 3; - public static final int STATUS_TLS_ERROR = 4; - public static final int STATUS_SERVER_NOT_FOUND = 5; - - protected String username; - protected String server; - protected String password; - protected int options = 0; - protected String rosterVersion; - protected String resource; - protected int status = 0; - protected JSONObject keys = new JSONObject(); - - protected boolean online = false; - - transient OtrEngine otrEngine = null; - transient XmppConnection xmppConnection = null; - - private String otrFingerprint; - - public Account() { - this.uuid = "0"; - } - - public Account(String username, String server, String password) { - this(java.util.UUID.randomUUID().toString(),username,server,password,0,null,""); - } - public Account(String uuid, String username, String server,String password, int options, String rosterVersion, String keys) { - this.uuid = uuid; - this.username = username; - this.server = server; - this.password = password; - this.options = options; - this.rosterVersion = rosterVersion; - try { - this.keys = new JSONObject(keys); - } catch (JSONException e) { - - } - } - - public boolean isOptionSet(int option) { - return ((options & (1 << option)) != 0); - } - - public void setOption(int option, boolean value) { - if (value) { - this.options |= 1 << option; - } else { - this.options &= ~(1 << option); - } - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getServer() { - return server; - } - - public void setServer(String server) { - this.server = server; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public void setStatus(int status) { - this.status = status; - } - - public int getStatus() { - if (isOptionSet(OPTION_DISABLED)) { - return STATUS_DISABLED; - } else { - return this.status; - } - } - - public void setResource(String resource) { - this.resource = resource; - } - - public String getJid() { - return username+"@"+server; - } - - public JSONObject getKeys() { - return keys; - } - - public boolean setKey(String keyName, String keyValue) { - try { - this.keys.put(keyName, keyValue); - return true; - } catch (JSONException e) { - return false; - } - } - - @Override - public ContentValues getContentValues() { - ContentValues values = new ContentValues(); - values.put(UUID,uuid); - values.put(USERNAME, username); - values.put(SERVER, server); - values.put(PASSWORD, password); - values.put(OPTIONS,options); - values.put(KEYS,this.keys.toString()); - values.put(ROSTERVERSION,rosterVersion); - return values; - } - - public static Account fromCursor(Cursor cursor) { - return new Account(cursor.getString(cursor.getColumnIndex(UUID)), - cursor.getString(cursor.getColumnIndex(USERNAME)), - cursor.getString(cursor.getColumnIndex(SERVER)), - cursor.getString(cursor.getColumnIndex(PASSWORD)), - cursor.getInt(cursor.getColumnIndex(OPTIONS)), - cursor.getString(cursor.getColumnIndex(ROSTERVERSION)), - cursor.getString(cursor.getColumnIndex(KEYS)) - ); - } - - - public OtrEngine getOtrEngine(Context context) { - if (otrEngine==null) { - otrEngine = new OtrEngine(context,this); - } - return this.otrEngine; - } - - public XmppConnection getXmppConnection() { - return this.xmppConnection; - } - - public void setXmppConnection(XmppConnection connection) { - this.xmppConnection = connection; - } - - public String getFullJid() { - return this.getJid()+"/"+this.resource; - } - - public String getOtrFingerprint() { - if (this.otrFingerprint == null) { - try { - DSAPublicKey pubkey = (DSAPublicKey) this.otrEngine.getPublicKey(); - StringBuilder builder = new StringBuilder(new OtrCryptoEngineImpl().getFingerprint(pubkey)); - builder.insert(8, " "); - builder.insert(17, " "); - builder.insert(26, " "); - builder.insert(35, " "); - this.otrFingerprint = builder.toString(); - } catch (OtrCryptoException e) { - - } - } - return this.otrFingerprint; - } - - public String getRosterVersion() { - if (this.rosterVersion==null) { - return ""; - } else { - return this.rosterVersion; - } - } - - public void setRosterVersion(String version) { - this.rosterVersion = version; - } -} diff --git a/src/de/gultsch/chat/entities/Contact.java b/src/de/gultsch/chat/entities/Contact.java deleted file mode 100644 index a8c9fa62..00000000 --- a/src/de/gultsch/chat/entities/Contact.java +++ /dev/null @@ -1,296 +0,0 @@ -package de.gultsch.chat.entities; - -import java.io.Serializable; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Set; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import de.gultsch.chat.xml.Element; - -import android.content.ContentValues; -import android.database.Cursor; - -public class Contact extends AbstractEntity implements Serializable { - private static final long serialVersionUID = -4570817093119419962L; - - public static final String TABLENAME = "contacts"; - - public static final String DISPLAYNAME = "name"; - public static final String JID = "jid"; - public static final String SUBSCRIPTION = "subscription"; - public static final String SYSTEMACCOUNT = "systemaccount"; - public static final String PHOTOURI = "photouri"; - public static final String KEYS = "pgpkey"; - public static final String PRESENCES = "presences"; - public static final String ACCOUNT = "accountUuid"; - - protected String accountUuid; - protected String displayName; - protected String jid; - protected int subscription = 0; - protected String systemAccount; - protected String photoUri; - protected JSONObject keys = new JSONObject(); - protected Presences presences = new Presences(); - - protected Account account; - - protected boolean inRoster = true; - - public Contact(Account account, String displayName, String jid, - String photoUri) { - if (account == null) { - this.accountUuid = null; - } else { - this.accountUuid = account.getUuid(); - } - this.account = account; - this.displayName = displayName; - this.jid = jid; - this.photoUri = photoUri; - this.uuid = java.util.UUID.randomUUID().toString(); - } - - public Contact(String uuid, String account, String displayName, String jid, - int subscription, String photoUri, String systemAccount, - String keys, String presences) { - this.uuid = uuid; - this.accountUuid = account; - this.displayName = displayName; - this.jid = jid; - this.subscription = subscription; - this.photoUri = photoUri; - this.systemAccount = systemAccount; - if (keys == null) { - keys = ""; - } - try { - this.keys = new JSONObject(keys); - } catch (JSONException e) { - this.keys = new JSONObject(); - } - this.presences = Presences.fromJsonString(presences); - } - - public String getDisplayName() { - return this.displayName; - } - - public String getProfilePhoto() { - return this.photoUri; - } - - public String getJid() { - return this.jid; - } - - public boolean match(String needle) { - return (jid.toLowerCase().contains(needle.toLowerCase()) || (displayName - .toLowerCase().contains(needle.toLowerCase()))); - } - - @Override - public ContentValues getContentValues() { - ContentValues values = new ContentValues(); - values.put(UUID, uuid); - values.put(ACCOUNT, accountUuid); - values.put(DISPLAYNAME, displayName); - values.put(JID, jid); - values.put(SUBSCRIPTION, subscription); - values.put(SYSTEMACCOUNT, systemAccount); - values.put(PHOTOURI, photoUri); - values.put(KEYS, keys.toString()); - values.put(PRESENCES, presences.toJsonString()); - return values; - } - - public static Contact fromCursor(Cursor cursor) { - return new Contact(cursor.getString(cursor.getColumnIndex(UUID)), - cursor.getString(cursor.getColumnIndex(ACCOUNT)), - cursor.getString(cursor.getColumnIndex(DISPLAYNAME)), - cursor.getString(cursor.getColumnIndex(JID)), - cursor.getInt(cursor.getColumnIndex(SUBSCRIPTION)), - cursor.getString(cursor.getColumnIndex(PHOTOURI)), - cursor.getString(cursor.getColumnIndex(SYSTEMACCOUNT)), - cursor.getString(cursor.getColumnIndex(KEYS)), - cursor.getString(cursor.getColumnIndex(PRESENCES))); - } - - public int getSubscription() { - return this.subscription; - } - - public void setSystemAccount(String account) { - this.systemAccount = account; - } - - public void setAccount(Account account) { - this.account = account; - this.accountUuid = account.getUuid(); - } - - public Account getAccount() { - return this.account; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - public boolean couldBeMuc() { - String[] split = this.getJid().split("@"); - if (split.length != 2) { - return false; - } else { - String[] domainParts = split[1].split("\\."); - if (domainParts.length < 3) { - return false; - } else { - return (domainParts[0].equals("conf") - || domainParts[0].equals("conference") || domainParts[0] - .equals("muc")); - } - } - } - - public Hashtable<String, Integer> getPresences() { - return this.presences.getPresences(); - } - - public void updatePresence(String resource, int status) { - this.presences.updatePresence(resource, status); - } - - public void removePresence(String resource) { - this.presences.removePresence(resource); - } - - public int getMostAvailableStatus() { - return this.presences.getMostAvailableStatus(); - } - - public void setPresences(Presences pres) { - this.presences = pres; - } - - public void setPhotoUri(String uri) { - this.photoUri = uri; - } - - public void setDisplayName(String name) { - this.displayName = name; - } - - public String getSystemAccount() { - return systemAccount; - } - - public Set<String> getOtrFingerprints() { - Set<String> set = new HashSet<String>(); - try { - if (this.keys.has("otr_fingerprints")) { - JSONArray fingerprints = this.keys.getJSONArray("otr_fingerprints"); - for (int i = 0; i < fingerprints.length(); ++i) { - set.add(fingerprints.getString(i)); - } - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return set; - } - - public void addOtrFingerprint(String print) { - try { - JSONArray fingerprints; - if (!this.keys.has("otr_fingerprints")) { - fingerprints = new JSONArray(); - - } else { - fingerprints = this.keys.getJSONArray("otr_fingerprints"); - } - fingerprints.put(print); - this.keys.put("otr_fingerprints", fingerprints); - } catch (JSONException e) { - - } - } - - public void setPgpKeyId(long keyId) { - try { - this.keys.put("pgp_keyid", keyId); - } catch (JSONException e) { - - } - } - - public long getPgpKeyId() { - if (this.keys.has("pgp_keyid")) { - try { - return this.keys.getLong("pgp_keyid"); - } catch (JSONException e) { - return 0; - } - } else { - return 0; - } - } - - public void setSubscriptionOption(int option) { - this.subscription |= 1 << option; - } - - public void resetSubscriptionOption(int option) { - this.subscription &= ~(1 << option); - } - - public boolean getSubscriptionOption(int option) { - return ((this.subscription & (1 << option)) != 0); - } - - public void parseSubscriptionFromElement(Element item) { - String ask = item.getAttribute("ask"); - String subscription = item.getAttribute("subscription"); - - if (subscription!=null) { - if (subscription.equals("to")) { - this.resetSubscriptionOption(Contact.Subscription.FROM); - this.setSubscriptionOption(Contact.Subscription.TO); - } else if (subscription.equals("from")) { - this.resetSubscriptionOption(Contact.Subscription.TO); - this.setSubscriptionOption(Contact.Subscription.FROM); - } else if (subscription.equals("both")) { - this.setSubscriptionOption(Contact.Subscription.TO); - this.setSubscriptionOption(Contact.Subscription.FROM); - } - } - - if ((ask!=null)&&(ask.equals("subscribe"))) { - this.setSubscriptionOption(Contact.Subscription.ASKING); - } else { - this.resetSubscriptionOption(Contact.Subscription.ASKING); - } - } - - - public class Subscription { - public static final int TO = 0; - public static final int FROM = 1; - public static final int ASKING = 2; - public static final int PREEMPTIVE_GRANT = 4; - } - - - public void flagAsNotInRoster() { - this.inRoster = false; - } - - public boolean isInRoster() { - return this.inRoster; - } -} diff --git a/src/de/gultsch/chat/entities/Conversation.java b/src/de/gultsch/chat/entities/Conversation.java deleted file mode 100644 index 3f83010c..00000000 --- a/src/de/gultsch/chat/entities/Conversation.java +++ /dev/null @@ -1,271 +0,0 @@ -package de.gultsch.chat.entities; - -import java.security.interfaces.DSAPublicKey; -import java.util.ArrayList; -import java.util.List; - -import de.gultsch.chat.crypto.OtrEngine; -import de.gultsch.chat.xmpp.XmppConnection; - -import net.java.otr4j.OtrException; -import net.java.otr4j.crypto.OtrCryptoEngineImpl; -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.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.util.Log; - -public class Conversation extends AbstractEntity { - - private static final long serialVersionUID = -6727528868973996739L; - - public static final String TABLENAME = "conversations"; - - public static final int STATUS_AVAILABLE = 0; - public static final int STATUS_ARCHIVED = 1; - public static final int STATUS_DELETED = 2; - - public static final int MODE_MULTI = 1; - public static final int MODE_SINGLE = 0; - - public static final String NAME = "name"; - public static final String ACCOUNT = "accountUuid"; - public static final String CONTACT = "contactUuid"; - public static final String CONTACTJID = "contactJid"; - public static final String STATUS = "status"; - public static final String CREATED = "created"; - public static final String MODE = "mode"; - - private String name; - private String contactUuid; - private String accountUuid; - private String contactJid; - private int status; - private long created; - private int mode; - - private transient List<Message> messages = null; - private transient Account account = null; - private transient Contact contact; - - private transient SessionImpl otrSession; - - private transient String otrFingerprint = null; - - public int nextMessageEncryption = Message.ENCRYPTION_NONE; - - public Conversation(String name, Account account, - String contactJid, 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) { - this.uuid = uuid; - this.name = name; - this.contactUuid = contactUuid; - this.accountUuid = accountUuid; - this.contactJid = contactJid; - this.created = created; - this.status = status; - this.mode = mode; - } - - public List<Message> getMessages() { - if (messages == null) this.messages = new ArrayList<Message>(); //prevent null pointer - - //populate with Conversation (this) - - for(Message msg : messages) { - msg.setConversation(this); - } - - return messages; - } - - public boolean isRead() { - if ((this.messages == null)||(this.messages.size() == 0)) return true; - return this.messages.get(this.messages.size() - 1).isRead(); - } - - public void markRead() { - if (this.messages == null) return; - for(int i = this.messages.size() -1; i >= 0; --i) { - if (messages.get(i).isRead()) return; - this.messages.get(i).markRead(); - } - } - - public Message getLatestMessage() { - if ((this.messages == null)||(this.messages.size()==0)) { - Message message = new Message(this,"",Message.ENCRYPTION_NONE); - message.setTime(getCreated()); - return message; - } else { - return this.messages.get(this.messages.size() - 1); - } - } - - public void setMessages(List<Message> msgs) { - this.messages = msgs; - } - - public String getName() { - if (this.contact!=null) { - return this.contact.getDisplayName(); - } else { - return this.name; - } - } - - public String getProfilePhotoString() { - if (this.contact==null) { - return null; - } else { - return this.contact.getProfilePhoto(); - } - } - - public String getAccountUuid() { - return this.accountUuid; - } - - public Account getAccount() { - return this.account; - } - - public Contact getContact() { - return this.contact; - } - - public void setContact(Contact contact) { - this.contact = contact; - if (contact!=null) { - this.contactUuid = contact.getUuid(); - } - } - - public void setAccount(Account account) { - this.account = account; - } - - public String getContactJid() { - return this.contactJid; - } - - public Uri getProfilePhotoUri() { - if (this.getProfilePhotoString() != null) { - return Uri.parse(this.getProfilePhotoString()); - } - return null; - } - - public int getStatus() { - return this.status; - } - - public long getCreated() { - return this.created; - } - - public ContentValues getContentValues() { - ContentValues values = new ContentValues(); - values.put(UUID, uuid); - values.put(NAME, name); - values.put(CONTACT, contactUuid); - values.put(ACCOUNT, accountUuid); - values.put(CONTACTJID, contactJid); - values.put(CREATED, created); - values.put(STATUS, status); - values.put(MODE,mode); - return values; - } - - public static Conversation fromCursor(Cursor cursor) { - 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)), - cursor.getLong(cursor.getColumnIndex(CREATED)), - cursor.getInt(cursor.getColumnIndex(STATUS)), - cursor.getInt(cursor.getColumnIndex(MODE))); - } - - public void setStatus(int status) { - this.status = status; - } - - public int getMode() { - return this.mode; - } - - public void setMode(int mode) { - this.mode = mode; - } - - public void startOtrSession(Context context, String presence) { - Log.d("xmppService","starting otr session with "+presence); - SessionID sessionId = new SessionID(this.getContactJid(),presence,"xmpp"); - this.otrSession = new SessionImpl(sessionId, getAccount().getOtrEngine(context)); - try { - this.otrSession.startSession(); - } catch (OtrException e) { - Log.d("xmppServic","couldnt start otr"); - } - } - - public SessionImpl getOtrSession() { - return this.otrSession; - } - - public void resetOtrSession() { - this.otrSession = null; - } - - public void endOtrIfNeeded() throws OtrException { - if (this.otrSession!=null) { - if (this.otrSession.getSessionStatus() == SessionStatus.ENCRYPTED) { - this.otrSession.endSession(); - } - } - this.resetOtrSession(); - } - - public boolean hasValidOtrSession() { - if (this.otrSession == null) { - return false; - } else { - String foreignPresence = this.otrSession.getSessionID().getUserID(); - if (!getContact().getPresences().containsKey(foreignPresence)) { - this.resetOtrSession(); - return false; - } - return true; - } - } - - public String getOtrFingerprint() { - if (this.otrFingerprint == null) { - try { - DSAPublicKey remotePubKey = (DSAPublicKey) getOtrSession().getRemotePublicKey(); - StringBuilder builder = new StringBuilder(new OtrCryptoEngineImpl().getFingerprint(remotePubKey)); - builder.insert(8, " "); - builder.insert(17, " "); - builder.insert(26, " "); - builder.insert(35, " "); - this.otrFingerprint = builder.toString(); - } catch (OtrCryptoException e) { - - } - } - return this.otrFingerprint; - } -} diff --git a/src/de/gultsch/chat/entities/Message.java b/src/de/gultsch/chat/entities/Message.java deleted file mode 100644 index 58e4ef63..00000000 --- a/src/de/gultsch/chat/entities/Message.java +++ /dev/null @@ -1,144 +0,0 @@ -package de.gultsch.chat.entities; - -import android.content.ContentValues; -import android.database.Cursor; - -public class Message extends AbstractEntity { - - private static final long serialVersionUID = 7222081895167103025L; - - public static final String TABLENAME = "messages"; - - public static final int STATUS_RECIEVED = 0; - public static final int STATUS_UNSEND = 1; - public static final int STATUS_SEND = 2; - public static final int STATUS_ERROR = 3; - - public static final int ENCRYPTION_NONE = 0; - public static final int ENCRYPTION_PGP = 1; - public static final int ENCRYPTION_OTR = 2; - public static final int ENCRYPTION_DECRYPTED = 3; - - public static String CONVERSATION = "conversationUuid"; - public static String COUNTERPART = "counterpart"; - public static String BODY = "body"; - public static String TIME_SENT = "timeSent"; - public static String ENCRYPTION = "encryption"; - public static String STATUS = "status"; - - protected String conversationUuid; - protected String counterpart; - protected String body; - protected long timeSent; - protected int encryption; - protected int status; - protected boolean read = true; - - protected transient Conversation conversation = null; - - public Message(Conversation conversation, String body, int encryption) { - this(java.util.UUID.randomUUID().toString(), conversation.getUuid(), - conversation.getContactJid(), body, System.currentTimeMillis(), encryption, - Message.STATUS_UNSEND); - this.conversation = conversation; - } - - public Message(Conversation conversation, String counterpart, String body, int encryption, int status) { - this(java.util.UUID.randomUUID().toString(), conversation.getUuid(),counterpart, body, System.currentTimeMillis(), encryption,status); - this.conversation = conversation; - } - - public Message(String uuid, String conversationUUid, String counterpart, - String body, long timeSent, int encryption, int status) { - this.uuid = uuid; - this.conversationUuid = conversationUUid; - this.counterpart = counterpart; - this.body = body; - this.timeSent = timeSent; - this.encryption = encryption; - this.status = status; - } - - @Override - public ContentValues getContentValues() { - ContentValues values = new ContentValues(); - values.put(UUID, uuid); - values.put(CONVERSATION, conversationUuid); - values.put(COUNTERPART, counterpart); - values.put(BODY, body); - values.put(TIME_SENT, timeSent); - values.put(ENCRYPTION, encryption); - values.put(STATUS, status); - return values; - } - - public String getConversationUuid() { - return conversationUuid; - } - - public Conversation getConversation() { - return this.conversation; - } - - public String getCounterpart() { - return counterpart; - } - - public String getBody() { - return body; - } - - public long getTimeSent() { - return timeSent; - } - - public int getEncryption() { - return encryption; - } - - public int getStatus() { - return status; - } - - public static Message fromCursor(Cursor cursor) { - return new Message(cursor.getString(cursor.getColumnIndex(UUID)), - cursor.getString(cursor.getColumnIndex(CONVERSATION)), - cursor.getString(cursor.getColumnIndex(COUNTERPART)), - cursor.getString(cursor.getColumnIndex(BODY)), - cursor.getLong(cursor.getColumnIndex(TIME_SENT)), - cursor.getInt(cursor.getColumnIndex(ENCRYPTION)), - cursor.getInt(cursor.getColumnIndex(STATUS))); - } - - public void setConversation(Conversation conv) { - this.conversation = conv; - } - - public void setStatus(int status) { - this.status = status; - } - - public boolean isRead() { - return this.read; - } - - public void markRead() { - this.read = true; - } - - public void markUnread() { - this.read = false; - } - - public void setTime(long time) { - this.timeSent = time; - } - - public void setEncryption(int encryption) { - this.encryption = encryption; - } - - public void setBody(String body) { - this.body = body; - } -} diff --git a/src/de/gultsch/chat/entities/Presences.java b/src/de/gultsch/chat/entities/Presences.java deleted file mode 100644 index aabc8440..00000000 --- a/src/de/gultsch/chat/entities/Presences.java +++ /dev/null @@ -1,76 +0,0 @@ -package de.gultsch.chat.entities; - -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map.Entry; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -public class Presences { - - public static final int CHAT = -1; - public static final int ONLINE = 0; - public static final int AWAY = 1; - public static final int XA = 2; - public static final int DND = 3; - public static final int OFFLINE = 4; - - private Hashtable<String, Integer> presences = new Hashtable<String, Integer>(); - - public Hashtable<String, Integer> getPresences() { - return this.presences; - } - - public void updatePresence(String resource, int status) { - this.presences.put(resource, status); - } - - public void removePresence(String resource) { - this.presences.remove(resource); - } - - public int getMostAvailableStatus() { - int status = OFFLINE; - Iterator<Entry<String, Integer>> it = presences.entrySet().iterator(); - while (it.hasNext()) { - Entry<String, Integer> entry = it.next(); - if (entry.getValue()<status) status = entry.getValue(); - } - return status; - } - - public String toJsonString() { - JSONArray json = new JSONArray(); - Iterator<Entry<String, Integer>> it = presences.entrySet().iterator(); - - while (it.hasNext()) { - Entry<String, Integer> entry = it.next(); - JSONObject jObj = new JSONObject(); - try { - jObj.put("resource", entry.getKey()); - jObj.put("status", entry.getValue()); - } catch (JSONException e) { - - } - json.put(jObj); - } - return json.toString(); - } - - public static Presences fromJsonString(String jsonString) { - Presences presences = new Presences(); - try { - JSONArray json = new JSONArray(jsonString); - for (int i = 0; i < json.length(); ++i) { - JSONObject jObj = json.getJSONObject(i); - presences.updatePresence(jObj.getString("resource"), - jObj.getInt("status")); - } - } catch (JSONException e1) { - - } - return presences; - } -} diff --git a/src/de/gultsch/chat/persistance/DatabaseBackend.java b/src/de/gultsch/chat/persistance/DatabaseBackend.java deleted file mode 100644 index 18fad7c4..00000000 --- a/src/de/gultsch/chat/persistance/DatabaseBackend.java +++ /dev/null @@ -1,284 +0,0 @@ -package de.gultsch.chat.persistance; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import de.gultsch.chat.entities.Account; -import de.gultsch.chat.entities.Contact; -import de.gultsch.chat.entities.Conversation; -import de.gultsch.chat.entities.Message; -import de.gultsch.chat.entities.Presences; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; -import android.os.Bundle; -import android.util.Log; - -public class DatabaseBackend extends SQLiteOpenHelper { - - private static DatabaseBackend instance = null; - - private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 1; - - public DatabaseBackend(Context context) { - super(context, DATABASE_NAME, null, DATABASE_VERSION); - } - - @Override - public void onCreate(SQLiteDatabase db) { - db.execSQL("PRAGMA foreign_keys=ON;"); - db.execSQL("create table " + Account.TABLENAME + "(" + Account.UUID - + " TEXT PRIMARY KEY," + Account.USERNAME + " TEXT," - + Account.SERVER + " TEXT," + Account.PASSWORD + " TEXT," - + Account.ROSTERVERSION + " TEXT," + Account.OPTIONS - + " NUMBER, "+Account.KEYS+" TEXT)"); - db.execSQL("create table " + Conversation.TABLENAME + " (" - + Conversation.UUID + " TEXT PRIMARY KEY, " + Conversation.NAME - + " TEXT, " + Conversation.CONTACT + " TEXT, " - + Conversation.ACCOUNT + " TEXT, " + Conversation.CONTACTJID - + " TEXT, " + Conversation.CREATED + " NUMBER, " - + Conversation.STATUS + " NUMBER," + Conversation.MODE - + " NUMBER," + "FOREIGN KEY(" + Conversation.ACCOUNT - + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID - + ") ON DELETE CASCADE);"); - db.execSQL("create table " + Message.TABLENAME + "( " + Message.UUID - + " TEXT PRIMARY KEY, " + Message.CONVERSATION + " TEXT, " - + Message.TIME_SENT + " NUMBER, " + Message.COUNTERPART - + " TEXT, " + Message.BODY + " TEXT, " + Message.ENCRYPTION - + " NUMBER, " + Message.STATUS + " NUMBER," + "FOREIGN KEY(" - + Message.CONVERSATION + ") REFERENCES " - + Conversation.TABLENAME + "(" + Conversation.UUID - + ") ON DELETE CASCADE);"); - db.execSQL("create table " + Contact.TABLENAME + "(" + Contact.UUID - + " TEXT PRIMARY KEY, " + Contact.ACCOUNT + " TEXT, " - + Contact.DISPLAYNAME + " TEXT," + Contact.JID + " TEXT," - + Contact.PRESENCES + " TEXT, " + Contact.KEYS - + " TEXT," + Contact.PHOTOURI + " TEXT," + Contact.SUBSCRIPTION - + " NUMBER," + Contact.SYSTEMACCOUNT + " NUMBER, " - + "FOREIGN KEY(" + Contact.ACCOUNT + ") REFERENCES " - + Account.TABLENAME + "(" + Account.UUID - + ") ON DELETE CASCADE);"); - } - - @Override - public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) { - // TODO Auto-generated method stub - - } - - public static synchronized DatabaseBackend getInstance(Context context) { - if (instance == null) { - instance = new DatabaseBackend(context); - } - return instance; - } - - public void createConversation(Conversation conversation) { - SQLiteDatabase db = this.getWritableDatabase(); - db.insert(Conversation.TABLENAME, null, conversation.getContentValues()); - } - - public void createMessage(Message message) { - SQLiteDatabase db = this.getWritableDatabase(); - db.insert(Message.TABLENAME, null, message.getContentValues()); - } - - public void createAccount(Account account) { - SQLiteDatabase db = this.getWritableDatabase(); - db.insert(Account.TABLENAME, null, account.getContentValues()); - } - - public void createContact(Contact contact) { - SQLiteDatabase db = this.getWritableDatabase(); - db.insert(Contact.TABLENAME, null, contact.getContentValues()); - } - - public int getConversationCount() { - SQLiteDatabase db = this.getReadableDatabase(); - Cursor cursor = db.rawQuery("select count(uuid) as count from " - + Conversation.TABLENAME + " where " + Conversation.STATUS - + "=" + Conversation.STATUS_AVAILABLE, null); - cursor.moveToFirst(); - return cursor.getInt(0); - } - - public List<Conversation> getConversations(int status) { - List<Conversation> list = new ArrayList<Conversation>(); - SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { "" + status }; - Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME - + " where " + Conversation.STATUS + " = ? order by " - + Conversation.CREATED + " desc", selectionArgs); - while (cursor.moveToNext()) { - list.add(Conversation.fromCursor(cursor)); - } - return list; - } - - public List<Message> getMessages(Conversation conversation, int limit) { - List<Message> list = new ArrayList<Message>(); - SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { conversation.getUuid() }; - Cursor cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION - + "=?", selectionArgs, null, null, Message.TIME_SENT + " DESC", - String.valueOf(limit)); - if (cursor.getCount() > 0) { - cursor.moveToLast(); - do { - list.add(Message.fromCursor(cursor)); - } while (cursor.moveToPrevious()); - } - return list; - } - - public Conversation findConversation(Account account, String contactJid) { - SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { account.getUuid(), contactJid }; - Cursor cursor = db.query(Conversation.TABLENAME, null, - Conversation.ACCOUNT + "=? AND " + Conversation.CONTACTJID + "=?", - selectionArgs, null, null, null); - if (cursor.getCount() == 0) - return null; - cursor.moveToFirst(); - return Conversation.fromCursor(cursor); - } - - public void updateConversation(Conversation conversation) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { conversation.getUuid() }; - db.update(Conversation.TABLENAME, conversation.getContentValues(), - Conversation.UUID + "=?", args); - } - - public List<Account> getAccounts() { - List<Account> list = new ArrayList<Account>(); - SQLiteDatabase db = this.getReadableDatabase(); - Cursor cursor = db.query(Account.TABLENAME, null, null, null, null, - null, null); - Log.d("gultsch", "found " + cursor.getCount() + " accounts"); - while (cursor.moveToNext()) { - list.add(Account.fromCursor(cursor)); - } - return list; - } - - public void updateAccount(Account account) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { account.getUuid() }; - db.update(Account.TABLENAME, account.getContentValues(), Account.UUID - + "=?", args); - } - - public void deleteAccount(Account account) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { account.getUuid() }; - db.delete(Account.TABLENAME, Account.UUID + "=?", args); - } - - @Override - public SQLiteDatabase getWritableDatabase() { - SQLiteDatabase db = super.getWritableDatabase(); - db.execSQL("PRAGMA foreign_keys=ON;"); - return db; - } - - public void updateMessage(Message message) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { message.getUuid() }; - db.update(Message.TABLENAME, message.getContentValues(), Message.UUID - + "=?", args); - } - - public void updateContact(Contact contact) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { contact.getUuid() }; - db.update(Contact.TABLENAME, contact.getContentValues(), Contact.UUID - + "=?", args); - } - - public void clearPresences(Account account) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { account.getUuid() }; - ContentValues values = new ContentValues(); - values.put(Contact.PRESENCES,"[]"); - db.update(Contact.TABLENAME, values, Contact.ACCOUNT - + "=?", args); - } - - public void mergeContacts(List<Contact> contacts) { - SQLiteDatabase db = this.getWritableDatabase(); - for (int i = 0; i < contacts.size(); i++) { - Contact contact = contacts.get(i); - String[] columns = {Contact.UUID, Contact.PRESENCES}; - String[] args = {contact.getAccount().getUuid(), contact.getJid()}; - Cursor cursor = db.query(Contact.TABLENAME, columns,Contact.ACCOUNT+"=? AND "+Contact.JID+"=?", args, null, null, null); - if (cursor.getCount()>=1) { - cursor.moveToFirst(); - contact.setUuid(cursor.getString(0)); - contact.setPresences(Presences.fromJsonString(cursor.getString(1))); - updateContact(contact); - } else { - contact.setUuid(UUID.randomUUID().toString()); - createContact(contact); - } - } - } - - public List<Contact> getContacts(Account account) { - List<Contact> list = new ArrayList<Contact>(); - SQLiteDatabase db = this.getReadableDatabase(); - Cursor cursor; - if (account==null) { - cursor = db.query(Contact.TABLENAME, null, null, null, null, - null, null); - } else { - String args[] = {account.getUuid()}; - cursor = db.query(Contact.TABLENAME, null, Contact.ACCOUNT+"=?", args, null, - null, null); - } - while (cursor.moveToNext()) { - list.add(Contact.fromCursor(cursor)); - } - return list; - } - - public List<Contact> getContats(String where) { - List<Contact> list = new ArrayList<Contact>(); - SQLiteDatabase db = this.getReadableDatabase(); - Cursor cursor = db.query(Contact.TABLENAME, null, where, null, null, null, null); - while (cursor.moveToNext()) { - list.add(Contact.fromCursor(cursor)); - } - return list; - } - - public Contact findContact(Account account, String jid) { - SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { account.getUuid(), jid }; - Cursor cursor = db.query(Contact.TABLENAME, null, - Contact.ACCOUNT + "=? AND " + Contact.JID + "=?", - selectionArgs, null, null, null); - if (cursor.getCount() == 0) - return null; - cursor.moveToFirst(); - return Contact.fromCursor(cursor); - } - - public void deleteMessage(Message message) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { message.getUuid() }; - db.delete(Message.TABLENAME, Message.UUID + "=?", args); - } - - public void deleteContact(Contact contact) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { contact.getUuid() }; - db.delete(Contact.TABLENAME, Contact.UUID + "=?", args); - } - - -} diff --git a/src/de/gultsch/chat/persistance/OnPhoneContactsMerged.java b/src/de/gultsch/chat/persistance/OnPhoneContactsMerged.java deleted file mode 100644 index a7918efb..00000000 --- a/src/de/gultsch/chat/persistance/OnPhoneContactsMerged.java +++ /dev/null @@ -1,5 +0,0 @@ -package de.gultsch.chat.persistance; - -public interface OnPhoneContactsMerged { - public void phoneContactsMerged(); -} diff --git a/src/de/gultsch/chat/services/XmppConnectionService.java b/src/de/gultsch/chat/services/XmppConnectionService.java deleted file mode 100644 index 7ff09957..00000000 --- a/src/de/gultsch/chat/services/XmppConnectionService.java +++ /dev/null @@ -1,944 +0,0 @@ -package de.gultsch.chat.services; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Hashtable; -import java.util.List; - -import org.json.JSONException; -import org.openintents.openpgp.util.OpenPgpApi; -import org.openintents.openpgp.util.OpenPgpServiceConnection; - -import net.java.otr4j.OtrException; -import net.java.otr4j.session.Session; -import net.java.otr4j.session.SessionStatus; - -import de.gultsch.chat.crypto.PgpEngine; -import de.gultsch.chat.crypto.PgpEngine.OpenPgpException; -import de.gultsch.chat.entities.Account; -import de.gultsch.chat.entities.Contact; -import de.gultsch.chat.entities.Conversation; -import de.gultsch.chat.entities.Message; -import de.gultsch.chat.entities.Presences; -import de.gultsch.chat.persistance.DatabaseBackend; -import de.gultsch.chat.persistance.OnPhoneContactsMerged; -import de.gultsch.chat.ui.OnAccountListChangedListener; -import de.gultsch.chat.ui.OnConversationListChangedListener; -import de.gultsch.chat.ui.OnRosterFetchedListener; -import de.gultsch.chat.utils.MessageParser; -import de.gultsch.chat.utils.OnPhoneContactsLoadedListener; -import de.gultsch.chat.utils.PhoneHelper; -import de.gultsch.chat.utils.UIHelper; -import de.gultsch.chat.xml.Element; -import de.gultsch.chat.xmpp.IqPacket; -import de.gultsch.chat.xmpp.MessagePacket; -import de.gultsch.chat.xmpp.OnIqPacketReceived; -import de.gultsch.chat.xmpp.OnMessagePacketReceived; -import de.gultsch.chat.xmpp.OnPresencePacketReceived; -import de.gultsch.chat.xmpp.OnStatusChanged; -import de.gultsch.chat.xmpp.PresencePacket; -import de.gultsch.chat.xmpp.XmppConnection; -import android.app.NotificationManager; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.database.ContentObserver; -import android.database.DatabaseUtils; -import android.os.Binder; -import android.os.Bundle; -import android.os.IBinder; -import android.os.PowerManager; -import android.preference.PreferenceManager; -import android.provider.ContactsContract; -import android.util.Log; - -public class XmppConnectionService extends Service { - - protected static final String LOGTAG = "xmppService"; - public DatabaseBackend databaseBackend; - - public long startDate; - - private List<Account> accounts; - private List<Conversation> conversations = null; - - public OnConversationListChangedListener convChangedListener = null; - private OnAccountListChangedListener accountChangedListener = null; - - private ContentObserver contactObserver = new ContentObserver(null) { - @Override - public void onChange(boolean selfChange) { - super.onChange(selfChange); - Log.d(LOGTAG, "contact list has changed"); - mergePhoneContactsWithRoster(null); - } - }; - - private XmppConnectionService service = this; - - private final IBinder mBinder = new XmppConnectionBinder(); - private OnMessagePacketReceived messageListener = new OnMessagePacketReceived() { - - @Override - public void onMessagePacketReceived(Account account, - MessagePacket packet) { - Message message = null; - boolean notify = false; - if ((packet.getType() == MessagePacket.TYPE_CHAT)) { - String pgpBody = MessageParser.getPgpBody(packet); - if (pgpBody != null) { - message = MessageParser.parsePgpChat(pgpBody, packet, - account, service); - notify = false; - } else if (packet.hasChild("body") - && (packet.getBody().startsWith("?OTR"))) { - message = MessageParser.parseOtrChat(packet, account, - service); - notify = true; - } else if (packet.hasChild("body")) { - message = MessageParser.parsePlainTextChat(packet, account, - service); - notify = true; - } else if (packet.hasChild("received") - || (packet.hasChild("sent"))) { - message = MessageParser.parseCarbonMessage(packet, account, - service); - } - - } else if (packet.getType() == MessagePacket.TYPE_GROUPCHAT) { - message = MessageParser - .parseGroupchat(packet, account, service); - if (message != null) { - notify = (message.getStatus() == Message.STATUS_RECIEVED); - } - } else if (packet.getType() == MessagePacket.TYPE_ERROR) { - message = MessageParser.parseError(packet, account, service); - } else { - Log.d(LOGTAG, "unparsed message " + packet.toString()); - } - if (message == null) { - return; - } - if (packet.hasChild("delay")) { - try { - String stamp = packet.findChild("delay").getAttribute( - "stamp"); - stamp = stamp.replace("Z", "+0000"); - Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") - .parse(stamp); - message.setTime(date.getTime()); - } catch (ParseException e) { - Log.d(LOGTAG, "error trying to parse date" + e.getMessage()); - } - } - if (notify) { - message.markUnread(); - } - Conversation conversation = message.getConversation(); - conversation.getMessages().add(message); - if (packet.getType() != MessagePacket.TYPE_ERROR) { - databaseBackend.createMessage(message); - } - if (convChangedListener != null) { - convChangedListener.onConversationListChanged(); - } else { - if (notify) { - NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - mNotificationManager.notify(2342, UIHelper - .getUnreadMessageNotification( - getApplicationContext(), conversation)); - } - } - } - }; - private OnStatusChanged statusListener = new OnStatusChanged() { - - @Override - public void onStatusChanged(Account account) { - if (accountChangedListener != null) { - accountChangedListener.onAccountListChangedListener(); - } - if (account.getStatus() == Account.STATUS_ONLINE) { - databaseBackend.clearPresences(account); - connectMultiModeConversations(account); - List<Conversation> conversations = getConversations(); - for (int i = 0; i < conversations.size(); ++i) { - if (conversations.get(i).getAccount() == account) { - sendUnsendMessages(conversations.get(i)); - } - } - if (convChangedListener != null) { - convChangedListener.onConversationListChanged(); - } - if (account.getKeys().has("pgp_signature")) { - try { - sendPgpPresence(account, account.getKeys().getString("pgp_signature")); - } catch (JSONException e) { - // - } - } - } - } - }; - - private OnPresencePacketReceived presenceListener = new OnPresencePacketReceived() { - - @Override - public void onPresencePacketReceived(Account account, - PresencePacket packet) { - String[] fromParts = packet.getAttribute("from").split("/"); - Contact contact = findContact(account, fromParts[0]); - if (contact == null) { - // most likely muc, self or roster not synced - Log.d(LOGTAG, - "got presence for non contact " + packet.toString()); - return; - } - String type = packet.getAttribute("type"); - if (type == null) { - Element show = packet.findChild("show"); - if (show == null) { - contact.updatePresence(fromParts[1], Presences.ONLINE); - } else if (show.getContent().equals("away")) { - contact.updatePresence(fromParts[1], Presences.AWAY); - } else if (show.getContent().equals("xa")) { - contact.updatePresence(fromParts[1], Presences.XA); - } else if (show.getContent().equals("chat")) { - contact.updatePresence(fromParts[1], Presences.CHAT); - } else if (show.getContent().equals("dnd")) { - contact.updatePresence(fromParts[1], Presences.DND); - } - PgpEngine pgp = getPgpEngine(); - if (pgp!=null) { - Element x = packet.findChild("x"); - if ((x != null) - && (x.getAttribute("xmlns").equals("jabber:x:signed"))) { - try { - Log.d(LOGTAG,"pgp signature for contact" +packet.getAttribute("from")); - contact.setPgpKeyId(pgp.fetchKeyId(packet.findChild("status") - .getContent(), x.getContent())); - } catch (OpenPgpException e) { - Log.d(LOGTAG,"faulty pgp. just ignore"); - } - } - } - databaseBackend.updateContact(contact); - } else if (type.equals("unavailable")) { - if (fromParts.length != 2) { - // Log.d(LOGTAG,"received presence with no resource "+packet.toString()); - } else { - contact.removePresence(fromParts[1]); - databaseBackend.updateContact(contact); - } - } else if (type.equals("subscribe")) { - if (contact - .getSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT)) { - sendPresenceUpdatesTo(contact); - contact.setSubscriptionOption(Contact.Subscription.FROM); - contact.resetSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT); - replaceContactInConversation(contact.getJid(), contact); - databaseBackend.updateContact(contact); - if ((contact - .getSubscriptionOption(Contact.Subscription.ASKING)) - && (!contact - .getSubscriptionOption(Contact.Subscription.TO))) { - requestPresenceUpdatesFrom(contact); - } - } else { - // TODO: ask user to handle it maybe - } - } else { - Log.d(LOGTAG, packet.toString()); - } - replaceContactInConversation(contact.getJid(), contact); - } - }; - - private OnIqPacketReceived unknownIqListener = new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.hasChild("query")) { - Element query = packet.findChild("query"); - String xmlns = query.getAttribute("xmlns"); - if ((xmlns != null) && (xmlns.equals("jabber:iq:roster"))) { - processRosterItems(account, query); - mergePhoneContactsWithRoster(null); - } - } - } - }; - - private OpenPgpServiceConnection pgpServiceConnection; - private PgpEngine mPgpEngine = null; - - public PgpEngine getPgpEngine() { - if (pgpServiceConnection.isBound()) { - if (this.mPgpEngine == null) { - this.mPgpEngine = new PgpEngine(new OpenPgpApi( - getApplicationContext(), - pgpServiceConnection.getService())); - } - return mPgpEngine; - } else { - return null; - } - - } - - private void processRosterItems(Account account, Element elements) { - String version = elements.getAttribute("ver"); - if (version != null) { - account.setRosterVersion(version); - databaseBackend.updateAccount(account); - } - for (Element item : elements.getChildren()) { - if (item.getName().equals("item")) { - String jid = item.getAttribute("jid"); - String subscription = item.getAttribute("subscription"); - Contact contact = databaseBackend.findContact(account, jid); - if (contact == null) { - if (!subscription.equals("remove")) { - String name = item.getAttribute("name"); - if (name == null) { - name = jid.split("@")[0]; - } - contact = new Contact(account, name, jid, null); - contact.parseSubscriptionFromElement(item); - databaseBackend.createContact(contact); - } - } else { - if (subscription.equals("remove")) { - databaseBackend.deleteContact(contact); - replaceContactInConversation(contact.getJid(), null); - } else { - contact.parseSubscriptionFromElement(item); - databaseBackend.updateContact(contact); - replaceContactInConversation(contact.getJid(), contact); - } - } - } - } - } - - private void replaceContactInConversation(String jid, Contact contact) { - List<Conversation> conversations = getConversations(); - for (int i = 0; i < conversations.size(); ++i) { - if ((conversations.get(i).getContactJid().equals(jid))) { - conversations.get(i).setContact(contact); - break; - } - } - } - - public class XmppConnectionBinder extends Binder { - public XmppConnectionService getService() { - return XmppConnectionService.this; - } - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - for (Account account : accounts) { - if (account.getXmppConnection() == null) { - if (!account.isOptionSet(Account.OPTION_DISABLED)) { - account.setXmppConnection(this.createConnection(account)); - } - } - } - return START_STICKY; - } - - @Override - public void onCreate() { - databaseBackend = DatabaseBackend.getInstance(getApplicationContext()); - this.accounts = databaseBackend.getAccounts(); - - getContentResolver().registerContentObserver( - ContactsContract.Contacts.CONTENT_URI, true, contactObserver); - this.pgpServiceConnection = new OpenPgpServiceConnection( - getApplicationContext(), "org.sufficientlysecure.keychain"); - this.pgpServiceConnection.bindToService(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - for (Account account : accounts) { - if (account.getXmppConnection() != null) { - disconnect(account); - } - } - } - - public XmppConnection createConnection(Account account) { - PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); - XmppConnection connection = new XmppConnection(account, pm); - connection.setOnMessagePacketReceivedListener(this.messageListener); - connection.setOnStatusChangedListener(this.statusListener); - connection.setOnPresencePacketReceivedListener(this.presenceListener); - connection - .setOnUnregisteredIqPacketReceivedListener(this.unknownIqListener); - Thread thread = new Thread(connection); - thread.start(); - return connection; - } - - public void sendMessage(Message message, String presence) { - Account account = message.getConversation().getAccount(); - Conversation conv = message.getConversation(); - boolean saveInDb = false; - boolean addToConversation = false; - if (account.getStatus() == Account.STATUS_ONLINE) { - MessagePacket packet; - if (message.getEncryption() == Message.ENCRYPTION_OTR) { - if (!conv.hasValidOtrSession()) { - // starting otr session. messages will be send later - conv.startOtrSession(getApplicationContext(), presence); - } else if (conv.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) { - // otr session aleary exists, creating message packet - // accordingly - packet = prepareMessagePacket(account, message, - conv.getOtrSession()); - account.getXmppConnection().sendMessagePacket(packet); - message.setStatus(Message.STATUS_SEND); - } - saveInDb = true; - addToConversation = true; - } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { - long keyId = message.getConversation().getContact() - .getPgpKeyId(); - packet = new MessagePacket(); - packet.setType(MessagePacket.TYPE_CHAT); - packet.setFrom(message.getConversation().getAccount() - .getFullJid()); - packet.setTo(message.getCounterpart()); - packet.setBody("This is an XEP-0027 encryted message"); - Element x = new Element("x"); - x.setAttribute("xmlns", "jabber:x:encrypted"); - x.setContent(this.getPgpEngine().encrypt(keyId, - message.getBody())); - packet.addChild(x); - account.getXmppConnection().sendMessagePacket(packet); - message.setStatus(Message.STATUS_SEND); - message.setEncryption(Message.ENCRYPTION_DECRYPTED); - saveInDb = true; - addToConversation = true; - } else { - // don't encrypt - if (message.getConversation().getMode() == Conversation.MODE_SINGLE) { - message.setStatus(Message.STATUS_SEND); - saveInDb = true; - addToConversation = true; - } - - packet = prepareMessagePacket(account, message, null); - account.getXmppConnection().sendMessagePacket(packet); - } - } else { - // account is offline - saveInDb = true; - addToConversation = true; - - } - if (saveInDb) { - databaseBackend.createMessage(message); - } - if (addToConversation) { - conv.getMessages().add(message); - if (convChangedListener != null) { - convChangedListener.onConversationListChanged(); - } - } - - } - - private void sendUnsendMessages(Conversation conversation) { - for (int i = 0; i < conversation.getMessages().size(); ++i) { - if (conversation.getMessages().get(i).getStatus() == Message.STATUS_UNSEND) { - Message message = conversation.getMessages().get(i); - MessagePacket packet = prepareMessagePacket( - conversation.getAccount(), message, null); - conversation.getAccount().getXmppConnection() - .sendMessagePacket(packet); - message.setStatus(Message.STATUS_SEND); - if (conversation.getMode() == Conversation.MODE_SINGLE) { - databaseBackend.updateMessage(message); - } else { - databaseBackend.deleteMessage(message); - conversation.getMessages().remove(i); - i--; - } - } - } - } - - public MessagePacket prepareMessagePacket(Account account, Message message, - Session otrSession) { - MessagePacket packet = new MessagePacket(); - if (message.getConversation().getMode() == Conversation.MODE_SINGLE) { - packet.setType(MessagePacket.TYPE_CHAT); - if (otrSession != null) { - try { - packet.setBody(otrSession.transformSending(message - .getBody())); - } catch (OtrException e) { - Log.d(LOGTAG, - account.getJid() - + ": could not encrypt message to " - + message.getCounterpart()); - } - Element privateMarker = new Element("private"); - privateMarker.setAttribute("xmlns", "urn:xmpp:carbons:2"); - packet.addChild(privateMarker); - packet.setTo(otrSession.getSessionID().getAccountID() + "/" - + otrSession.getSessionID().getUserID()); - packet.setFrom(account.getFullJid()); - } else { - packet.setBody(message.getBody()); - packet.setTo(message.getCounterpart()); - packet.setFrom(account.getJid()); - } - } else if (message.getConversation().getMode() == Conversation.MODE_MULTI) { - packet.setType(MessagePacket.TYPE_GROUPCHAT); - packet.setBody(message.getBody()); - packet.setTo(message.getCounterpart()); - packet.setFrom(account.getJid()); - } - return packet; - } - - public void getRoster(Account account, - final OnRosterFetchedListener listener) { - List<Contact> contacts = databaseBackend.getContacts(account); - for (int i = 0; i < contacts.size(); ++i) { - contacts.get(i).setAccount(account); - } - if (listener != null) { - listener.onRosterFetched(contacts); - } - } - - public void updateRoster(final Account account, - final OnRosterFetchedListener listener) { - IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET); - Element query = new Element("query"); - query.setAttribute("xmlns", "jabber:iq:roster"); - query.setAttribute("ver", account.getRosterVersion()); - iqPacket.addChild(query); - account.getXmppConnection().sendIqPacket(iqPacket, - new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(final Account account, - IqPacket packet) { - Element roster = packet.findChild("query"); - if (roster != null) { - processRosterItems(account, roster); - StringBuilder mWhere = new StringBuilder(); - mWhere.append("jid NOT IN("); - List<Element> items = roster.getChildren(); - for (int i = 0; i < items.size(); ++i) { - mWhere.append(DatabaseUtils - .sqlEscapeString(items.get(i) - .getAttribute("jid"))); - if (i != items.size() - 1) { - mWhere.append(","); - } - } - mWhere.append(") and accountUuid = \""); - mWhere.append(account.getUuid()); - mWhere.append("\""); - List<Contact> contactsToDelete = databaseBackend - .getContats(mWhere.toString()); - for (Contact contact : contactsToDelete) { - databaseBackend.deleteContact(contact); - replaceContactInConversation(contact.getJid(), - null); - } - - } - mergePhoneContactsWithRoster(new OnPhoneContactsMerged() { - - @Override - public void phoneContactsMerged() { - if (listener != null) { - getRoster(account, listener); - } - } - }); - } - }); - } - - public void mergePhoneContactsWithRoster( - final OnPhoneContactsMerged listener) { - PhoneHelper.loadPhoneContacts(getApplicationContext(), - new OnPhoneContactsLoadedListener() { - @Override - public void onPhoneContactsLoaded( - Hashtable<String, Bundle> phoneContacts) { - List<Contact> contacts = databaseBackend - .getContacts(null); - for (int i = 0; i < contacts.size(); ++i) { - Contact contact = contacts.get(i); - if (phoneContacts.containsKey(contact.getJid())) { - Bundle phoneContact = phoneContacts.get(contact - .getJid()); - String systemAccount = phoneContact - .getInt("phoneid") - + "#" - + phoneContact.getString("lookup"); - contact.setSystemAccount(systemAccount); - contact.setPhotoUri(phoneContact - .getString("photouri")); - contact.setDisplayName(phoneContact - .getString("displayname")); - databaseBackend.updateContact(contact); - replaceContactInConversation(contact.getJid(), - contact); - } else { - if ((contact.getSystemAccount() != null) - || (contact.getProfilePhoto() != null)) { - contact.setSystemAccount(null); - contact.setPhotoUri(null); - databaseBackend.updateContact(contact); - replaceContactInConversation( - contact.getJid(), contact); - } - } - } - if (listener != null) { - listener.phoneContactsMerged(); - } - } - }); - } - - public List<Conversation> getConversations() { - if (this.conversations == null) { - Hashtable<String, Account> accountLookupTable = new Hashtable<String, Account>(); - for (Account account : this.accounts) { - accountLookupTable.put(account.getUuid(), account); - } - this.conversations = databaseBackend - .getConversations(Conversation.STATUS_AVAILABLE); - for (Conversation conv : this.conversations) { - Account account = accountLookupTable.get(conv.getAccountUuid()); - conv.setAccount(account); - conv.setContact(findContact(account, conv.getContactJid())); - conv.setMessages(databaseBackend.getMessages(conv, 50)); - } - } - return this.conversations; - } - - public List<Account> getAccounts() { - return this.accounts; - } - - public Contact findContact(Account account, String jid) { - Contact contact = databaseBackend.findContact(account, jid); - if (contact != null) { - contact.setAccount(account); - } - return contact; - } - - public Conversation findOrCreateConversation(Account account, String jid, - boolean muc) { - for (Conversation conv : this.getConversations()) { - if ((conv.getAccount().equals(account)) - && (conv.getContactJid().equals(jid))) { - return conv; - } - } - Conversation conversation = databaseBackend.findConversation(account, - jid); - if (conversation != null) { - conversation.setStatus(Conversation.STATUS_AVAILABLE); - conversation.setAccount(account); - if (muc) { - conversation.setMode(Conversation.MODE_MULTI); - if (account.getStatus() == Account.STATUS_ONLINE) { - joinMuc(conversation); - } - } else { - conversation.setMode(Conversation.MODE_SINGLE); - } - this.databaseBackend.updateConversation(conversation); - conversation.setContact(findContact(account, - conversation.getContactJid())); - } else { - String conversationName; - Contact contact = findContact(account, jid); - if (contact != null) { - conversationName = contact.getDisplayName(); - } else { - conversationName = jid.split("@")[0]; - } - if (muc) { - conversation = new Conversation(conversationName, account, jid, - Conversation.MODE_MULTI); - if (account.getStatus() == Account.STATUS_ONLINE) { - joinMuc(conversation); - } - } else { - conversation = new Conversation(conversationName, account, jid, - Conversation.MODE_SINGLE); - } - conversation.setContact(contact); - this.databaseBackend.createConversation(conversation); - } - this.conversations.add(conversation); - if (this.convChangedListener != null) { - this.convChangedListener.onConversationListChanged(); - } - return conversation; - } - - public void archiveConversation(Conversation conversation) { - if (conversation.getMode() == Conversation.MODE_MULTI) { - leaveMuc(conversation); - } else { - try { - conversation.endOtrIfNeeded(); - } catch (OtrException e) { - Log.d(LOGTAG, - "error ending otr session for " - + conversation.getName()); - } - } - this.databaseBackend.updateConversation(conversation); - this.conversations.remove(conversation); - if (this.convChangedListener != null) { - this.convChangedListener.onConversationListChanged(); - } - } - - public int getConversationCount() { - return this.databaseBackend.getConversationCount(); - } - - public void createAccount(Account account) { - databaseBackend.createAccount(account); - this.accounts.add(account); - account.setXmppConnection(this.createConnection(account)); - if (accountChangedListener != null) - accountChangedListener.onAccountListChangedListener(); - } - - public void deleteContact(Contact contact) { - IqPacket iq = new IqPacket(IqPacket.TYPE_SET); - Element query = new Element("query"); - query.setAttribute("xmlns", "jabber:iq:roster"); - Element item = new Element("item"); - item.setAttribute("jid", contact.getJid()); - item.setAttribute("subscription", "remove"); - query.addChild(item); - iq.addChild(query); - contact.getAccount().getXmppConnection().sendIqPacket(iq, null); - replaceContactInConversation(contact.getJid(), null); - databaseBackend.deleteContact(contact); - } - - public void updateAccount(Account account) { - databaseBackend.updateAccount(account); - if (account.getXmppConnection() != null) { - disconnect(account); - } - if (!account.isOptionSet(Account.OPTION_DISABLED)) { - account.setXmppConnection(this.createConnection(account)); - } - if (accountChangedListener != null) - accountChangedListener.onAccountListChangedListener(); - } - - public void deleteAccount(Account account) { - Log.d(LOGTAG, "called delete account"); - if (account.getXmppConnection() != null) { - this.disconnect(account); - } - databaseBackend.deleteAccount(account); - this.accounts.remove(account); - if (accountChangedListener != null) - accountChangedListener.onAccountListChangedListener(); - } - - public void setOnConversationListChangedListener( - OnConversationListChangedListener listener) { - this.convChangedListener = listener; - } - - public void removeOnConversationListChangedListener() { - this.convChangedListener = null; - } - - public void setOnAccountListChangedListener( - OnAccountListChangedListener listener) { - this.accountChangedListener = listener; - } - - public void removeOnAccountListChangedListener() { - this.accountChangedListener = null; - } - - 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); - } - } - } - - public void joinMuc(Conversation conversation) { - String muc = conversation.getContactJid(); - PresencePacket packet = new PresencePacket(); - packet.setAttribute("to", muc + "/" - + conversation.getAccount().getUsername()); - Element x = new Element("x"); - x.setAttribute("xmlns", "http://jabber.org/protocol/muc"); - if (conversation.getMessages().size() != 0) { - Element history = new Element("history"); - long lastMsgTime = conversation.getLatestMessage().getTimeSent(); - long diff = (System.currentTimeMillis() - lastMsgTime) / 1000 - 1; - history.setAttribute("seconds", diff + ""); - x.addChild(history); - } - packet.addChild(x); - conversation.getAccount().getXmppConnection() - .sendPresencePacket(packet); - } - - public void leaveMuc(Conversation conversation) { - - } - - public void disconnect(Account account) { - 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 { - try { - conversation.endOtrIfNeeded(); - } catch (OtrException e) { - Log.d(LOGTAG, "error ending otr session for " - + conversation.getName()); - } - } - } - } - account.getXmppConnection().disconnect(); - Log.d(LOGTAG, "disconnected account: " + account.getJid()); - account.setXmppConnection(null); - } - - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - - public void updateContact(Contact contact) { - databaseBackend.updateContact(contact); - } - - public void updateMessage(Message message) { - databaseBackend.updateMessage(message); - } - - public void createContact(Contact contact) { - SharedPreferences sharedPref = PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - boolean autoGrant = sharedPref.getBoolean("grant_new_contacts", true); - if (autoGrant) { - contact.setSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT); - contact.setSubscriptionOption(Contact.Subscription.ASKING); - } - databaseBackend.createContact(contact); - IqPacket iq = new IqPacket(IqPacket.TYPE_SET); - Element query = new Element("query"); - query.setAttribute("xmlns", "jabber:iq:roster"); - Element item = new Element("item"); - item.setAttribute("jid", contact.getJid()); - item.setAttribute("name", contact.getJid()); - query.addChild(item); - iq.addChild(query); - Account account = contact.getAccount(); - account.getXmppConnection().sendIqPacket(iq, null); - if (autoGrant) { - requestPresenceUpdatesFrom(contact); - } - replaceContactInConversation(contact.getJid(), contact); - } - - public void requestPresenceUpdatesFrom(Contact contact) { - // Requesting a Subscription type=subscribe - PresencePacket packet = new PresencePacket(); - packet.setAttribute("type", "subscribe"); - packet.setAttribute("to", contact.getJid()); - packet.setAttribute("from", contact.getAccount().getJid()); - Log.d(LOGTAG, packet.toString()); - contact.getAccount().getXmppConnection().sendPresencePacket(packet); - } - - public void stopPresenceUpdatesFrom(Contact contact) { - // Unsubscribing type='unsubscribe' - PresencePacket packet = new PresencePacket(); - packet.setAttribute("type", "unsubscribe"); - packet.setAttribute("to", contact.getJid()); - packet.setAttribute("from", contact.getAccount().getJid()); - Log.d(LOGTAG, packet.toString()); - contact.getAccount().getXmppConnection().sendPresencePacket(packet); - } - - public void stopPresenceUpdatesTo(Contact contact) { - // Canceling a Subscription type=unsubscribed - PresencePacket packet = new PresencePacket(); - packet.setAttribute("type", "unsubscribed"); - packet.setAttribute("to", contact.getJid()); - packet.setAttribute("from", contact.getAccount().getJid()); - Log.d(LOGTAG, packet.toString()); - contact.getAccount().getXmppConnection().sendPresencePacket(packet); - } - - public void sendPresenceUpdatesTo(Contact contact) { - // type='subscribed' - PresencePacket packet = new PresencePacket(); - packet.setAttribute("type", "subscribed"); - packet.setAttribute("to", contact.getJid()); - packet.setAttribute("from", contact.getAccount().getJid()); - Log.d(LOGTAG, packet.toString()); - contact.getAccount().getXmppConnection().sendPresencePacket(packet); - } - - public void sendPgpPresence(Account account, String signature) { - PresencePacket packet = new PresencePacket(); - packet.setAttribute("from", account.getFullJid()); - Element status = new Element("status"); - status.setContent("online"); - packet.addChild(status); - Element x = new Element("x"); - x.setAttribute("xmlns", "jabber:x:signed"); - x.setContent(signature); - packet.addChild(x); - account.getXmppConnection().sendPresencePacket(packet); - } - - public void generatePgpAnnouncement(Account account) - throws PgpEngine.UserInputRequiredException { - if (account.getStatus() == Account.STATUS_ONLINE) { - String signature = getPgpEngine().generateSignature("online"); - account.setKey("pgp_signature", signature); - databaseBackend.updateAccount(account); - sendPgpPresence(account, signature); - } - } -}
\ No newline at end of file diff --git a/src/de/gultsch/chat/ui/ConversationActivity.java b/src/de/gultsch/chat/ui/ConversationActivity.java deleted file mode 100644 index 88d30bc5..00000000 --- a/src/de/gultsch/chat/ui/ConversationActivity.java +++ /dev/null @@ -1,484 +0,0 @@ -package de.gultsch.chat.ui; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import org.openintents.openpgp.OpenPgpSignatureResult; -import org.openintents.openpgp.util.OpenPgpConstants; - -import de.gultsch.chat.R; -import de.gultsch.chat.R.id; -import de.gultsch.chat.crypto.PgpEngine; -import de.gultsch.chat.crypto.PgpEngine.UserInputRequiredException; -import de.gultsch.chat.entities.Account; -import de.gultsch.chat.entities.Contact; -import de.gultsch.chat.entities.Conversation; -import de.gultsch.chat.entities.Message; -import de.gultsch.chat.utils.UIHelper; -import android.net.Uri; -import android.os.Bundle; -import android.app.AlertDialog; -import android.app.FragmentTransaction; -import android.app.NotificationManager; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentSender.SendIntentException; -import android.graphics.Typeface; -import android.support.v4.widget.SlidingPaneLayout; -import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener; -import android.util.Log; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ArrayAdapter; -import android.widget.ListView; -import android.widget.PopupMenu; -import android.widget.PopupMenu.OnMenuItemClickListener; -import android.widget.TextView; -import android.widget.ImageView; - -public class ConversationActivity extends XmppActivity { - - public static final String VIEW_CONVERSATION = "viewConversation"; - public static final String CONVERSATION = "conversationUuid"; - - public static final int REQUEST_SEND_MESSAGE = 0x75441; - public static final int REQUEST_DECRYPT_PGP = 0x76783; - - protected SlidingPaneLayout spl; - - private List<Conversation> conversationList = new ArrayList<Conversation>(); - private Conversation selectedConversation = null; - private ListView listView; - - private boolean paneShouldBeOpen = true; - private ArrayAdapter<Conversation> listAdapter; - - private OnConversationListChangedListener onConvChanged = new OnConversationListChangedListener() { - - @Override - public void onConversationListChanged() { - final Conversation currentConv = getSelectedConversation(); - conversationList.clear(); - conversationList.addAll(xmppConnectionService - .getConversations()); - runOnUiThread(new Runnable() { - - @Override - public void run() { - updateConversationList(); - if(paneShouldBeOpen) { - if (conversationList.size() >= 1) { - swapConversationFragment(); - } else { - startActivity(new Intent(getApplicationContext(), NewConversationActivity.class)); - finish(); - } - } - ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager().findFragmentByTag("conversation"); - if (selectedFragment!=null) { - selectedFragment.updateMessages(); - } - } - }); - } - }; - - private DialogInterface.OnClickListener addToRoster = new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - String jid = getSelectedConversation().getContactJid(); - Account account = getSelectedConversation().getAccount(); - String name = jid.split("@")[0]; - Contact contact = new Contact(account, name, jid, null); - xmppConnectionService.createContact(contact); - } - }; - private boolean contactInserted = false; - - - public List<Conversation> getConversationList() { - return this.conversationList; - } - - public Conversation getSelectedConversation() { - return this.selectedConversation; - } - - public ListView getConversationListView() { - return this.listView; - } - - public SlidingPaneLayout getSlidingPaneLayout() { - return this.spl; - } - - public boolean shouldPaneBeOpen() { - return paneShouldBeOpen; - } - - public void updateConversationList() { - if (conversationList.size() >= 1) { - Collections.sort(this.conversationList, new Comparator<Conversation>() { - @Override - public int compare(Conversation lhs, Conversation rhs) { - return (int) (rhs.getLatestMessage().getTimeSent() - lhs.getLatestMessage().getTimeSent()); - } - }); - } - this.listView.invalidateViews(); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - - super.onCreate(savedInstanceState); - - setContentView(R.layout.fragment_conversations_overview); - - listView = (ListView) findViewById(R.id.list); - - this.listAdapter = new ArrayAdapter<Conversation>(this, - R.layout.conversation_list_row, conversationList) { - @Override - public View getView(int position, View view, ViewGroup parent) { - if (view == null) { - LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = (View) inflater.inflate( - R.layout.conversation_list_row, null); - } - Conversation conv = getItem(position); - TextView convName = (TextView) view.findViewById(R.id.conversation_name); - convName.setText(conv.getName()); - TextView convLastMsg = (TextView) view.findViewById(R.id.conversation_lastmsg); - convLastMsg.setText(conv.getLatestMessage().getBody()); - - if(!conv.isRead()) { - convName.setTypeface(null,Typeface.BOLD); - convLastMsg.setTypeface(null,Typeface.BOLD); - } else { - convName.setTypeface(null,Typeface.NORMAL); - convLastMsg.setTypeface(null,Typeface.NORMAL); - } - - ((TextView) view.findViewById(R.id.conversation_lastupdate)) - .setText(UIHelper.readableTimeDifference(getItem(position).getLatestMessage().getTimeSent())); - - Uri profilePhoto = getItem(position).getProfilePhotoUri(); - ImageView imageView = (ImageView) view.findViewById(R.id.conversation_image); - if (profilePhoto!=null) { - imageView.setImageURI(profilePhoto); - } else { - imageView.setImageBitmap(UIHelper.getUnknownContactPicture(getItem(position).getName(),200)); - } - - - ((ImageView) view.findViewById(R.id.conversation_image)) - .setImageURI(getItem(position).getProfilePhotoUri()); - return view; - } - - }; - - listView.setAdapter(this.listAdapter); - - listView.setOnItemClickListener(new OnItemClickListener() { - - @Override - public void onItemClick(AdapterView<?> arg0, View clickedView, - int position, long arg3) { - paneShouldBeOpen = false; - if (selectedConversation != conversationList.get(position)) { - selectedConversation = conversationList.get(position); - swapConversationFragment(); //.onBackendConnected(conversationList.get(position)); - } else { - spl.closePane(); - } - } - }); - spl = (SlidingPaneLayout) findViewById(id.slidingpanelayout); - spl.setParallaxDistance(150); - spl.setShadowResource(R.drawable.es_slidingpane_shadow); - spl.setSliderFadeColor(0); - spl.setPanelSlideListener(new PanelSlideListener() { - - @Override - public void onPanelOpened(View arg0) { - paneShouldBeOpen = true; - getActionBar().setDisplayHomeAsUpEnabled(false); - getActionBar().setTitle(R.string.app_name); - invalidateOptionsMenu(); - - InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - - View focus = getCurrentFocus(); - - if (focus != null) { - - inputManager.hideSoftInputFromWindow( - focus.getWindowToken(), - InputMethodManager.HIDE_NOT_ALWAYS); - } - } - - @Override - public void onPanelClosed(View arg0) { - paneShouldBeOpen = false; - if (conversationList.size() > 0) { - getActionBar().setDisplayHomeAsUpEnabled(true); - getActionBar().setTitle(getSelectedConversation().getName()); - invalidateOptionsMenu(); - if (!getSelectedConversation().isRead()) { - getSelectedConversation().markRead(); - updateConversationList(); - } - } - } - - @Override - public void onPanelSlide(View arg0, float arg1) { - // TODO Auto-generated method stub - - } - }); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.conversations, menu); - MenuItem menuSecure = (MenuItem) menu.findItem(R.id.action_security); - - if (spl.isOpen()) { - ((MenuItem) menu.findItem(R.id.action_archive)).setVisible(false); - ((MenuItem) menu.findItem(R.id.action_details)).setVisible(false); - menuSecure.setVisible(false); - } else { - ((MenuItem) menu.findItem(R.id.action_add)).setVisible(false); - if (this.getSelectedConversation()!=null) { - if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) { - ((MenuItem) menu.findItem(R.id.action_security)).setVisible(false); - menuSecure.setVisible(false); - ((MenuItem) menu.findItem(R.id.action_archive)).setTitle("Leave conference"); - } else { - if (this.getSelectedConversation().getLatestMessage().getEncryption() != Message.ENCRYPTION_NONE) { - menuSecure.setIcon(R.drawable.ic_action_secure); - } - } - } - } - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - spl.openPane(); - break; - case R.id.action_settings: - startActivity(new Intent(this, SettingsActivity.class)); - break; - case R.id.action_accounts: - startActivity(new Intent(this, ManageAccountActivity.class)); - break; - case R.id.action_add: - startActivity(new Intent(this, NewConversationActivity.class)); - break; - case R.id.action_archive: - Conversation conv = getSelectedConversation(); - conv.setStatus(Conversation.STATUS_ARCHIVED); - paneShouldBeOpen = true; - spl.openPane(); - xmppConnectionService.archiveConversation(conv); - selectedConversation = conversationList.get(0); - break; - case R.id.action_details: - DialogContactDetails details = new DialogContactDetails(); - Contact contact = this.getSelectedConversation().getContact(); - if (contact != null) { - contact.setAccount(this.selectedConversation.getAccount()); - details.setContact(contact); - details.show(getFragmentManager(), "details"); - } else { - String jid = getSelectedConversation().getContactJid(); - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(jid); - builder.setMessage("The contact is not in your roster. Would you like to add it."); - builder.setNegativeButton("Cancel", null); - builder.setPositiveButton("Add",addToRoster); - builder.create().show(); - } - break; - case R.id.action_security: - final Conversation selConv = getSelectedConversation(); - View menuItemView = findViewById(R.id.action_security); - PopupMenu popup = new PopupMenu(this, menuItemView); - final ConversationFragment fragment = (ConversationFragment) getFragmentManager().findFragmentByTag("conversation"); - if (fragment!=null) { - popup.setOnMenuItemClickListener(new OnMenuItemClickListener() { - - @Override - public boolean onMenuItemClick(MenuItem item) { - switch (item.getItemId()) { - case R.id.encryption_choice_none: - selConv.nextMessageEncryption = Message.ENCRYPTION_NONE; - item.setChecked(true); - break; - case R.id.encryption_choice_otr: - selConv.nextMessageEncryption = Message.ENCRYPTION_OTR; - item.setChecked(true); - break; - case R.id.encryption_choice_pgp: - selConv.nextMessageEncryption = Message.ENCRYPTION_PGP; - item.setChecked(true); - break; - default: - selConv.nextMessageEncryption = Message.ENCRYPTION_NONE; - break; - } - fragment.updateChatMsgHint(); - return true; - } - }); - popup.inflate(R.menu.encryption_choices); - switch (selConv.nextMessageEncryption) { - case Message.ENCRYPTION_NONE: - popup.getMenu().findItem(R.id.encryption_choice_none).setChecked(true); - break; - case Message.ENCRYPTION_OTR: - popup.getMenu().findItem(R.id.encryption_choice_otr).setChecked(true); - break; - case Message.ENCRYPTION_PGP: - popup.getMenu().findItem(R.id.encryption_choice_pgp).setChecked(true); - break; - case Message.ENCRYPTION_DECRYPTED: - popup.getMenu().findItem(R.id.encryption_choice_pgp).setChecked(true); - break; - default: - popup.getMenu().findItem(R.id.encryption_choice_none).setChecked(true); - break; - } - popup.show(); - } - - break; - default: - break; - } - return super.onOptionsItemSelected(item); - } - - protected ConversationFragment swapConversationFragment() { - ConversationFragment selectedFragment = new ConversationFragment(); - - FragmentTransaction transaction = getFragmentManager() - .beginTransaction(); - transaction.replace(R.id.selected_conversation, selectedFragment,"conversation"); - transaction.commit(); - return selectedFragment; - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK) { - if (!spl.isOpen()) { - spl.openPane(); - return false; - } - } - return super.onKeyDown(keyCode, event); - } - - public void onStart() { - super.onStart(); - NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - nm.cancelAll(); - if (conversationList.size()>=1) { - onConvChanged.onConversationListChanged(); - } - } - - @Override - protected void onStop() { - Log.d("gultsch","called on stop in conversation activity"); - if (xmppConnectionServiceBound) { - xmppConnectionService.removeOnConversationListChangedListener(); - } - super.onStop(); - } - - @Override - void onBackendConnected() { - - xmppConnectionService.setOnConversationListChangedListener(this.onConvChanged); - - if (conversationList.size()==0) { - conversationList.clear(); - conversationList.addAll(xmppConnectionService - .getConversations()); - - this.updateConversationList(); - } - - if ((getIntent().getAction().equals(Intent.ACTION_VIEW) && (!handledViewIntent))) { - if (getIntent().getType().equals( - ConversationActivity.VIEW_CONVERSATION)) { - handledViewIntent = true; - - String convToView = (String) getIntent().getExtras().get(CONVERSATION); - - for(int i = 0; i < conversationList.size(); ++i) { - if (conversationList.get(i).getUuid().equals(convToView)) { - selectedConversation = conversationList.get(i); - } - } - paneShouldBeOpen = false; - swapConversationFragment(); - } - } else { - if (xmppConnectionService.getAccounts().size() == 0) { - startActivity(new Intent(this, ManageAccountActivity.class)); - finish(); - } else if (conversationList.size() <= 0) { - //add no history - startActivity(new Intent(this, NewConversationActivity.class)); - finish(); - } else { - spl.openPane(); - //find currently loaded fragment - ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager().findFragmentByTag("conversation"); - if (selectedFragment!=null) { - Log.d("gultsch","ConversationActivity. found old fragment."); - selectedFragment.onBackendConnected(); - } else { - Log.d("gultsch","conversationactivity. no old fragment found. creating new one"); - selectedConversation = conversationList.get(0); - Log.d("gultsch","selected conversation is #"+selectedConversation); - swapConversationFragment(); - } - } - } - } - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (resultCode == RESULT_OK) { - if (requestCode == REQUEST_DECRYPT_PGP) { - ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager().findFragmentByTag("conversation"); - if (selectedFragment!=null) { - selectedFragment.hidePgpPassphraseBox(); - } - } - } - } -} diff --git a/src/de/gultsch/chat/ui/ConversationFragment.java b/src/de/gultsch/chat/ui/ConversationFragment.java deleted file mode 100644 index af07fdbb..00000000 --- a/src/de/gultsch/chat/ui/ConversationFragment.java +++ /dev/null @@ -1,602 +0,0 @@ -package de.gultsch.chat.ui; - -import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import net.java.otr4j.session.SessionStatus; - -import de.gultsch.chat.R; -import de.gultsch.chat.crypto.PgpEngine.OpenPgpException; -import de.gultsch.chat.crypto.PgpEngine.UserInputRequiredException; -import de.gultsch.chat.entities.Contact; -import de.gultsch.chat.entities.Conversation; -import de.gultsch.chat.entities.Message; -import de.gultsch.chat.services.XmppConnectionService; -import de.gultsch.chat.utils.PhoneHelper; -import de.gultsch.chat.utils.UIHelper; -import android.app.AlertDialog; -import android.app.Fragment; -import android.content.DialogInterface; -import android.content.IntentSender; -import android.content.SharedPreferences; -import android.content.IntentSender.SendIntentException; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Typeface; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.ListView; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.TextView; - -public class ConversationFragment extends Fragment { - - protected Conversation conversation; - protected ListView messagesView; - protected LayoutInflater inflater; - protected List<Message> messageList = new ArrayList<Message>(); - protected ArrayAdapter<Message> messageListAdapter; - protected Contact contact; - protected BitmapCache mBitmapCache = new BitmapCache(); - - protected String queuedPqpMessage = null; - - private EditText chatMsg; - - protected Bitmap selfBitmap; - - private IntentSender askForPassphraseIntent = null; - - private OnClickListener sendMsgListener = new OnClickListener() { - - @Override - public void onClick(View v) { - if (chatMsg.getText().length() < 1) - return; - Message message = new Message(conversation, chatMsg.getText() - .toString(), conversation.nextMessageEncryption); - if (conversation.nextMessageEncryption == Message.ENCRYPTION_OTR) { - sendOtrMessage(message); - } else if (conversation.nextMessageEncryption == Message.ENCRYPTION_PGP) { - sendPgpMessage(message); - } else { - sendPlainTextMessage(message); - } - } - }; - protected OnClickListener clickToDecryptListener = new OnClickListener() { - - @Override - public void onClick(View v) { - Log.d("gultsch","clicked to decrypt"); - if (askForPassphraseIntent!=null) { - try { - getActivity().startIntentSenderForResult(askForPassphraseIntent, ConversationActivity.REQUEST_DECRYPT_PGP, null, 0, 0, 0); - } catch (SendIntentException e) { - Log.d("gultsch","couldnt fire intent"); - } - } - } - }; - private LinearLayout pgpInfo; - - public void hidePgpPassphraseBox() { - pgpInfo.setVisibility(View.GONE); - } - - public void updateChatMsgHint() { - if (conversation.getMode() == Conversation.MODE_MULTI) { - chatMsg.setHint("Send message to conference"); - } else { - switch (conversation.nextMessageEncryption) { - case Message.ENCRYPTION_NONE: - chatMsg.setHint("Send plain text message"); - break; - case Message.ENCRYPTION_OTR: - chatMsg.setHint("Send OTR encrypted message"); - break; - case Message.ENCRYPTION_PGP: - chatMsg.setHint("Send openPGP encryted messeage"); - break; - case Message.ENCRYPTION_DECRYPTED: - chatMsg.setHint("Send openPGP encryted messeage"); - break; - default: - break; - } - } - } - - @Override - public View onCreateView(final LayoutInflater inflater, - ViewGroup container, Bundle savedInstanceState) { - - this.inflater = inflater; - - final View view = inflater.inflate(R.layout.fragment_conversation, - container, false); - chatMsg = (EditText) view.findViewById(R.id.textinput); - ImageButton sendButton = (ImageButton) view - .findViewById(R.id.textSendButton); - sendButton.setOnClickListener(this.sendMsgListener); - - pgpInfo = (LinearLayout) view.findViewById(R.id.pgp_keyentry); - pgpInfo.setOnClickListener(clickToDecryptListener); - - messagesView = (ListView) view.findViewById(R.id.messages_view); - - messageListAdapter = new ArrayAdapter<Message>(this.getActivity() - .getApplicationContext(), R.layout.message_sent, - this.messageList) { - - private static final int SENT = 0; - private static final int RECIEVED = 1; - private static final int ERROR = 2; - - @Override - public int getViewTypeCount() { - return 3; - } - - @Override - public int getItemViewType(int position) { - if (getItem(position).getStatus() == Message.STATUS_RECIEVED) { - return RECIEVED; - } else if (getItem(position).getStatus() == Message.STATUS_ERROR) { - return ERROR; - } else { - return SENT; - } - } - - @Override - public View getView(int position, View view, ViewGroup parent) { - Message item = getItem(position); - int type = getItemViewType(position); - ViewHolder viewHolder; - if (view == null) { - viewHolder = new ViewHolder(); - switch (type) { - case SENT: - view = (View) inflater.inflate(R.layout.message_sent, - null); - viewHolder.imageView = (ImageView) view - .findViewById(R.id.message_photo); - viewHolder.imageView.setImageBitmap(selfBitmap); - break; - case RECIEVED: - view = (View) inflater.inflate( - R.layout.message_recieved, null); - viewHolder.imageView = (ImageView) view - .findViewById(R.id.message_photo); - if (item.getConversation().getMode() == Conversation.MODE_SINGLE) { - Uri uri = item.getConversation() - .getProfilePhotoUri(); - if (uri != null) { - viewHolder.imageView - .setImageBitmap(mBitmapCache.get(item - .getConversation().getName(), - uri)); - } else { - viewHolder.imageView - .setImageBitmap(mBitmapCache.get(item - .getConversation().getName(), - null)); - } - } - break; - case ERROR: - view = (View) inflater.inflate(R.layout.message_error, - null); - viewHolder.imageView = (ImageView) view - .findViewById(R.id.message_photo); - viewHolder.imageView.setImageBitmap(mBitmapCache - .getError()); - break; - default: - viewHolder = null; - break; - } - viewHolder.messageBody = (TextView) view - .findViewById(R.id.message_body); - viewHolder.time = (TextView) view - .findViewById(R.id.message_time); - view.setTag(viewHolder); - } else { - viewHolder = (ViewHolder) view.getTag(); - } - if (type == RECIEVED) { - if (item.getConversation().getMode() == Conversation.MODE_MULTI) { - if (item.getCounterpart() != null) { - viewHolder.imageView.setImageBitmap(mBitmapCache - .get(item.getCounterpart(), null)); - } else { - viewHolder.imageView - .setImageBitmap(mBitmapCache.get(item - .getConversation().getName(), null)); - } - } - } - String body = item.getBody(); - if (body != null) { - if (item.getEncryption() == Message.ENCRYPTION_PGP) { - viewHolder.messageBody.setText(getString(R.string.encrypted_message)); - viewHolder.messageBody.setTextColor(0xff33B5E5); - viewHolder.messageBody.setTypeface(null,Typeface.ITALIC); - } else { - viewHolder.messageBody.setText(body.trim()); - viewHolder.messageBody.setTextColor(0xff000000); - viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); - } - } - if (item.getStatus() == Message.STATUS_UNSEND) { - viewHolder.time.setTypeface(null, Typeface.ITALIC); - viewHolder.time.setText("sending\u2026"); - } else { - viewHolder.time.setTypeface(null, Typeface.NORMAL); - if ((item.getConversation().getMode() == Conversation.MODE_SINGLE) - || (type != RECIEVED)) { - viewHolder.time.setText(UIHelper - .readableTimeDifference(item.getTimeSent())); - } else { - viewHolder.time.setText(item.getCounterpart() - + " \u00B7 " - + UIHelper.readableTimeDifference(item - .getTimeSent())); - } - } - return view; - } - }; - messagesView.setAdapter(messageListAdapter); - - return view; - } - - protected Bitmap findSelfPicture() { - SharedPreferences sharedPref = PreferenceManager - .getDefaultSharedPreferences(getActivity() - .getApplicationContext()); - boolean showPhoneSelfContactPicture = sharedPref.getBoolean( - "show_phone_selfcontact_picture", true); - - Bitmap self = null; - - if (showPhoneSelfContactPicture) { - Uri selfiUri = PhoneHelper.getSefliUri(getActivity()); - if (selfiUri != null) { - try { - self = BitmapFactory.decodeStream(getActivity() - .getContentResolver().openInputStream(selfiUri)); - } catch (FileNotFoundException e) { - self = null; - } - } - } - if (self == null) { - self = UIHelper.getUnknownContactPicture(conversation.getAccount() - .getJid(), 200); - } - - final Bitmap selfBitmap = self; - return selfBitmap; - } - - @Override - public void onStart() { - super.onStart(); - ConversationActivity activity = (ConversationActivity) getActivity(); - - if (activity.xmppConnectionServiceBound) { - this.onBackendConnected(); - } - } - - public void onBackendConnected() { - final ConversationActivity activity = (ConversationActivity) getActivity(); - this.conversation = activity.getSelectedConversation(); - this.selfBitmap = findSelfPicture(); - updateMessages(); - // rendering complete. now go tell activity to close pane - if (!activity.shouldPaneBeOpen()) { - activity.getSlidingPaneLayout().closePane(); - activity.getActionBar().setDisplayHomeAsUpEnabled(true); - activity.getActionBar().setTitle(conversation.getName()); - activity.invalidateOptionsMenu(); - if (!conversation.isRead()) { - conversation.markRead(); - activity.updateConversationList(); - } - } - if (queuedPqpMessage != null) { - this.conversation.nextMessageEncryption = Message.ENCRYPTION_PGP; - Message message = new Message(conversation, queuedPqpMessage, - Message.ENCRYPTION_PGP); - sendPgpMessage(message); - } - } - - public void updateMessages() { - ConversationActivity activity = (ConversationActivity) getActivity(); - List<Message> encryptedMessages = new LinkedList<Message>(); - for(Message message : this.conversation.getMessages()) { - if (message.getEncryption() == Message.ENCRYPTION_PGP) { - encryptedMessages.add(message); - } - } - if (encryptedMessages.size() > 0) { - DecryptMessage task = new DecryptMessage(); - Message[] msgs = new Message[encryptedMessages.size()]; - task.execute(encryptedMessages.toArray(msgs)); - } - this.messageList.clear(); - this.messageList.addAll(this.conversation.getMessages()); - this.messageListAdapter.notifyDataSetChanged(); - if (messageList.size() >= 1) { - int latestEncryption = this.conversation.getLatestMessage() - .getEncryption(); - if (latestEncryption== Message.ENCRYPTION_DECRYPTED) { - conversation.nextMessageEncryption = Message.ENCRYPTION_PGP; - } else { - conversation.nextMessageEncryption = latestEncryption; - } - makeFingerprintWarning(latestEncryption); - } - getActivity().invalidateOptionsMenu(); - updateChatMsgHint(); - int size = this.messageList.size(); - if (size >= 1) - messagesView.setSelection(size - 1); - if (!activity.shouldPaneBeOpen()) { - conversation.markRead(); - activity.updateConversationList(); - } - } - - protected void makeFingerprintWarning(int latestEncryption) { - final LinearLayout fingerprintWarning = (LinearLayout) getView() - .findViewById(R.id.new_fingerprint); - if (conversation.getContact() != null) { - Set<String> knownFingerprints = conversation.getContact() - .getOtrFingerprints(); - if ((latestEncryption == Message.ENCRYPTION_OTR) - && (conversation.hasValidOtrSession() - && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!knownFingerprints - .contains(conversation.getOtrFingerprint())))) { - fingerprintWarning.setVisibility(View.VISIBLE); - TextView fingerprint = (TextView) getView().findViewById( - R.id.otr_fingerprint); - fingerprint.setText(conversation.getOtrFingerprint()); - fingerprintWarning.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - AlertDialog dialog = UIHelper - .getVerifyFingerprintDialog( - (ConversationActivity) getActivity(), - conversation, fingerprintWarning); - dialog.show(); - } - }); - } else { - fingerprintWarning.setVisibility(View.GONE); - } - } else { - fingerprintWarning.setVisibility(View.GONE); - } - } - - protected void sendPlainTextMessage(Message message) { - ConversationActivity activity = (ConversationActivity) getActivity(); - activity.xmppConnectionService.sendMessage(message, null); - chatMsg.setText(""); - } - - protected void sendPgpMessage(final Message message) { - ConversationActivity activity = (ConversationActivity) getActivity(); - final XmppConnectionService xmppService = activity.xmppConnectionService; - Contact contact = message.getConversation().getContact(); - if (contact.getPgpKeyId() != 0) { - xmppService.sendMessage(message, null); - chatMsg.setText(""); - } else { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setTitle("No openPGP key found"); - builder.setIconAttribute(android.R.attr.alertDialogIcon); - builder.setMessage("There is no openPGP key assoziated with this contact"); - builder.setNegativeButton("Cancel", null); - builder.setPositiveButton("Send plain text", - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - conversation.nextMessageEncryption = Message.ENCRYPTION_NONE; - message.setEncryption(Message.ENCRYPTION_NONE); - xmppService.sendMessage(message, null); - chatMsg.setText(""); - } - }); - builder.create().show(); - } - } - - public void resendPgpMessage(String msg) { - this.queuedPqpMessage = msg; - } - - protected void sendOtrMessage(final Message message) { - ConversationActivity activity = (ConversationActivity) getActivity(); - final XmppConnectionService xmppService = activity.xmppConnectionService; - if (conversation.hasValidOtrSession()) { - activity.xmppConnectionService.sendMessage(message, null); - chatMsg.setText(""); - } else { - Hashtable<String, Integer> presences; - if (conversation.getContact() != null) { - presences = conversation.getContact().getPresences(); - } else { - presences = null; - } - if ((presences == null) || (presences.size() == 0)) { - AlertDialog.Builder builder = new AlertDialog.Builder( - getActivity()); - builder.setTitle("Contact is offline"); - builder.setIconAttribute(android.R.attr.alertDialogIcon); - builder.setMessage("Sending OTR encrypted messages to an offline contact is impossible."); - builder.setPositiveButton("Send plain text", - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - conversation.nextMessageEncryption = Message.ENCRYPTION_NONE; - message.setEncryption(Message.ENCRYPTION_NONE); - xmppService.sendMessage(message, null); - chatMsg.setText(""); - } - }); - builder.setNegativeButton("Cancel", null); - builder.create().show(); - } else if (presences.size() == 1) { - xmppService.sendMessage(message, (String) presences.keySet() - .toArray()[0]); - chatMsg.setText(""); - } else { - AlertDialog.Builder builder = new AlertDialog.Builder( - getActivity()); - builder.setTitle("Choose Presence"); - final String[] presencesArray = new String[presences.size()]; - presences.keySet().toArray(presencesArray); - builder.setItems(presencesArray, - new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, - int which) { - xmppService.sendMessage(message, - presencesArray[which]); - chatMsg.setText(""); - } - }); - builder.create().show(); - } - } - } - - private static class ViewHolder { - - protected TextView time; - protected TextView messageBody; - protected ImageView imageView; - - } - - private class BitmapCache { - private HashMap<String, Bitmap> bitmaps = new HashMap<String, Bitmap>(); - private Bitmap error = null; - - public Bitmap get(String name, Uri uri) { - if (bitmaps.containsKey(name)) { - return bitmaps.get(name); - } else { - Bitmap bm; - if (uri != null) { - try { - bm = BitmapFactory.decodeStream(getActivity() - .getContentResolver().openInputStream(uri)); - } catch (FileNotFoundException e) { - bm = UIHelper.getUnknownContactPicture(name, 200); - } - } else { - bm = UIHelper.getUnknownContactPicture(name, 200); - } - bitmaps.put(name, bm); - return bm; - } - } - - public Bitmap getError() { - if (error == null) { - error = UIHelper.getErrorPicture(200); - } - return error; - } - } - - class DecryptMessage extends AsyncTask<Message, Void, Boolean> { - - @Override - protected Boolean doInBackground(Message... params) { - final ConversationActivity activity = (ConversationActivity) getActivity(); - askForPassphraseIntent = null; - for(int i = 0; i < params.length; ++i) { - if (params[i].getEncryption() == Message.ENCRYPTION_PGP) { - String body = params[i].getBody(); - String decrypted = null; - try { - if (activity==null) { - return false; - } - Log.d("gultsch","calling to decrypt message id #"+params[i].getUuid()); - decrypted = activity.xmppConnectionService.getPgpEngine().decrypt(body); - } catch (UserInputRequiredException e) { - askForPassphraseIntent = e.getPendingIntent().getIntentSender(); - activity.runOnUiThread(new Runnable() { - - @Override - public void run() { - pgpInfo.setVisibility(View.VISIBLE); - } - }); - - return false; - - } catch (OpenPgpException e) { - Log.d("gultsch","error decrypting pgp"); - } - if (decrypted!=null) { - params[i].setBody(decrypted); - params[i].setEncryption(Message.ENCRYPTION_DECRYPTED); - activity.xmppConnectionService.updateMessage(params[i]); - } - if (activity!=null) { - activity.runOnUiThread(new Runnable() { - - @Override - public void run() { - messageListAdapter.notifyDataSetChanged(); - } - }); - } - } - if (activity!=null) { - activity.runOnUiThread(new Runnable() { - - @Override - public void run() { - activity.updateConversationList(); - } - }); - } - } - return true; - } - - } -} diff --git a/src/de/gultsch/chat/ui/DialogContactDetails.java b/src/de/gultsch/chat/ui/DialogContactDetails.java deleted file mode 100644 index 324a7aac..00000000 --- a/src/de/gultsch/chat/ui/DialogContactDetails.java +++ /dev/null @@ -1,219 +0,0 @@ -package de.gultsch.chat.ui; - -import de.gultsch.chat.R; -import de.gultsch.chat.entities.Contact; -import de.gultsch.chat.entities.Presences; -import de.gultsch.chat.utils.UIHelper; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Bundle; -import android.provider.ContactsContract.CommonDataKinds; -import android.provider.ContactsContract.Contacts; -import android.provider.ContactsContract.Intents; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.CheckBox; -import android.widget.QuickContactBadge; -import android.widget.TextView; - -public class DialogContactDetails extends DialogFragment { - - private Contact contact = null; - boolean displayingInRoster = false; - - private DialogContactDetails mDetailsDialog = this; - private XmppActivity activity; - - private CheckBox send; - private CheckBox receive; - - private DialogInterface.OnClickListener askRemoveFromRoster = new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setTitle("Delete from roster"); - builder.setMessage("Do you want to delete "+contact.getJid()+" from your roster. The conversation assoziated with this account will not be removed."); - builder.setNegativeButton("Cancel", null); - builder.setPositiveButton("Delete",removeFromRoster); - builder.create().show(); - } - }; - - private DialogInterface.OnClickListener removeFromRoster = new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - activity.xmppConnectionService.deleteContact(contact); - mDetailsDialog.dismiss(); - } - }; - - private DialogInterface.OnClickListener addToPhonebook = new DialogInterface.OnClickListener() { - - @Override - 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_PROTOCOL,CommonDataKinds.Im.PROTOCOL_JABBER); - intent.putExtra("finishActivityOnSaveCompleted", true); - getActivity().startActivityForResult(intent,0); - mDetailsDialog.dismiss(); - } - }; - - private DialogInterface.OnClickListener updateSubscriptions = new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - boolean needsUpdating = false; - if (contact.getSubscriptionOption(Contact.Subscription.FROM)) { - if (!send.isChecked()) { - contact.resetSubscriptionOption(Contact.Subscription.FROM); - contact.resetSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT); - activity.xmppConnectionService.stopPresenceUpdatesTo(contact); - needsUpdating=true; - } - } else { - if (contact.getSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT)) { - if (!send.isChecked()) { - contact.resetSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT); - needsUpdating=true; - } - } else { - if (send.isChecked()) { - contact.setSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT); - needsUpdating=true; - } - } - } - if (contact.getSubscriptionOption(Contact.Subscription.TO)) { - if (!receive.isChecked()) { - contact.resetSubscriptionOption(Contact.Subscription.TO); - activity.xmppConnectionService.stopPresenceUpdatesFrom(contact); - needsUpdating=true; - } - } else { - if (contact.getSubscriptionOption(Contact.Subscription.ASKING)) { - if (!receive.isChecked()) { - contact.resetSubscriptionOption(Contact.Subscription.ASKING); - activity.xmppConnectionService.stopPresenceUpdatesFrom(contact); - needsUpdating=true; - } - } else { - if (receive.isChecked()) { - contact.setSubscriptionOption(Contact.Subscription.ASKING); - activity.xmppConnectionService.requestPresenceUpdatesFrom(contact); - needsUpdating=true; - } - } - } - if (needsUpdating) { - activity.xmppConnectionService.updateContact(contact); - } - } - }; - - public void setContact(Contact contact) { - this.contact = contact; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - this.activity = (XmppActivity) getActivity(); - AlertDialog.Builder builder = new AlertDialog.Builder(this.activity); - LayoutInflater inflater = getActivity().getLayoutInflater(); - View view = inflater.inflate(R.layout.dialog_contact_details, null); - TextView contactJid = (TextView) view.findViewById(R.id.details_contactjid); - TextView accountJid = (TextView) view.findViewById(R.id.details_account); - TextView status = (TextView) view.findViewById(R.id.details_contactstatus); - send = (CheckBox) view.findViewById(R.id.details_send_presence); - receive = (CheckBox) view.findViewById(R.id.details_receive_presence); - //ImageView contactPhoto = (ImageView) view.findViewById(R.id.details_contact_picture); - QuickContactBadge badge = (QuickContactBadge) view.findViewById(R.id.details_contact_badge); - - if (contact.getSubscriptionOption(Contact.Subscription.FROM)) { - send.setChecked(true); - } else { - send.setText("Preemptively grant subscription request"); - if (contact.getSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT)) { - send.setChecked(true); - } else { - send.setChecked(false); - } - } - if (contact.getSubscriptionOption(Contact.Subscription.TO)) { - receive.setChecked(true); - } else { - receive.setText("Request presence updates"); - if (contact.getSubscriptionOption(Contact.Subscription.ASKING)) { - receive.setChecked(true); - } else { - receive.setChecked(false); - } - } - - switch (contact.getMostAvailableStatus()) { - case Presences.CHAT: - status.setText("free to chat"); - status.setTextColor(0xFF83b600); - break; - case Presences.ONLINE: - status.setText("online"); - status.setTextColor(0xFF83b600); - break; - case Presences.AWAY: - status.setText("away"); - status.setTextColor(0xFFffa713); - break; - case Presences.XA: - status.setText("extended away"); - status.setTextColor(0xFFffa713); - break; - case Presences.DND: - status.setText("do not disturb"); - status.setTextColor(0xFFe92727); - break; - case Presences.OFFLINE: - status.setText("offline"); - status.setTextColor(0xFFe92727); - break; - default: - status.setText("offline"); - status.setTextColor(0xFFe92727); - break; - } - contactJid.setText(contact.getJid()); - accountJid.setText(contact.getAccount().getJid()); - - UIHelper.prepareContactBadge(getActivity(), badge, contact); - - if (contact.getSystemAccount()==null) { - badge.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setTitle("Add to phone book"); - builder.setMessage("Do you want to add "+contact.getJid()+" to your phones contact list?"); - builder.setNegativeButton("Cancel", null); - builder.setPositiveButton("Add",addToPhonebook); - builder.create().show(); - } - }); - } - - builder.setView(view); - builder.setTitle(contact.getDisplayName()); - - builder.setNeutralButton("Done", this.updateSubscriptions); - builder.setPositiveButton("Remove from roster", this.askRemoveFromRoster); - return builder.create(); - } -} diff --git a/src/de/gultsch/chat/ui/EditAccount.java b/src/de/gultsch/chat/ui/EditAccount.java deleted file mode 100644 index 88aa76f5..00000000 --- a/src/de/gultsch/chat/ui/EditAccount.java +++ /dev/null @@ -1,141 +0,0 @@ -package de.gultsch.chat.ui; - -import de.gultsch.chat.R; -import de.gultsch.chat.entities.Account; -import de.gultsch.chat.utils.Validator; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.EditText; -import android.widget.RelativeLayout; -import android.widget.TextView; - -public class EditAccount extends DialogFragment { - - protected Account account; - - public void setAccount(Account account) { - this.account = account; - } - - public interface EditAccountListener { - public void onAccountEdited(Account account); - } - - protected EditAccountListener listener = null; - - public void setEditAccountListener(EditAccountListener listener) { - this.listener = listener; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - LayoutInflater inflater = getActivity().getLayoutInflater(); - View view = inflater.inflate(R.layout.edit_account_dialog, null); - final EditText jidText = (EditText) view.findViewById(R.id.account_jid); - final TextView confirmPwDesc = (TextView) view - .findViewById(R.id.account_confirm_password_desc); - CheckBox useTLS = (CheckBox) view.findViewById(R.id.account_usetls); - - final EditText password = (EditText) view - .findViewById(R.id.account_password); - final EditText passwordConfirm = (EditText) view - .findViewById(R.id.account_password_confirm2); - final CheckBox registerAccount = (CheckBox) view - .findViewById(R.id.edit_account_register_new); - - final String okButtonDesc; - - if (account != null) { - builder.setTitle("Edit account"); - registerAccount.setVisibility(View.GONE); - jidText.setText(account.getJid()); - password.setText(account.getPassword()); - okButtonDesc = "Edit"; - if (account.isOptionSet(Account.OPTION_USETLS)) { - useTLS.setChecked(true); - } else { - useTLS.setChecked(false); - } - } else { - builder.setTitle("Add account"); - okButtonDesc = "Add"; - } - - registerAccount - .setOnCheckedChangeListener(new OnCheckedChangeListener() { - - @Override - public void onCheckedChanged(CompoundButton buttonView, - boolean isChecked) { - AlertDialog d = (AlertDialog) getDialog(); - Button positiveButton = (Button) d - .getButton(Dialog.BUTTON_POSITIVE); - if (isChecked) { - positiveButton.setText("Register"); - passwordConfirm.setVisibility(View.VISIBLE); - confirmPwDesc.setVisibility(View.VISIBLE); - } else { - passwordConfirm.setVisibility(View.GONE); - positiveButton.setText("Add"); - confirmPwDesc.setVisibility(View.GONE); - } - } - }); - - builder.setView(view); - builder.setNeutralButton("Cancel", null); - builder.setPositiveButton(okButtonDesc, null); - return builder.create(); - } - - @Override - public void onStart() { - super.onStart(); - final AlertDialog d = (AlertDialog) getDialog(); - Button positiveButton = (Button) d.getButton(Dialog.BUTTON_POSITIVE); - positiveButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - EditText jidEdit = (EditText) d.findViewById(R.id.account_jid); - String jid = jidEdit.getText().toString(); - EditText passwordEdit = (EditText) d - .findViewById(R.id.account_password); - String password = passwordEdit.getText().toString(); - CheckBox useTLS = (CheckBox) d.findViewById(R.id.account_usetls); - String username; - String server; - if (Validator.isValidJid(jid)) { - String[] parts = jid.split("@"); - username = parts[0]; - server = parts[1]; - } else { - jidEdit.setError("Invalid Jabber ID"); - return; - } - if (account != null) { - account.setPassword(password); - account.setUsername(username); - account.setServer(server); - } else { - account = new Account(username, server, password); - } - account.setOption(Account.OPTION_USETLS, useTLS.isChecked()); - if (listener != null) { - listener.onAccountEdited(account); - d.dismiss(); - } - } - }); - } -} diff --git a/src/de/gultsch/chat/ui/ManageAccountActivity.java b/src/de/gultsch/chat/ui/ManageAccountActivity.java deleted file mode 100644 index bcc5306d..00000000 --- a/src/de/gultsch/chat/ui/ManageAccountActivity.java +++ /dev/null @@ -1,312 +0,0 @@ -package de.gultsch.chat.ui; - -import java.util.ArrayList; -import java.util.List; - -import de.gultsch.chat.R; -import de.gultsch.chat.crypto.PgpEngine; -import de.gultsch.chat.crypto.PgpEngine.UserInputRequiredException; -import de.gultsch.chat.entities.Account; -import de.gultsch.chat.ui.EditAccount.EditAccountListener; -import android.app.Activity; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.content.IntentSender.SendIntentException; -import android.os.Bundle; -import android.util.Log; -import android.view.ActionMode; -import android.view.ActionMode.Callback; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.ArrayAdapter; -import android.widget.ListView; -import android.widget.TextView; - -public class ManageAccountActivity extends XmppActivity implements ActionMode.Callback { - - public static final int REQUEST_ANNOUNCE_PGP = 0x73731; - - protected boolean isActionMode = false; - protected ActionMode actionMode; - protected Account selectedAccountForActionMode = null; - - protected List<Account> accountList = new ArrayList<Account>(); - protected ListView accountListView; - protected ArrayAdapter<Account> accountListViewAdapter; - protected OnAccountListChangedListener accountChanged = new OnAccountListChangedListener() { - - @Override - public void onAccountListChangedListener() { - Log.d("xmppService", "ui on account list changed listener"); - accountList.clear(); - accountList.addAll(xmppConnectionService.getAccounts()); - runOnUiThread(new Runnable() { - - @Override - public void run() { - if (accountList.size() == 1) { - startActivity(new Intent(getApplicationContext(), - NewConversationActivity.class)); - } - accountListViewAdapter.notifyDataSetChanged(); - } - }); - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - - super.onCreate(savedInstanceState); - - setContentView(R.layout.manage_accounts); - - accountListView = (ListView) findViewById(R.id.account_list); - accountListViewAdapter = new ArrayAdapter<Account>( - getApplicationContext(), R.layout.account_row, this.accountList) { - @Override - public View getView(int position, View view, ViewGroup parent) { - Account account = getItem(position); - if (view == null) { - LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = (View) inflater.inflate(R.layout.account_row, null); - } - ((TextView) view.findViewById(R.id.account_jid)) - .setText(account.getJid()); - TextView statusView = (TextView) view - .findViewById(R.id.account_status); - switch (account.getStatus()) { - case Account.STATUS_DISABLED: - statusView.setText("temporarily disabled"); - statusView.setTextColor(0xFF1da9da); - break; - case Account.STATUS_ONLINE: - statusView.setText("online"); - statusView.setTextColor(0xFF83b600); - break; - case Account.STATUS_OFFLINE: - statusView.setText("offline"); - statusView.setTextColor(0xFFe92727); - break; - case Account.STATUS_UNAUTHORIZED: - statusView.setText("unauthorized"); - statusView.setTextColor(0xFFe92727); - break; - case Account.STATUS_SERVER_NOT_FOUND: - statusView.setText("server not found"); - statusView.setTextColor(0xFFe92727); - break; - default: - break; - } - - return view; - } - }; - final Activity activity = this; - accountListView.setAdapter(this.accountListViewAdapter); - accountListView.setOnItemClickListener(new OnItemClickListener() { - - @Override - public void onItemClick(AdapterView<?> arg0, View view, - int position, long arg3) { - if (!isActionMode) { - EditAccount dialog = new EditAccount(); - dialog.setAccount(accountList.get(position)); - dialog.setEditAccountListener(new EditAccountListener() { - - @Override - public void onAccountEdited(Account account) { - xmppConnectionService.updateAccount(account); - } - }); - dialog.show(getFragmentManager(), "edit_account"); - } else { - selectedAccountForActionMode = accountList.get(position); - actionMode.invalidate(); - } - } - }); - accountListView.setOnItemLongClickListener(new OnItemLongClickListener() { - - @Override - public boolean onItemLongClick(AdapterView<?> arg0, View view, - int position, long arg3) { - if (!isActionMode) { - accountListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); - accountListView.setItemChecked(position,true); - selectedAccountForActionMode = accountList.get(position); - actionMode = activity.startActionMode((Callback) activity); - return true; - } else { - return false; - } - } - }); - } - - @Override - protected void onStop() { - if (xmppConnectionServiceBound) { - xmppConnectionService.removeOnAccountListChangedListener(); - } - super.onStop(); - } - - @Override - void onBackendConnected() { - xmppConnectionService.setOnAccountListChangedListener(accountChanged); - this.accountList.clear(); - this.accountList.addAll(xmppConnectionService.getAccounts()); - accountListViewAdapter.notifyDataSetChanged(); - if (this.accountList.size() == 0) { - getActionBar().setDisplayHomeAsUpEnabled(false); - addAccount(); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.manageaccounts, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.action_settings: - startActivity(new Intent(this, SettingsActivity.class)); - break; - case R.id.action_add_account: - addAccount(); - break; - default: - break; - } - return super.onOptionsItemSelected(item); - } - - protected void addAccount() { - final Activity activity = this; - EditAccount dialog = new EditAccount(); - dialog.setEditAccountListener(new EditAccountListener() { - - @Override - public void onAccountEdited(Account account) { - xmppConnectionService.createAccount(account); - activity.getActionBar().setDisplayHomeAsUpEnabled(true); - } - }); - dialog.show(getFragmentManager(), "add_account"); - } - - @Override - public boolean onActionItemClicked(final ActionMode mode, MenuItem item) { - if (item.getItemId()==R.id.account_disable) { - selectedAccountForActionMode.setOption(Account.OPTION_DISABLED, true); - xmppConnectionService.updateAccount(selectedAccountForActionMode); - mode.finish(); - } else if (item.getItemId()==R.id.account_enable) { - selectedAccountForActionMode.setOption(Account.OPTION_DISABLED, false); - xmppConnectionService.updateAccount(selectedAccountForActionMode); - mode.finish(); - } else if (item.getItemId()==R.id.account_delete) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle("Are you sure?"); - builder.setIconAttribute(android.R.attr.alertDialogIcon); - builder.setMessage("If you delete your account your entire conversation history will be lost"); - builder.setPositiveButton("Delete", new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - xmppConnectionService.deleteAccount(selectedAccountForActionMode); - selectedAccountForActionMode = null; - mode.finish(); - } - }); - builder.setNegativeButton("Cancel",null); - builder.create().show(); - } else if (item.getItemId()==R.id.announce_pgp) { - mode.finish(); - try { - xmppConnectionService.generatePgpAnnouncement(selectedAccountForActionMode); - } catch (PgpEngine.UserInputRequiredException e) { - try { - startIntentSenderForResult(e.getPendingIntent().getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0); - } catch (SendIntentException e1) { - Log.d("gultsch","sending intent failed"); - } - } - } - return true; - } - - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - MenuInflater inflater = mode.getMenuInflater(); - inflater.inflate(R.menu.manageaccounts_context, menu); - return true; - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - // TODO Auto-generated method stub - - } - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - if (selectedAccountForActionMode.isOptionSet(Account.OPTION_DISABLED)) { - menu.findItem(R.id.account_enable).setVisible(true); - menu.findItem(R.id.account_disable).setVisible(false); - } else { - menu.findItem(R.id.account_disable).setVisible(true); - menu.findItem(R.id.account_enable).setVisible(false); - } - return true; - } - - @Override - public void onActionModeStarted(ActionMode mode) { - super.onActionModeStarted(mode); - this.isActionMode = true; - } - - @Override - public void onActionModeFinished(ActionMode mode) { - super.onActionModeFinished(mode); - this.isActionMode = false; - accountListView.clearChoices(); - accountListView.requestLayout(); - accountListView.post(new Runnable() { - @Override - public void run() { - accountListView.setChoiceMode(ListView.CHOICE_MODE_NONE); - } - }); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (resultCode == RESULT_OK) { - if (requestCode == REQUEST_ANNOUNCE_PGP) { - try { - xmppConnectionService.generatePgpAnnouncement(selectedAccountForActionMode); - } catch (UserInputRequiredException e) { - Log.d("gultsch","already came back. ignoring"); - } - } - } - } -} diff --git a/src/de/gultsch/chat/ui/NewConversationActivity.java b/src/de/gultsch/chat/ui/NewConversationActivity.java deleted file mode 100644 index ac178fad..00000000 --- a/src/de/gultsch/chat/ui/NewConversationActivity.java +++ /dev/null @@ -1,338 +0,0 @@ -package de.gultsch.chat.ui; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import de.gultsch.chat.R; -import de.gultsch.chat.entities.Account; -import de.gultsch.chat.entities.Contact; -import de.gultsch.chat.entities.Conversation; -import de.gultsch.chat.utils.UIHelper; -import de.gultsch.chat.utils.Validator; -import android.net.Uri; -import android.os.Bundle; -import android.provider.ContactsContract; -import android.text.Editable; -import android.text.TextWatcher; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.ArrayAdapter; -import android.widget.EditText; -import android.widget.ListView; -import android.widget.ProgressBar; -import android.widget.TextView; -import android.widget.ImageView; -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.AlertDialog; -import android.content.Context; -import android.content.CursorLoader; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.content.Loader; -import android.content.Loader.OnLoadCompleteListener; -import android.database.Cursor; - -public class NewConversationActivity extends XmppActivity { - - protected List<Contact> phoneContacts = new ArrayList<Contact>(); - protected List<Contact> rosterContacts = new ArrayList<Contact>(); - protected List<Contact> aggregatedContacts = new ArrayList<Contact>(); - protected ListView contactsView; - protected ArrayAdapter<Contact> contactsAdapter; - - protected EditText search; - protected String searchString = ""; - private TextView contactsHeader; - private List<Account> accounts; - - protected void updateAggregatedContacts() { - - aggregatedContacts.clear(); - for (Contact contact : rosterContacts) { - if (contact.match(searchString)) - aggregatedContacts.add(contact); - } - - Collections.sort(aggregatedContacts, new Comparator<Contact>() { - - @SuppressLint("DefaultLocale") - @Override - public int compare(Contact lhs, Contact rhs) { - return lhs.getDisplayName().toLowerCase() - .compareTo(rhs.getDisplayName().toLowerCase()); - } - }); - - if (aggregatedContacts.size() == 0) { - - if (Validator.isValidJid(searchString)) { - String name = searchString.split("@")[0]; - Contact newContact = new Contact(null, name, searchString, null); - newContact.flagAsNotInRoster(); - aggregatedContacts.add(newContact); - contactsHeader.setText("Create new contact"); - } else { - contactsHeader.setText("Contacts"); - } - } else { - contactsHeader.setText("Contacts"); - } - - contactsAdapter.notifyDataSetChanged(); - contactsView.setScrollX(0); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_new_conversation); - - contactsHeader = (TextView) findViewById(R.id.contacts_header); - - search = (EditText) findViewById(R.id.new_conversation_search); - search.addTextChangedListener(new TextWatcher() { - - @Override - public void onTextChanged(CharSequence s, int start, int before, - int count) { - searchString = search.getText().toString(); - updateAggregatedContacts(); - } - - @Override - public void afterTextChanged(Editable s) { - // TODO Auto-generated method stub - - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, - int after) { - // TODO Auto-generated method stub - - } - }); - - contactsView = (ListView) findViewById(R.id.contactList); - contactsAdapter = new ArrayAdapter<Contact>(getApplicationContext(), - R.layout.contact, aggregatedContacts) { - @Override - public View getView(int position, View view, ViewGroup parent) { - LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - Contact contact = getItem(position); - if (view == null) { - view = (View) inflater.inflate(R.layout.contact, null); - } - - ((TextView) view.findViewById(R.id.contact_display_name)) - .setText(getItem(position).getDisplayName()); - TextView contactJid = (TextView) view - .findViewById(R.id.contact_jid); - contactJid.setText(contact.getJid()); - String profilePhoto = getItem(position).getProfilePhoto(); - ImageView imageView = (ImageView) view - .findViewById(R.id.contact_photo); - if (profilePhoto != null) { - imageView.setImageURI(Uri.parse(profilePhoto)); - } else { - imageView.setImageBitmap(UIHelper.getUnknownContactPicture( - getItem(position).getDisplayName(), 90)); - } - return view; - } - }; - contactsView.setAdapter(contactsAdapter); - final Activity activity = this; - contactsView.setOnItemClickListener(new OnItemClickListener() { - - @Override - public void onItemClick(AdapterView<?> arg0, final View view, - int pos, long arg3) { - final Contact clickedContact = aggregatedContacts.get(pos); - - if ((clickedContact.getAccount()==null)&&(accounts.size()>1)) { - String[] accountList = new String[accounts.size()]; - for (int i = 0; i < accounts.size(); ++i) { - accountList[i] = accounts.get(i).getJid(); - } - - AlertDialog.Builder accountChooser = new AlertDialog.Builder( - activity); - accountChooser.setTitle("Choose account"); - accountChooser.setItems(accountList, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - clickedContact.setAccount(accounts.get(which)); - showIsMucDialogIfNeeded(clickedContact); - } - }); - accountChooser.create().show(); - } else { - if (clickedContact.getAccount()==null) { - clickedContact.setAccount(accounts.get(0)); - } - showIsMucDialogIfNeeded(clickedContact); - } - } - }); - contactsView.setOnItemLongClickListener(new OnItemLongClickListener() { - - @Override - public boolean onItemLongClick(AdapterView<?> arg0, View arg1, - int pos, long arg3) { - Contact clickedContact = aggregatedContacts.get(pos); - DialogContactDetails dialog = new DialogContactDetails(); - dialog.setContact(clickedContact); - dialog.show(getFragmentManager(), "details"); - return true; - } - }); - } - - public void showIsMucDialogIfNeeded(final Contact clickedContact) { - if (clickedContact.couldBeMuc()) { - AlertDialog.Builder dialog = new AlertDialog.Builder(this); - dialog.setTitle("Multi User Conference"); - dialog.setMessage("Are you trying to join a conference?"); - dialog.setPositiveButton("Yes", new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - startConversation(clickedContact, clickedContact.getAccount(),true); - } - }); - dialog.setNegativeButton("No", new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - startConversation(clickedContact, clickedContact.getAccount(),false); - } - }); - dialog.create().show(); - } else { - startConversation(clickedContact, clickedContact.getAccount(),false); - } - } - - public void startConversation(Contact contact, Account account, boolean muc) { - if (!contact.isInRoster()) { - xmppConnectionService.createContact(contact); - } - Conversation conversation = xmppConnectionService - .findOrCreateConversation(account, contact.getJid(), muc); - - Intent viewConversationIntent = new Intent(this, - ConversationActivity.class); - viewConversationIntent.setAction(Intent.ACTION_VIEW); - viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, - conversation.getUuid()); - viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION); - viewConversationIntent.setFlags(viewConversationIntent.getFlags() - | Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivity(viewConversationIntent); - } - - @Override - void onBackendConnected() { - if (xmppConnectionService.getConversationCount() == 0) { - getActionBar().setDisplayHomeAsUpEnabled(false); - getActionBar().setHomeButtonEnabled(false); - } - this.accounts = xmppConnectionService.getAccounts(); - this.rosterContacts.clear(); - for (int i = 0; i < accounts.size(); ++i) { - xmppConnectionService.getRoster(accounts.get(i), - new OnRosterFetchedListener() { - - @Override - public void onRosterFetched(List<Contact> roster) { - rosterContacts.addAll(roster); - runOnUiThread(new Runnable() { - - @Override - public void run() { - updateAggregatedContacts(); - } - }); - - } - }); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.newconversation, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.action_settings: - startActivity(new Intent(this, SettingsActivity.class)); - break; - case R.id.action_accounts: - startActivity(new Intent(this, ManageAccountActivity.class)); - break; - case R.id.action_refresh_contacts: - refreshContacts(); - break; - default: - break; - } - return super.onOptionsItemSelected(item); - } - - private void refreshContacts() { - final ProgressBar progress = (ProgressBar) findViewById(R.id.progressBar1); - final EditText searchBar = (EditText) findViewById(R.id.new_conversation_search); - final TextView contactsHeader = (TextView) findViewById(R.id.contacts_header); - final ListView contactList = (ListView) findViewById(R.id.contactList); - searchBar.setVisibility(View.GONE); - contactsHeader.setVisibility(View.GONE); - contactList.setVisibility(View.GONE); - progress.setVisibility(View.VISIBLE); - this.accounts = xmppConnectionService.getAccounts(); - this.rosterContacts.clear(); - for (int i = 0; i < accounts.size(); ++i) { - if (accounts.get(i).getStatus() == Account.STATUS_ONLINE) { - xmppConnectionService.updateRoster(accounts.get(i), - new OnRosterFetchedListener() { - - @Override - public void onRosterFetched( - final List<Contact> roster) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - rosterContacts.addAll(roster); - progress.setVisibility(View.GONE); - searchBar.setVisibility(View.VISIBLE); - contactList.setVisibility(View.VISIBLE); - contactList.setVisibility(View.VISIBLE); - updateAggregatedContacts(); - } - }); - } - }); - } - } - } -} diff --git a/src/de/gultsch/chat/ui/OnAccountListChangedListener.java b/src/de/gultsch/chat/ui/OnAccountListChangedListener.java deleted file mode 100644 index 4af5ac9b..00000000 --- a/src/de/gultsch/chat/ui/OnAccountListChangedListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package de.gultsch.chat.ui; - -public interface OnAccountListChangedListener { - public void onAccountListChangedListener(); -} diff --git a/src/de/gultsch/chat/ui/OnConversationListChangedListener.java b/src/de/gultsch/chat/ui/OnConversationListChangedListener.java deleted file mode 100644 index 08b2bfb1..00000000 --- a/src/de/gultsch/chat/ui/OnConversationListChangedListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package de.gultsch.chat.ui; - -public interface OnConversationListChangedListener { - public void onConversationListChanged(); -} diff --git a/src/de/gultsch/chat/ui/OnRosterFetchedListener.java b/src/de/gultsch/chat/ui/OnRosterFetchedListener.java deleted file mode 100644 index ad3f6592..00000000 --- a/src/de/gultsch/chat/ui/OnRosterFetchedListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.gultsch.chat.ui; - -import java.util.List; -import de.gultsch.chat.entities.Contact; - -public interface OnRosterFetchedListener { - public void onRosterFetched(List<Contact> roster); -} diff --git a/src/de/gultsch/chat/ui/SettingsActivity.java b/src/de/gultsch/chat/ui/SettingsActivity.java deleted file mode 100644 index 886c05cc..00000000 --- a/src/de/gultsch/chat/ui/SettingsActivity.java +++ /dev/null @@ -1,16 +0,0 @@ -package de.gultsch.chat.ui; - -import android.app.Activity; -import android.os.Bundle; - -public class SettingsActivity extends Activity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // Display the fragment as the main content. - getFragmentManager().beginTransaction() - .replace(android.R.id.content, new SettingsFragment()).commit(); - } - -} diff --git a/src/de/gultsch/chat/ui/SettingsFragment.java b/src/de/gultsch/chat/ui/SettingsFragment.java deleted file mode 100644 index 3ca4841a..00000000 --- a/src/de/gultsch/chat/ui/SettingsFragment.java +++ /dev/null @@ -1,15 +0,0 @@ -package de.gultsch.chat.ui; - -import de.gultsch.chat.R; -import android.os.Bundle; -import android.preference.PreferenceFragment; - -public class SettingsFragment extends PreferenceFragment { - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // Load the preferences from an XML resource - addPreferencesFromResource(R.xml.preferences); - } -} diff --git a/src/de/gultsch/chat/ui/XmppActivity.java b/src/de/gultsch/chat/ui/XmppActivity.java deleted file mode 100644 index 66c92b72..00000000 --- a/src/de/gultsch/chat/ui/XmppActivity.java +++ /dev/null @@ -1,52 +0,0 @@ -package de.gultsch.chat.ui; - -import de.gultsch.chat.services.XmppConnectionService; -import de.gultsch.chat.services.XmppConnectionService.XmppConnectionBinder; -import android.app.Activity; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.IBinder; - -public abstract class XmppActivity extends Activity { - public XmppConnectionService xmppConnectionService; - public boolean xmppConnectionServiceBound = false; - protected boolean handledViewIntent = false; - protected ServiceConnection mConnection = new ServiceConnection() { - - @Override - public void onServiceConnected(ComponentName className, IBinder service) { - XmppConnectionBinder binder = (XmppConnectionBinder) service; - xmppConnectionService = binder.getService(); - xmppConnectionServiceBound = true; - onBackendConnected(); - } - - @Override - public void onServiceDisconnected(ComponentName arg0) { - xmppConnectionServiceBound = false; - } - }; - - @Override - protected void onStart() { - startService(new Intent(this, XmppConnectionService.class)); - super.onStart(); - if (!xmppConnectionServiceBound) { - Intent intent = new Intent(this, XmppConnectionService.class); - bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - } - } - - @Override - protected void onStop() { - super.onStop(); - if (xmppConnectionServiceBound) { - unbindService(mConnection); - xmppConnectionServiceBound = false; - } - } - - abstract void onBackendConnected(); -} diff --git a/src/de/gultsch/chat/utils/DNSHelper.java b/src/de/gultsch/chat/utils/DNSHelper.java deleted file mode 100644 index f19b1b6f..00000000 --- a/src/de/gultsch/chat/utils/DNSHelper.java +++ /dev/null @@ -1,93 +0,0 @@ -package de.gultsch.chat.utils; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.util.Random; - -import android.os.Bundle; -import android.util.Log; - -public class DNSHelper { - public static Bundle getSRVRecord(String host) { - Bundle namePort = new Bundle(); - try { - String[] hostParts = host.split("\\."); - byte[] transId = new byte[2]; - Random random = new Random(); - random.nextBytes(transId); - byte[] header = { 0x01, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x0c, 0x5f, 0x78, 0x6d, 0x70, 0x70, 0x2d, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x04, 0x5f, 0x74, 0x63, 0x70 }; - byte[] rest = { 0x00, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x29, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - ByteArrayOutputStream output = new ByteArrayOutputStream(); - output.write(transId); - output.write(header); - for (int i = 0; i < hostParts.length; ++i) { - char[] tmpChars = hostParts[i].toCharArray(); - byte[] tmp = new byte[tmpChars.length]; - for (int j = 0; j < tmpChars.length; ++j) { - tmp[j] = (byte) tmpChars[j]; - } - output.write(tmp.length); - output.write(tmp); - } - output.write(rest); - byte[] sendPaket = output.toByteArray(); - byte[] addr = { 0x8, 0x8, 0x8, 0x8 }; - int realLenght = sendPaket.length - 11; - DatagramPacket packet = new DatagramPacket(sendPaket, - sendPaket.length, InetAddress.getByAddress(addr), 53); - DatagramSocket datagramSocket = new DatagramSocket(); - datagramSocket.send(packet); - byte[] receiveData = new byte[1024]; - - DatagramPacket receivePacket = new DatagramPacket(receiveData, - receiveData.length); - datagramSocket.setSoTimeout(2000); - datagramSocket.receive(receivePacket); - if (receiveData[3]!=-128) { - namePort.putString("error", "nosrv"); - return namePort; - } - namePort.putInt("port",calcPort(receiveData[realLenght + 16], - receiveData[realLenght + 17])); - int i = realLenght + 18; - int wordLenght = 0; - StringBuilder builder = new StringBuilder(); - while (receiveData[i] != 0) { - if (wordLenght > 0) { - builder.append((char) receiveData[i]); - --wordLenght; - } else { - wordLenght = receiveData[i]; - builder.append("."); - } - ++i; - } - builder.replace(0, 1, ""); - namePort.putString("name",builder.toString()); - } catch (IOException e) { - Log.d("xmppService","gut" + e.getMessage()); - } - return namePort; - } - - static int calcPort(byte hb, byte lb) { - return ((int) hb << 8) | ((int) lb & 0xFF); - } - - final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); - public static String bytesToHex(byte[] bytes) { - char[] hexChars = new char[bytes.length * 2]; - for ( int j = 0; j < bytes.length; j++ ) { - int v = bytes[j] & 0xFF; - hexChars[j * 2] = hexArray[v >>> 4]; - hexChars[j * 2 + 1] = hexArray[v & 0x0F]; - } - return new String(hexChars); - } -} diff --git a/src/de/gultsch/chat/utils/MessageParser.java b/src/de/gultsch/chat/utils/MessageParser.java deleted file mode 100644 index a12ef58c..00000000 --- a/src/de/gultsch/chat/utils/MessageParser.java +++ /dev/null @@ -1,149 +0,0 @@ -package de.gultsch.chat.utils; - -import java.util.List; - -import net.java.otr4j.session.Session; -import net.java.otr4j.session.SessionStatus; -import android.util.Log; -import de.gultsch.chat.entities.Account; -import de.gultsch.chat.entities.Conversation; -import de.gultsch.chat.entities.Message; -import de.gultsch.chat.services.XmppConnectionService; -import de.gultsch.chat.xml.Element; -import de.gultsch.chat.xmpp.MessagePacket; - -public class MessageParser { - - protected static final String LOGTAG = "xmppService"; - - public static Message parsePlainTextChat(MessagePacket packet, Account account, XmppConnectionService service) { - String[] fromParts = packet.getFrom().split("/"); - Conversation conversation = service.findOrCreateConversation(account, fromParts[0],false); - String body = packet.getBody(); - return new Message(conversation, packet.getFrom(), body, Message.ENCRYPTION_NONE, Message.STATUS_RECIEVED); - } - - public static Message parsePgpChat(String pgpBody, MessagePacket packet, Account account, XmppConnectionService service) { - String[] fromParts = packet.getFrom().split("/"); - Conversation conversation = service.findOrCreateConversation(account, fromParts[0],false); - return new Message(conversation, packet.getFrom(), pgpBody, Message.ENCRYPTION_PGP, Message.STATUS_RECIEVED); - } - - public static Message parseOtrChat(MessagePacket packet, Account account, XmppConnectionService service) { - String[] fromParts = packet.getFrom().split("/"); - Conversation conversation = service.findOrCreateConversation(account, fromParts[0],false); - String body = packet.getBody(); - if (!conversation.hasValidOtrSession()) { - conversation.startOtrSession(service.getApplicationContext(), fromParts[1]); - } - try { - Session otrSession = conversation.getOtrSession(); - SessionStatus before = otrSession - .getSessionStatus(); - body = otrSession.transformReceiving(body); - SessionStatus after = otrSession.getSessionStatus(); - if ((before != after) - && (after == SessionStatus.ENCRYPTED)) { - Log.d(LOGTAG, "otr session etablished"); - List<Message> messages = conversation - .getMessages(); - for (int i = 0; i < messages.size(); ++i) { - Message msg = messages.get(i); - if ((msg.getStatus() == Message.STATUS_UNSEND) - && (msg.getEncryption() == Message.ENCRYPTION_OTR)) { - MessagePacket outPacket = service.prepareMessagePacket( - account, msg, otrSession); - msg.setStatus(Message.STATUS_SEND); - service.databaseBackend.updateMessage(msg); - account.getXmppConnection() - .sendMessagePacket(outPacket); - } - } - if (service.convChangedListener!=null) { - service.convChangedListener.onConversationListChanged(); - } - } else if ((before != after) && (after == SessionStatus.FINISHED)) { - conversation.resetOtrSession(); - Log.d(LOGTAG,"otr session stoped"); - } - } catch (Exception e) { - Log.d(LOGTAG, "error receiving otr. resetting"); - conversation.resetOtrSession(); - return null; - } - if (body == null) { - return null; - } - return new Message(conversation, packet.getFrom(), body, Message.ENCRYPTION_OTR,Message.STATUS_RECIEVED); - } - - public static Message parseGroupchat(MessagePacket packet, Account account, XmppConnectionService service) { - int status; - String[] fromParts = packet.getFrom().split("/"); - Conversation conversation = service.findOrCreateConversation(account, fromParts[0],true); - if ((fromParts.length == 1) || (packet.hasChild("subject"))) { - return null; - } - String counterPart = fromParts[1]; - if (counterPart.equals(account.getUsername())) { - status = Message.STATUS_SEND; - } else { - status = Message.STATUS_RECIEVED; - } - return new Message(conversation, counterPart, packet.getBody(), Message.ENCRYPTION_NONE, status); - } - - public static Message parseCarbonMessage(MessagePacket packet, - Account account, XmppConnectionService service) { - // TODO Auto-generated method stub - int status; - String fullJid; - Element forwarded; - if (packet.hasChild("received")) { - forwarded = packet.findChild("received").findChild( - "forwarded"); - status = Message.STATUS_RECIEVED; - } else if (packet.hasChild("sent")) { - forwarded = packet.findChild("sent").findChild( - "forwarded"); - status = Message.STATUS_SEND; - } else { - return null; - } - Element message = forwarded.findChild("message"); - if ((message == null) || (!message.hasChild("body"))) - return null; // either malformed or boring - if (status == Message.STATUS_RECIEVED) { - fullJid = message.getAttribute("from"); - } else { - fullJid = message.getAttribute("to"); - } - String[] parts = fullJid.split("/"); - Conversation conversation = service.findOrCreateConversation(account, parts[0],false); - return new Message(conversation,fullJid, message.findChild("body").getContent(), Message.ENCRYPTION_NONE,status); - } - - public static Message parseError(MessagePacket packet, Account account, XmppConnectionService service) { - - String[] fromParts = packet.getFrom().split("/"); - Conversation conversation = service.findOrCreateConversation(account, fromParts[0],false); - Element error = packet.findChild("error"); - String errorName = error.getChildren().get(0).getName(); - String displayError; - if (errorName.equals("service-unavailable")) { - displayError = "Contact is offline and does not have offline storage"; - } else { - displayError = errorName.replace("-", " "); - } - return new Message(conversation, packet.getFrom(), displayError, Message.ENCRYPTION_NONE, Message.STATUS_ERROR); - } - - public static String getPgpBody(MessagePacket packet) { - for(Element child : packet.getChildren()) { - if (child.getName().equals("x")&&child.getAttribute("xmlns").equals("jabber:x:encrypted")) { - return child.getContent(); - } - } - return null; - } -} diff --git a/src/de/gultsch/chat/utils/OnPhoneContactsLoadedListener.java b/src/de/gultsch/chat/utils/OnPhoneContactsLoadedListener.java deleted file mode 100644 index c4df4ac3..00000000 --- a/src/de/gultsch/chat/utils/OnPhoneContactsLoadedListener.java +++ /dev/null @@ -1,9 +0,0 @@ -package de.gultsch.chat.utils; - -import java.util.Hashtable; - -import android.os.Bundle; - -public interface OnPhoneContactsLoadedListener { - public void onPhoneContactsLoaded(Hashtable<String, Bundle> phoneContacts); -} diff --git a/src/de/gultsch/chat/utils/PhoneHelper.java b/src/de/gultsch/chat/utils/PhoneHelper.java deleted file mode 100644 index 14773caa..00000000 --- a/src/de/gultsch/chat/utils/PhoneHelper.java +++ /dev/null @@ -1,87 +0,0 @@ -package de.gultsch.chat.utils; - -import java.util.Hashtable; - -import android.app.Activity; -import android.content.Context; -import android.content.CursorLoader; -import android.content.Loader; -import android.content.Loader.OnLoadCompleteListener; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; -import android.os.Looper; -import android.provider.ContactsContract; -import android.provider.ContactsContract.Profile; - -public class PhoneHelper { - - public static void loadPhoneContacts(Context context, final OnPhoneContactsLoadedListener listener) { - if (Looper.myLooper()==null) { - Looper.prepare(); - } - final Looper mLooper = Looper.myLooper(); - final Hashtable<String, Bundle> phoneContacts = new Hashtable<String, Bundle>(); - - final String[] PROJECTION = new String[] { - ContactsContract.Data._ID, - ContactsContract.Data.DISPLAY_NAME, - ContactsContract.Data.PHOTO_THUMBNAIL_URI, - ContactsContract.Data.LOOKUP_KEY, - ContactsContract.CommonDataKinds.Im.DATA }; - - final String SELECTION = "(" + ContactsContract.Data.MIMETYPE + "=\"" - + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE - + "\") AND (" + ContactsContract.CommonDataKinds.Im.PROTOCOL - + "=\"" + ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER - + "\")"; - - CursorLoader mCursorLoader = new CursorLoader(context, - ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, null, - null); - mCursorLoader.registerListener(0, new OnLoadCompleteListener<Cursor>() { - - @Override - public void onLoadComplete(Loader<Cursor> arg0, Cursor cursor) { - while (cursor.moveToNext()) { - Bundle contact = new Bundle(); - contact.putInt("phoneid", cursor.getInt(cursor - .getColumnIndex(ContactsContract.Data._ID))); - contact.putString( - "displayname", - cursor.getString(cursor - .getColumnIndex(ContactsContract.Data.DISPLAY_NAME))); - contact.putString( - "photouri", - cursor.getString(cursor - .getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI))); - contact.putString("lookup",cursor.getString(cursor - .getColumnIndex(ContactsContract.Data.LOOKUP_KEY))); - phoneContacts.put( - cursor.getString(cursor - .getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA)), - contact); - } - if (listener!=null) { - listener.onPhoneContactsLoaded(phoneContacts); - } - mLooper.quit(); - } - }); - mCursorLoader.startLoading(); - } - - public static Uri getSefliUri(Activity activity) { - String[] mProjection = new String[] { Profile._ID, - Profile.PHOTO_THUMBNAIL_URI }; - Cursor mProfileCursor = activity.getContentResolver().query( - Profile.CONTENT_URI, mProjection, null, null, null); - - if (mProfileCursor.getCount()==0) { - return null; - } else { - mProfileCursor.moveToFirst(); - return Uri.parse(mProfileCursor.getString(1)); - } - } -} diff --git a/src/de/gultsch/chat/utils/SASL.java b/src/de/gultsch/chat/utils/SASL.java deleted file mode 100644 index 266f0cb2..00000000 --- a/src/de/gultsch/chat/utils/SASL.java +++ /dev/null @@ -1,24 +0,0 @@ -package de.gultsch.chat.utils; - -import android.util.Base64; - -public class SASL { - public static String plain(String username, String password) { - byte[] userBytes = username.getBytes(); - int userLenght = userBytes.length; - byte[] passwordBytes = password.getBytes(); - byte[] saslBytes = new byte[userBytes.length+passwordBytes.length+2]; - saslBytes[0] = 0x0; - for(int i = 1; i < saslBytes.length; ++i) { - if (i<=userLenght) { - saslBytes[i] = userBytes[i-1]; - } else if (i==userLenght+1) { - saslBytes[i] = 0x0; - } else { - saslBytes[i] = passwordBytes[i-(userLenght+2)]; - } - } - - return Base64.encodeToString(saslBytes, Base64.DEFAULT); - } -} diff --git a/src/de/gultsch/chat/utils/UIHelper.java b/src/de/gultsch/chat/utils/UIHelper.java deleted file mode 100644 index 5e81f099..00000000 --- a/src/de/gultsch/chat/utils/UIHelper.java +++ /dev/null @@ -1,213 +0,0 @@ -package de.gultsch.chat.utils; - -import java.io.FileDescriptor; -import java.io.FileNotFoundException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.List; - -import de.gultsch.chat.R; -import de.gultsch.chat.entities.Account; -import de.gultsch.chat.entities.Contact; -import de.gultsch.chat.entities.Conversation; -import de.gultsch.chat.entities.Message; -import de.gultsch.chat.ui.ConversationActivity; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Notification; -import android.app.PendingIntent; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Rect; -import android.net.Uri; -import android.preference.PreferenceManager; -import android.provider.ContactsContract.Contacts; -import android.support.v4.app.NotificationCompat; -import android.support.v4.app.TaskStackBuilder; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.LinearLayout; -import android.widget.QuickContactBadge; -import android.widget.TextView; - -public class UIHelper { - public static String readableTimeDifference(long time) { - if (time == 0) { - return "just now"; - } - Date date = new Date(time); - long difference = (System.currentTimeMillis() - time) / 1000; - if (difference < 60) { - return "just now"; - } else if (difference < 60 * 10) { - return difference / 60 + " min ago"; - } else if (difference < 60 * 60 * 24) { - SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); - return sdf.format(date); - } else { - SimpleDateFormat sdf = new SimpleDateFormat("MM/dd"); - return sdf.format(date); - } - } - - public static Bitmap getUnknownContactPicture(String name, int size) { - String firstLetter = name.substring(0, 1).toUpperCase(); - - int holoColors[] = { 0xFF1da9da, 0xFFb368d9, 0xFF83b600, 0xFFffa713, - 0xFFe92727 }; - - int color = holoColors[Math.abs(name.hashCode()) % holoColors.length]; - - Bitmap bitmap = Bitmap - .createBitmap(size, size, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); - - bitmap.eraseColor(color); - - Paint paint = new Paint(); - paint.setColor(0xffe5e5e5); - paint.setTextSize((float) (size * 0.9)); - paint.setAntiAlias(true); - Rect rect = new Rect(); - paint.getTextBounds(firstLetter, 0, 1, rect); - float width = paint.measureText(firstLetter); - canvas.drawText(firstLetter, (size / 2) - (width / 2), (size / 2) - + (rect.height() / 2), paint); - - return bitmap; - } - - public static Bitmap getErrorPicture(int size) { - Bitmap bitmap = Bitmap - .createBitmap(size, size, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); - - bitmap.eraseColor(0xFFe92727); - - Paint paint = new Paint(); - paint.setColor(0xffe5e5e5); - paint.setTextSize((float) (size * 0.9)); - paint.setAntiAlias(true); - Rect rect = new Rect(); - paint.getTextBounds("!", 0, 1, rect); - float width = paint.measureText("!"); - canvas.drawText("!", (size / 2) - (width / 2), (size / 2) - + (rect.height() / 2), paint); - - return bitmap; - } - - public static Notification getUnreadMessageNotification(Context context, - Conversation conversation) { - - SharedPreferences sharedPref = PreferenceManager - .getDefaultSharedPreferences(context); - String ringtone = sharedPref.getString("notification_ringtone", null); - - Resources res = context.getResources(); - NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( - context); - mBuilder.setLargeIcon(UIHelper.getUnknownContactPicture(conversation - .getName(), (int) res - .getDimension(android.R.dimen.notification_large_icon_width))); - mBuilder.setContentTitle(conversation.getName()); - mBuilder.setTicker(conversation.getLatestMessage().getBody().trim()); - StringBuilder bigText = new StringBuilder(); - List<Message> messages = conversation.getMessages(); - String firstLine = ""; - for(int i = messages.size() -1; i >= 0; --i) { - if (!messages.get(i).isRead()) { - if (i == messages.size() -1 ) { - firstLine = messages.get(i).getBody().trim(); - bigText.append(firstLine); - } else { - firstLine = messages.get(i).getBody().trim(); - bigText.insert(0, firstLine+"\n"); - } - } else { - break; - } - } - mBuilder.setContentText(firstLine); - mBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText.toString())); - mBuilder.setSmallIcon(R.drawable.notification); - mBuilder.setLights(0xffffffff, 2000, 4000); - if (ringtone != null) { - mBuilder.setSound(Uri.parse(ringtone)); - } - - TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); - stackBuilder.addParentStack(ConversationActivity.class); - - Intent viewConversationIntent = new Intent(context, - ConversationActivity.class); - viewConversationIntent.setAction(Intent.ACTION_VIEW); - viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, - conversation.getUuid()); - viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION); - - stackBuilder.addNextIntent(viewConversationIntent); - - PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, - PendingIntent.FLAG_UPDATE_CURRENT); - - mBuilder.setContentIntent(resultPendingIntent); - return mBuilder.build(); - } - - public static void prepareContactBadge(final Activity activity, - QuickContactBadge badge, final Contact contact) { - if (contact.getSystemAccount()!=null) { - String[] systemAccount = contact.getSystemAccount().split("#"); - long id = Long.parseLong(systemAccount[0]); - badge.assignContactUri(Contacts.getLookupUri(id, systemAccount[1])); - - if (contact.getProfilePhoto() != null) { - badge.setImageURI(Uri.parse(contact.getProfilePhoto())); - } else { - badge.setImageBitmap(UIHelper.getUnknownContactPicture(contact.getDisplayName(), 400)); - } - } else { - badge.setImageBitmap(UIHelper.getUnknownContactPicture(contact.getDisplayName(), 400)); - } - - } - - public static AlertDialog getVerifyFingerprintDialog(final ConversationActivity activity,final Conversation conversation, final LinearLayout msg) { - final Contact contact = conversation.getContact(); - final Account account = conversation.getAccount(); - - AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setTitle("Verify fingerprint"); - LayoutInflater inflater = activity.getLayoutInflater(); - View view = inflater.inflate(R.layout.dialog_verify_otr, null); - TextView jid = (TextView) view.findViewById(R.id.verify_otr_jid); - TextView fingerprint = (TextView) view.findViewById(R.id.verify_otr_fingerprint); - TextView yourprint = (TextView) view.findViewById(R.id.verify_otr_yourprint); - - jid.setText(contact.getJid()); - fingerprint.setText(conversation.getOtrFingerprint()); - yourprint.setText(account.getOtrFingerprint()); - builder.setNegativeButton("Cancel", null); - builder.setPositiveButton("Verify", new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - contact.addOtrFingerprint(conversation.getOtrFingerprint()); - msg.setVisibility(View.GONE); - activity.xmppConnectionService.updateContact(contact); - } - }); - builder.setView(view); - return builder.create(); - } -} diff --git a/src/de/gultsch/chat/utils/Validator.java b/src/de/gultsch/chat/utils/Validator.java deleted file mode 100644 index a29ffa0a..00000000 --- a/src/de/gultsch/chat/utils/Validator.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.gultsch.chat.utils; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class Validator { - public static final Pattern VALID_JID = - Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE); - - public static boolean isValidJid(String jid) { - Matcher matcher = VALID_JID.matcher(jid); - return matcher.find(); - } -} diff --git a/src/de/gultsch/chat/xml/Element.java b/src/de/gultsch/chat/xml/Element.java deleted file mode 100644 index 01deb1d2..00000000 --- a/src/de/gultsch/chat/xml/Element.java +++ /dev/null @@ -1,101 +0,0 @@ -package de.gultsch.chat.xml; - -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.List; - -import android.util.Log; - -public class Element { - protected String name; - protected Hashtable<String, String> attributes = new Hashtable<String, String>(); - protected String content; - protected List<Element> children = new ArrayList<Element>(); - - public Element(String name) { - this.name = name; - } - - public Element addChild(Element child) { - this.content = null; - children.add(child); - return this; - } - - public Element setContent(String content) { - this.content = content; - this.children.clear(); - return this; - } - - public Element findChild(String name) { - for(Element child : this.children) { - if (child.getName().equals(name)) { - return child; - } - } - return null; - } - - public boolean hasChild(String name) { - for(Element child : this.children) { - if (child.getName().equals(name)) { - return true; - } - } - return false; - } - - public List<Element> getChildren() { - return this.children; - } - - public String getContent() { - return content; - } - - public Element setAttribute(String name, String value) { - this.attributes.put(name, value); - return this; - } - - public Element setAttributes(Hashtable<String, String> attributes) { - this.attributes = attributes; - return this; - } - - public String getAttribute(String name) { - if (this.attributes.containsKey(name)) { - return this.attributes.get(name); - } else { - return null; - } - } - - public String toString() { - StringBuilder elementOutput = new StringBuilder(); - if ((content==null)&&(children.size() == 0)) { - Tag emptyTag = Tag.empty(name); - emptyTag.setAtttributes(this.attributes); - elementOutput.append(emptyTag.toString()); - } else { - Tag startTag = Tag.start(name); - startTag.setAtttributes(this.attributes); - elementOutput.append(startTag); - if (content!=null) { - elementOutput.append(content); - } else { - for(Element child : children) { - elementOutput.append(child.toString()); - } - } - Tag endTag = Tag.end(name); - elementOutput.append(endTag); - } - return elementOutput.toString(); - } - - public String getName() { - return name; - } -} diff --git a/src/de/gultsch/chat/xml/Tag.java b/src/de/gultsch/chat/xml/Tag.java deleted file mode 100644 index 275229cf..00000000 --- a/src/de/gultsch/chat/xml/Tag.java +++ /dev/null @@ -1,99 +0,0 @@ -package de.gultsch.chat.xml; - -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map.Entry; -import java.util.Set; - -public class Tag { - public static final int NO = -1; - public static final int START = 0; - public static final int END = 1; - public static final int EMPTY = 2; - - protected int type; - protected String name; - protected Hashtable<String, String> attributes = new Hashtable<String, String>(); - - protected Tag(int type, String name) { - this.type = type; - this.name = name; - } - - - public static Tag no(String text) { - return new Tag(NO,text); - } - - public static Tag start(String name) { - return new Tag(START,name); - } - - public static Tag end(String name) { - return new Tag(END,name); - } - - public static Tag empty(String name) { - return new Tag(EMPTY,name); - } - - public String getName() { - return name; - } - - public String getAttribute(String attrName) { - return this.attributes.get(attrName); - } - - public Tag setAttribute(String attrName, String attrValue) { - this.attributes.put(attrName, attrValue); - return this; - } - - public Tag setAtttributes(Hashtable<String, String> attributes) { - this.attributes = attributes; - return this; - } - - public boolean isStart(String needle) { - return (this.type == START) && (this.name.equals(needle)); - } - - public boolean isEnd(String needle) { - return (this.type == END) && (this.name.equals(needle)); - } - - public boolean isNo() { - return (this.type == NO); - } - - public String toString() { - StringBuilder tagOutput = new StringBuilder(); - tagOutput.append('<'); - if (type==END) { - tagOutput.append('/'); - } - tagOutput.append(name); - if(type!=END) { - Set<Entry<String, String>> attributeSet = attributes.entrySet(); - Iterator<Entry<String, String>> it = attributeSet.iterator(); - while(it.hasNext()) { - Entry<String,String> entry = it.next(); - tagOutput.append(' '); - tagOutput.append(entry.getKey()); - tagOutput.append("=\""); - tagOutput.append(entry.getValue()); - tagOutput.append('"'); - } - } - if (type==EMPTY) { - tagOutput.append('/'); - } - tagOutput.append('>'); - return tagOutput.toString(); - } - - public Hashtable<String, String> getAttributes() { - return this.attributes; - } -} diff --git a/src/de/gultsch/chat/xml/TagWriter.java b/src/de/gultsch/chat/xml/TagWriter.java deleted file mode 100644 index 844f5253..00000000 --- a/src/de/gultsch/chat/xml/TagWriter.java +++ /dev/null @@ -1,64 +0,0 @@ -package de.gultsch.chat.xml; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.util.concurrent.LinkedBlockingQueue; - -import android.util.Log; - -public class TagWriter { - - private OutputStreamWriter outputStream; - private LinkedBlockingQueue<String> writeQueue = new LinkedBlockingQueue<String>(); - private Thread writer = new Thread() { - public boolean shouldStop = false; - @Override - public void run() { - while(!shouldStop) { - try { - String output = writeQueue.take(); - outputStream.write(output); - outputStream.flush(); - } catch (IOException e) { - Log.d("xmppService", "error writing to stream"); - } catch (InterruptedException e) { - - } - } - } - }; - - - public TagWriter() { - - } - - public TagWriter(OutputStream out) { - this.setOutputStream(out); - writer.start(); - } - - public void setOutputStream(OutputStream out) { - this.outputStream = new OutputStreamWriter(out); - if (!writer.isAlive()) writer.start(); - } - - public TagWriter beginDocument() { - writeQueue.add("<?xml version='1.0'?>"); - return this; - } - - public TagWriter writeTag(Tag tag) { - writeQueue.add(tag.toString()); - return this; - } - - public void writeString(String string) { - writeQueue.add(string); - } - - public void writeElement(Element element) { - writeQueue.add(element.toString()); - } -} diff --git a/src/de/gultsch/chat/xml/XmlReader.java b/src/de/gultsch/chat/xml/XmlReader.java deleted file mode 100644 index 0ff2e785..00000000 --- a/src/de/gultsch/chat/xml/XmlReader.java +++ /dev/null @@ -1,102 +0,0 @@ -package de.gultsch.chat.xml; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.util.Log; -import android.util.Xml; - -public class XmlReader { - private static final String LOGTAG = "xmppService"; - private XmlPullParser parser; - private PowerManager.WakeLock wakeLock; - private InputStream is; - - public XmlReader(WakeLock wakeLock) { - this.parser = Xml.newPullParser(); - try { - this.parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES,true); - } catch (XmlPullParserException e) { - Log.d(LOGTAG,"error setting namespace feature on parser"); - } - this.wakeLock = wakeLock; - } - - public void setInputStream(InputStream inputStream) { - this.is = inputStream; - try { - parser.setInput(new InputStreamReader(this.is)); - } catch (XmlPullParserException e) { - Log.d(LOGTAG,"error setting input stream"); - } - } - - public void reset() { - try { - parser.setInput(new InputStreamReader(this.is)); - } catch (XmlPullParserException e) { - Log.d(LOGTAG,"error resetting input stream"); - } - } - - public Tag readTag() throws XmlPullParserException, IOException { - if (wakeLock.isHeld()) { - //Log.d(LOGTAG,"there was a wake lock. releasing it till next event"); - wakeLock.release(); //release wake look while waiting on next parser event - } - //Log.d(LOGTAG,"waiting for new event..."); - while(parser.next() != XmlPullParser.END_DOCUMENT) { - //Log.d(LOGTAG,"found new event. acquiring wake lock"); - wakeLock.acquire(); - if (parser.getEventType() == XmlPullParser.START_TAG) { - Tag tag = Tag.start(parser.getName()); - for(int i = 0; i < parser.getAttributeCount(); ++i) { - tag.setAttribute(parser.getAttributeName(i), parser.getAttributeValue(i)); - } - String xmlns = parser.getNamespace(); - if (xmlns!=null) { - tag.setAttribute("xmlns",xmlns); - } - return tag; - } else if (parser.getEventType() == XmlPullParser.END_TAG) { - Tag tag = Tag.end(parser.getName()); - return tag; - } else if (parser.getEventType() == XmlPullParser.TEXT) { - Tag tag = Tag.no(parser.getText()); - return tag; - } - } - if (wakeLock.isHeld()) { - wakeLock.release(); - } - return null; //end document; - } - - public Element readElement(Tag currentTag) throws XmlPullParserException, IOException { - Element element = new Element(currentTag.getName()); - //Log.d(LOGTAG,"trying to read element "+element.getName()); - element.setAttributes(currentTag.getAttributes()); - Tag nextTag = this.readTag(); - //Log.d(LOGTAG,"next Tag is: "+nextTag.toString()); - if(nextTag.isNo()) { - element.setContent(nextTag.getName()); - nextTag = this.readTag(); - } - //Log.d(LOGTAG,"reading till the end of "+element.getName()); - while(!nextTag.isEnd(element.getName())) { - if (!nextTag.isNo()) { - Element child = this.readElement(nextTag); - element.addChild(child); - } - nextTag = this.readTag(); - } - //Log.d(LOGTAG,"return with element"+element); - return element; - } -} diff --git a/src/de/gultsch/chat/xmpp/IqPacket.java b/src/de/gultsch/chat/xmpp/IqPacket.java deleted file mode 100644 index d7672540..00000000 --- a/src/de/gultsch/chat/xmpp/IqPacket.java +++ /dev/null @@ -1,40 +0,0 @@ -package de.gultsch.chat.xmpp; - -import de.gultsch.chat.xml.Element; - -public class IqPacket extends Element { - - public static final int TYPE_SET = 0; - public static final int TYPE_RESULT = 1; - public static final int TYPE_GET = 2; - - private IqPacket(String name) { - super(name); - } - - public IqPacket(int type) { - super("iq"); - switch (type) { - case TYPE_SET: - this.setAttribute("type", "set"); - break; - case TYPE_GET: - this.setAttribute("type", "get"); - break; - case TYPE_RESULT: - this.setAttribute("type", "result"); - break; - default: - break; - } - } - - public IqPacket() { - super("iq"); - } - - public String getId() { - return this.getAttribute("id"); - } - -} diff --git a/src/de/gultsch/chat/xmpp/MessagePacket.java b/src/de/gultsch/chat/xmpp/MessagePacket.java deleted file mode 100644 index 160a8c0a..00000000 --- a/src/de/gultsch/chat/xmpp/MessagePacket.java +++ /dev/null @@ -1,81 +0,0 @@ -package de.gultsch.chat.xmpp; - -import de.gultsch.chat.xml.Element; - -public class MessagePacket extends Element { - public static final int TYPE_CHAT = 0; - public static final int TYPE_UNKNOWN = 1; - public static final int TYPE_NO = 2; - public static final int TYPE_GROUPCHAT = 3; - public static final int TYPE_ERROR = 4; - - private MessagePacket(String name) { - super(name); - } - - public MessagePacket() { - super("message"); - } - - public String getTo() { - return getAttribute("to"); - } - - public String getFrom() { - return getAttribute("from"); - } - - public String getBody() { - Element body = this.findChild("body"); - if (body!=null) { - return body.getContent(); - } else { - return null; - } - } - - public void setTo(String to) { - setAttribute("to", to); - } - - public void setFrom(String from) { - setAttribute("from",from); - } - - public void setBody(String text) { - this.children.remove(findChild("body")); - Element body = new Element("body"); - body.setContent(text); - this.children.add(body); - } - - public void setType(int type) { - switch (type) { - case TYPE_CHAT: - this.setAttribute("type","chat"); - break; - case TYPE_GROUPCHAT: - this.setAttribute("type", "groupchat"); - break; - default: - this.setAttribute("type","chat"); - break; - } - } - - public int getType() { - String type = getAttribute("type"); - if (type==null) { - return TYPE_NO; - } - if (type.equals("chat")) { - return TYPE_CHAT; - } else if (type.equals("groupchat")) { - return TYPE_GROUPCHAT; - } else if (type.equals("error")) { - return TYPE_ERROR; - } else { - return TYPE_UNKNOWN; - } - } -} diff --git a/src/de/gultsch/chat/xmpp/OnIqPacketReceived.java b/src/de/gultsch/chat/xmpp/OnIqPacketReceived.java deleted file mode 100644 index 0a2e0361..00000000 --- a/src/de/gultsch/chat/xmpp/OnIqPacketReceived.java +++ /dev/null @@ -1,7 +0,0 @@ -package de.gultsch.chat.xmpp; - -import de.gultsch.chat.entities.Account; - -public interface OnIqPacketReceived { - public void onIqPacketReceived(Account account, IqPacket packet); -} diff --git a/src/de/gultsch/chat/xmpp/OnMessagePacketReceived.java b/src/de/gultsch/chat/xmpp/OnMessagePacketReceived.java deleted file mode 100644 index 30f6c29b..00000000 --- a/src/de/gultsch/chat/xmpp/OnMessagePacketReceived.java +++ /dev/null @@ -1,7 +0,0 @@ -package de.gultsch.chat.xmpp; - -import de.gultsch.chat.entities.Account; - -public interface OnMessagePacketReceived { - public void onMessagePacketReceived(Account account, MessagePacket packet); -} diff --git a/src/de/gultsch/chat/xmpp/OnPresencePacketReceived.java b/src/de/gultsch/chat/xmpp/OnPresencePacketReceived.java deleted file mode 100644 index 4c976779..00000000 --- a/src/de/gultsch/chat/xmpp/OnPresencePacketReceived.java +++ /dev/null @@ -1,7 +0,0 @@ -package de.gultsch.chat.xmpp; - -import de.gultsch.chat.entities.Account; - -public interface OnPresencePacketReceived { - public void onPresencePacketReceived(Account account, PresencePacket packet); -} diff --git a/src/de/gultsch/chat/xmpp/OnStatusChanged.java b/src/de/gultsch/chat/xmpp/OnStatusChanged.java deleted file mode 100644 index f79305e3..00000000 --- a/src/de/gultsch/chat/xmpp/OnStatusChanged.java +++ /dev/null @@ -1,7 +0,0 @@ -package de.gultsch.chat.xmpp; - -import de.gultsch.chat.entities.Account; - -public interface OnStatusChanged { - public void onStatusChanged(Account account); -} diff --git a/src/de/gultsch/chat/xmpp/PresencePacket.java b/src/de/gultsch/chat/xmpp/PresencePacket.java deleted file mode 100644 index 947afe7a..00000000 --- a/src/de/gultsch/chat/xmpp/PresencePacket.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.gultsch.chat.xmpp; - -import de.gultsch.chat.xml.Element; - -public class PresencePacket extends Element { - private PresencePacket(String name) { - super("presence"); - } - - public PresencePacket() { - super("presence"); - } -} diff --git a/src/de/gultsch/chat/xmpp/XmppConnection.java b/src/de/gultsch/chat/xmpp/XmppConnection.java deleted file mode 100644 index 1b9aa0c3..00000000 --- a/src/de/gultsch/chat/xmpp/XmppConnection.java +++ /dev/null @@ -1,446 +0,0 @@ -package de.gultsch.chat.xmpp; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.math.BigInteger; -import java.net.Socket; -import java.net.UnknownHostException; -import java.security.SecureRandom; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.List; - -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; - -import org.xmlpull.v1.XmlPullParserException; - -import android.os.Bundle; -import android.os.PowerManager; -import android.util.Log; -import de.gultsch.chat.entities.Account; -import de.gultsch.chat.utils.DNSHelper; -import de.gultsch.chat.utils.SASL; -import de.gultsch.chat.xml.Element; -import de.gultsch.chat.xml.Tag; -import de.gultsch.chat.xml.XmlReader; -import de.gultsch.chat.xml.TagWriter; - -public class XmppConnection implements Runnable { - - protected Account account; - private static final String LOGTAG = "xmppService"; - - private PowerManager.WakeLock wakeLock; - - private SecureRandom random = new SecureRandom(); - - private Socket socket; - private XmlReader tagReader; - private TagWriter tagWriter; - - private boolean isTlsEncrypted = false; - private boolean isAuthenticated = false; - // private boolean shouldUseTLS = false; - private boolean shouldConnect = true; - private boolean shouldBind = true; - private boolean shouldAuthenticate = true; - private Element streamFeatures; - private HashSet<String> discoFeatures = new HashSet<String>(); - - private static final int PACKET_IQ = 0; - private static final int PACKET_MESSAGE = 1; - private static final int PACKET_PRESENCE = 2; - - private Hashtable<String, OnIqPacketReceived> iqPacketCallbacks = new Hashtable<String, OnIqPacketReceived>(); - private OnPresencePacketReceived presenceListener = null; - private OnIqPacketReceived unregisteredIqListener = null; - private OnMessagePacketReceived messageListener = null; - private OnStatusChanged statusListener = null; - - public XmppConnection(Account account, PowerManager pm) { - this.account = account; - wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, - "XmppConnection"); - tagReader = new XmlReader(wakeLock); - tagWriter = new TagWriter(); - } - - protected void connect() { - try { - Bundle namePort = DNSHelper.getSRVRecord(account.getServer()); - String srvRecordServer = namePort.getString("name"); - int srvRecordPort = namePort.getInt("port"); - if (srvRecordServer != null) { - Log.d(LOGTAG, account.getJid() + ": using values from dns " - + srvRecordServer + ":" + srvRecordPort); - socket = new Socket(srvRecordServer, srvRecordPort); - } else { - socket = new Socket(account.getServer(), 5222); - } - OutputStream out = socket.getOutputStream(); - tagWriter.setOutputStream(out); - InputStream in = socket.getInputStream(); - tagReader.setInputStream(in); - tagWriter.beginDocument(); - sendStartStream(); - Tag nextTag; - while ((nextTag = tagReader.readTag()) != null) { - if (nextTag.isStart("stream")) { - processStream(nextTag); - break; - } else { - Log.d(LOGTAG, "found unexpected tag: " + nextTag.getName()); - return; - } - } - if (socket.isConnected()) { - socket.close(); - } - } catch (UnknownHostException e) { - account.setStatus(Account.STATUS_SERVER_NOT_FOUND); - if (statusListener != null) { - statusListener.onStatusChanged(account); - } - return; - } catch (IOException e) { - Log.d(LOGTAG, "bla " + e.getMessage()); - if (shouldConnect) { - Log.d(LOGTAG, account.getJid() + ": connection lost"); - account.setStatus(Account.STATUS_OFFLINE); - if (statusListener != null) { - statusListener.onStatusChanged(account); - } - } - } catch (XmlPullParserException e) { - Log.d(LOGTAG, "xml exception " + e.getMessage()); - return; - } - - } - - @Override - public void run() { - shouldConnect = true; - while (shouldConnect) { - connect(); - try { - if (shouldConnect) { - Thread.sleep(30000); - } - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - Log.d(LOGTAG, "end run"); - } - - private void processStream(Tag currentTag) throws XmlPullParserException, - IOException { - Tag nextTag = tagReader.readTag(); - while ((nextTag != null) && (!nextTag.isEnd("stream"))) { - if (nextTag.isStart("error")) { - processStreamError(nextTag); - } else if (nextTag.isStart("features")) { - processStreamFeatures(nextTag); - } else if (nextTag.isStart("proceed")) { - switchOverToTls(nextTag); - } else if (nextTag.isStart("success")) { - isAuthenticated = true; - Log.d(LOGTAG, account.getJid() - + ": read success tag in stream. reset again"); - tagReader.readTag(); - tagReader.reset(); - sendStartStream(); - processStream(tagReader.readTag()); - break; - } else if (nextTag.isStart("failure")) { - Element failure = tagReader.readElement(nextTag); - Log.d(LOGTAG, "read failure element" + failure.toString()); - account.setStatus(Account.STATUS_UNAUTHORIZED); - if (statusListener != null) { - statusListener.onStatusChanged(account); - } - tagWriter.writeTag(Tag.end("stream")); - } else if (nextTag.isStart("iq")) { - processIq(nextTag); - } else if (nextTag.isStart("message")) { - processMessage(nextTag); - } else if (nextTag.isStart("presence")) { - processPresence(nextTag); - } else { - Log.d(LOGTAG, "found unexpected tag: " + nextTag.getName() - + " as child of " + currentTag.getName()); - } - nextTag = tagReader.readTag(); - } - if (account.getStatus() == Account.STATUS_ONLINE) { - account.setStatus(Account.STATUS_OFFLINE); - if (statusListener != null) { - statusListener.onStatusChanged(account); - } - } - } - - private Element processPacket(Tag currentTag, int packetType) - throws XmlPullParserException, IOException { - Element element; - switch (packetType) { - case PACKET_IQ: - element = new IqPacket(); - break; - case PACKET_MESSAGE: - element = new MessagePacket(); - break; - case PACKET_PRESENCE: - element = new PresencePacket(); - break; - default: - return null; - } - element.setAttributes(currentTag.getAttributes()); - Tag nextTag = tagReader.readTag(); - while (!nextTag.isEnd(element.getName())) { - if (!nextTag.isNo()) { - Element child = tagReader.readElement(nextTag); - element.addChild(child); - } - nextTag = tagReader.readTag(); - } - return element; - } - - private IqPacket processIq(Tag currentTag) throws XmlPullParserException, - IOException { - IqPacket packet = (IqPacket) processPacket(currentTag, PACKET_IQ); - if (iqPacketCallbacks.containsKey(packet.getId())) { - iqPacketCallbacks.get(packet.getId()).onIqPacketReceived(account, - packet); - iqPacketCallbacks.remove(packet.getId()); - } else if (this.unregisteredIqListener != null) { - this.unregisteredIqListener.onIqPacketReceived(account, packet); - } - return packet; - } - - private void processMessage(Tag currentTag) throws XmlPullParserException, - IOException { - MessagePacket packet = (MessagePacket) processPacket(currentTag, - PACKET_MESSAGE); - if (this.messageListener != null) { - this.messageListener.onMessagePacketReceived(account, packet); - } - } - - private void processPresence(Tag currentTag) throws XmlPullParserException, - IOException { - PresencePacket packet = (PresencePacket) processPacket(currentTag, - PACKET_PRESENCE); - if (this.presenceListener != null) { - this.presenceListener.onPresencePacketReceived(account, packet); - } - } - - private void sendStartTLS() { - Tag startTLS = Tag.empty("starttls"); - startTLS.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-tls"); - Log.d(LOGTAG, account.getJid() + ": sending starttls"); - tagWriter.writeTag(startTLS); - } - - private void switchOverToTls(Tag currentTag) throws XmlPullParserException, - IOException { - Tag nextTag = tagReader.readTag(); // should be proceed end tag - Log.d(LOGTAG, account.getJid() + ": now switch to ssl"); - SSLSocket sslSocket; - try { - sslSocket = (SSLSocket) ((SSLSocketFactory) SSLSocketFactory - .getDefault()).createSocket(socket, socket.getInetAddress() - .getHostAddress(), socket.getPort(), true); - tagReader.setInputStream(sslSocket.getInputStream()); - Log.d(LOGTAG, "reset inputstream"); - tagWriter.setOutputStream(sslSocket.getOutputStream()); - Log.d(LOGTAG, "switch over seemed to work"); - isTlsEncrypted = true; - sendStartStream(); - processStream(tagReader.readTag()); - sslSocket.close(); - } catch (IOException e) { - Log.d(LOGTAG, - account.getJid() + ": error on ssl '" + e.getMessage() - + "'"); - } - } - - private void sendSaslAuth() throws IOException, XmlPullParserException { - String saslString = SASL.plain(account.getUsername(), - account.getPassword()); - Element auth = new Element("auth"); - auth.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl"); - auth.setAttribute("mechanism", "PLAIN"); - auth.setContent(saslString); - Log.d(LOGTAG, account.getJid() + ": sending sasl " + auth.toString()); - tagWriter.writeElement(auth); - } - - private void processStreamFeatures(Tag currentTag) - throws XmlPullParserException, IOException { - this.streamFeatures = tagReader.readElement(currentTag); - Log.d(LOGTAG, account.getJid() + ": process stream features " - + streamFeatures); - if (this.streamFeatures.hasChild("starttls") - && account.isOptionSet(Account.OPTION_USETLS)) { - sendStartTLS(); - } else if (this.streamFeatures.hasChild("mechanisms") - && shouldAuthenticate) { - sendSaslAuth(); - } - if (this.streamFeatures.hasChild("bind") && shouldBind) { - sendBindRequest(); - if (this.streamFeatures.hasChild("session")) { - IqPacket startSession = new IqPacket(IqPacket.TYPE_SET); - Element session = new Element("session"); - session.setAttribute("xmlns", - "urn:ietf:params:xml:ns:xmpp-session"); - session.setContent(""); - startSession.addChild(session); - sendIqPacket(startSession, null); - tagWriter.writeElement(startSession); - } - Element presence = new Element("presence"); - - tagWriter.writeElement(presence); - } - } - - private void sendBindRequest() throws IOException { - IqPacket iq = new IqPacket(IqPacket.TYPE_SET); - Element bind = new Element("bind"); - bind.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-bind"); - iq.addChild(bind); - this.sendIqPacket(iq, new OnIqPacketReceived() { - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - String resource = packet.findChild("bind").findChild("jid") - .getContent().split("/")[1]; - account.setResource(resource); - account.setStatus(Account.STATUS_ONLINE); - if (statusListener != null) { - statusListener.onStatusChanged(account); - } - sendServiceDiscovery(); - } - }); - } - - private void sendServiceDiscovery() { - IqPacket iq = new IqPacket(IqPacket.TYPE_GET); - iq.setAttribute("to", account.getServer()); - Element query = new Element("query"); - query.setAttribute("xmlns", "http://jabber.org/protocol/disco#info"); - iq.addChild(query); - this.sendIqPacket(iq, new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - if (packet.hasChild("query")) { - List<Element> elements = packet.findChild("query") - .getChildren(); - for (int i = 0; i < elements.size(); ++i) { - if (elements.get(i).getName().equals("feature")) { - discoFeatures.add(elements.get(i).getAttribute( - "var")); - } - } - } - if (discoFeatures.contains("urn:xmpp:carbons:2")) { - sendEnableCarbons(); - } - } - }); - } - - private void sendEnableCarbons() { - Log.d(LOGTAG,account.getJid()+": enable carbons"); - IqPacket iq = new IqPacket(IqPacket.TYPE_SET); - Element enable = new Element("enable"); - enable.setAttribute("xmlns", "urn:xmpp:carbons:2"); - iq.addChild(enable); - this.sendIqPacket(iq, new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, IqPacket packet) { - if (!packet.hasChild("error")) { - Log.d(LOGTAG,account.getJid()+": successfully enabled carbons"); - } else { - Log.d(LOGTAG,account.getJid()+": error enableing carbons "+packet.toString()); - } - } - }); - } - - private void processStreamError(Tag currentTag) { - Log.d(LOGTAG, "processStreamError"); - } - - private void sendStartStream() { - Tag stream = Tag.start("stream:stream"); - stream.setAttribute("from", account.getJid()); - stream.setAttribute("to", account.getServer()); - stream.setAttribute("version", "1.0"); - stream.setAttribute("xml:lang", "en"); - stream.setAttribute("xmlns", "jabber:client"); - stream.setAttribute("xmlns:stream", "http://etherx.jabber.org/streams"); - tagWriter.writeTag(stream); - } - - private String nextRandomId() { - return new BigInteger(50, random).toString(32); - } - - public void sendIqPacket(IqPacket packet, OnIqPacketReceived callback) { - String id = nextRandomId(); - packet.setAttribute("id", id); - tagWriter.writeElement(packet); - if (callback != null) { - iqPacketCallbacks.put(id, callback); - } - //Log.d(LOGTAG, account.getJid() + ": sending: " + packet.toString()); - } - - public void sendMessagePacket(MessagePacket packet) { - Log.d(LOGTAG,"sending message packet "+packet.toString()); - tagWriter.writeElement(packet); - } - - public void sendPresencePacket(PresencePacket packet) { - tagWriter.writeElement(packet); - Log.d(LOGTAG, account.getJid() + ": sending: " + packet.toString()); - } - - public void setOnMessagePacketReceivedListener( - OnMessagePacketReceived listener) { - this.messageListener = listener; - } - - public void setOnUnregisteredIqPacketReceivedListener( - OnIqPacketReceived listener) { - this.unregisteredIqListener = listener; - } - - public void setOnPresencePacketReceivedListener( - OnPresencePacketReceived listener) { - this.presenceListener = listener; - } - - public void setOnStatusChangedListener(OnStatusChanged listener) { - this.statusListener = listener; - } - - public void disconnect() { - shouldConnect = false; - tagWriter.writeTag(Tag.end("stream:stream")); - } -} |