From 993477cd8301e1a9a19ccdc10008bc23928faf08 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 19 May 2014 15:15:09 +0200 Subject: reworked roster/contact handling. might break some stuff. not sycing to disk yet --- src/eu/siacs/conversations/crypto/PgpEngine.java | 1 - src/eu/siacs/conversations/entities/Account.java | 9 + src/eu/siacs/conversations/entities/Contact.java | 123 ++++----- .../siacs/conversations/entities/Conversation.java | 20 +- src/eu/siacs/conversations/entities/Presences.java | 37 --- src/eu/siacs/conversations/entities/Roster.java | 63 +++++ .../conversations/persistance/DatabaseBackend.java | 152 ++++------- .../services/XmppConnectionService.java | 300 ++++++--------------- .../conversations/ui/ContactDetailsActivity.java | 90 ++++--- .../siacs/conversations/ui/ContactsActivity.java | 58 +--- .../conversations/ui/ConversationActivity.java | 8 +- .../siacs/conversations/ui/ShareWithActivity.java | 2 +- .../utils/OnPhoneContactsLoadedListener.java | 4 +- src/eu/siacs/conversations/utils/PhoneHelper.java | 23 +- src/eu/siacs/conversations/utils/UIHelper.java | 2 +- 15 files changed, 332 insertions(+), 560 deletions(-) create mode 100644 src/eu/siacs/conversations/entities/Roster.java (limited to 'src/eu') diff --git a/src/eu/siacs/conversations/crypto/PgpEngine.java b/src/eu/siacs/conversations/crypto/PgpEngine.java index 48750e24..0f2aeff4 100644 --- a/src/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/eu/siacs/conversations/crypto/PgpEngine.java @@ -221,7 +221,6 @@ public class PgpEngine { return 0; } case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED: - Log.d("xmppService","openpgp user interaction requeried"); return 0; case OpenPgpApi.RESULT_CODE_ERROR: Log.d("xmppService","openpgp error: "+((OpenPgpError) result diff --git a/src/eu/siacs/conversations/entities/Account.java b/src/eu/siacs/conversations/entities/Account.java index 3e7ad97f..b9c87eac 100644 --- a/src/eu/siacs/conversations/entities/Account.java +++ b/src/eu/siacs/conversations/entities/Account.java @@ -65,6 +65,8 @@ public class Account extends AbstractEntity{ private String otrFingerprint; + private Roster roster = null; + public Account() { this.uuid = "0"; } @@ -287,4 +289,11 @@ public class Account extends AbstractEntity{ return null; } } + + public Roster getRoster() { + if (this.roster==null) { + this.roster = new Roster(this); + } + return this.roster; + } } diff --git a/src/eu/siacs/conversations/entities/Contact.java b/src/eu/siacs/conversations/entities/Contact.java index 599aa8de..17cead63 100644 --- a/src/eu/siacs/conversations/entities/Contact.java +++ b/src/eu/siacs/conversations/entities/Contact.java @@ -4,33 +4,30 @@ 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 eu.siacs.conversations.xml.Element; - import android.content.ContentValues; import android.database.Cursor; -import android.util.Log; 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 SYSTEMNAME = "systemname"; + public static final String SERVERNAME = "servername"; public static final String JID = "jid"; - public static final String SUBSCRIPTION = "subscription"; + public static final String OPTIONS = "options"; public static final String SYSTEMACCOUNT = "systemaccount"; public static final String PHOTOURI = "photouri"; public static final String KEYS = "pgpkey"; - public static final String PRESENCES = "presences"; public static final String ACCOUNT = "accountUuid"; protected String accountUuid; - protected String displayName; + protected String systemName; + protected String serverName; protected String jid; protected int subscription = 0; protected String systemAccount; @@ -42,26 +39,13 @@ public class Contact extends AbstractEntity implements Serializable { 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) { + public Contact(String uuid, String account, String systemName, + String serverName, String jid, int subscription, String photoUri, + String systemAccount, String keys) { this.uuid = uuid; this.accountUuid = account; - this.displayName = displayName; + this.systemName = systemName; + this.serverName = serverName; this.jid = jid; this.subscription = subscription; this.photoUri = photoUri; @@ -74,11 +58,20 @@ public class Contact extends AbstractEntity implements Serializable { } catch (JSONException e) { this.keys = new JSONObject(); } - this.presences = Presences.fromJsonString(presences); + } + + public Contact(String jid) { + this.jid = jid; } public String getDisplayName() { - return this.displayName; + if (this.systemName != null) { + return this.systemName; + } else if (this.serverName != null) { + return this.serverName; + } else { + return this.jid.split("@")[0]; + } } public String getProfilePhoto() { @@ -90,7 +83,7 @@ public class Contact extends AbstractEntity implements Serializable { } public boolean match(String needle) { - return (jid.toLowerCase().contains(needle.toLowerCase()) || (displayName + return (jid.toLowerCase().contains(needle.toLowerCase()) || (getDisplayName() .toLowerCase().contains(needle.toLowerCase()))); } @@ -99,26 +92,26 @@ public class Contact extends AbstractEntity implements Serializable { ContentValues values = new ContentValues(); values.put(UUID, uuid); values.put(ACCOUNT, accountUuid); - values.put(DISPLAYNAME, displayName); + values.put(SYSTEMNAME, systemName); + values.put(SERVERNAME, serverName); values.put(JID, jid); - values.put(SUBSCRIPTION, subscription); + values.put(OPTIONS, 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(SYSTEMNAME)), + cursor.getString(cursor.getColumnIndex(SERVERNAME)), cursor.getString(cursor.getColumnIndex(JID)), - cursor.getInt(cursor.getColumnIndex(SUBSCRIPTION)), + cursor.getInt(cursor.getColumnIndex(OPTIONS)), cursor.getString(cursor.getColumnIndex(PHOTOURI)), cursor.getString(cursor.getColumnIndex(SYSTEMACCOUNT)), - cursor.getString(cursor.getColumnIndex(KEYS)), - cursor.getString(cursor.getColumnIndex(PRESENCES))); + cursor.getString(cursor.getColumnIndex(KEYS))); } public int getSubscription() { @@ -154,8 +147,8 @@ public class Contact extends AbstractEntity implements Serializable { return (domainParts[0].equals("conf") || domainParts[0].equals("conference") || domainParts[0].equals("muc") - || domainParts[0].equals("sala") - || domainParts[0].equals("salas")); + || domainParts[0].equals("sala") || domainParts[0] + .equals("salas")); } } } @@ -188,8 +181,12 @@ public class Contact extends AbstractEntity implements Serializable { this.photoUri = uri; } - public void setDisplayName(String name) { - this.displayName = name; + public void setServerName(String serverName) { + this.serverName = serverName; + } + + public void setSystemName(String systemName) { + this.systemName = systemName; } public String getSystemAccount() { @@ -249,15 +246,15 @@ public class Contact extends AbstractEntity implements Serializable { } } - public void setSubscriptionOption(int option) { + public void setOption(int option) { this.subscription |= 1 << option; } - public void resetSubscriptionOption(int option) { + public void resetOption(int option) { this.subscription &= ~(1 << option); } - public boolean getSubscriptionOption(int option) { + public boolean getOption(int option) { return ((this.subscription & (1 << option)) != 0); } @@ -267,40 +264,38 @@ public class Contact extends AbstractEntity implements Serializable { if (subscription != null) { if (subscription.equals("to")) { - this.resetSubscriptionOption(Contact.Subscription.FROM); - this.setSubscriptionOption(Contact.Subscription.TO); + this.resetOption(Contact.Options.FROM); + this.setOption(Contact.Options.TO); } else if (subscription.equals("from")) { - this.resetSubscriptionOption(Contact.Subscription.TO); - this.setSubscriptionOption(Contact.Subscription.FROM); + this.resetOption(Contact.Options.TO); + this.setOption(Contact.Options.FROM); } else if (subscription.equals("both")) { - this.setSubscriptionOption(Contact.Subscription.TO); - this.setSubscriptionOption(Contact.Subscription.FROM); + this.setOption(Contact.Options.TO); + this.setOption(Contact.Options.FROM); } } if ((ask != null) && (ask.equals("subscribe"))) { - this.setSubscriptionOption(Contact.Subscription.ASKING); + this.setOption(Contact.Options.ASKING); } else { - this.resetSubscriptionOption(Contact.Subscription.ASKING); + this.resetOption(Contact.Options.ASKING); + } + } + + public Element asElement() { + Element item = new Element("item"); + item.setAttribute("jid", this.jid); + if (this.serverName != null) { + item.setAttribute("name", this.serverName); } + return item; } - public class Subscription { + public class Options { public static final int TO = 0; public static final int FROM = 1; public static final int ASKING = 2; public static final int PREEMPTIVE_GRANT = 4; - } - - public void flagAsNotInRoster() { - this.inRoster = false; - } - - public boolean isInRoster() { - return this.inRoster; - } - - public String getAccountUuid() { - return this.accountUuid; + public static final int IN_ROSTER = 8; } } diff --git a/src/eu/siacs/conversations/entities/Conversation.java b/src/eu/siacs/conversations/entities/Conversation.java index 88d6279e..e61537da 100644 --- a/src/eu/siacs/conversations/entities/Conversation.java +++ b/src/eu/siacs/conversations/entities/Conversation.java @@ -49,7 +49,6 @@ public class Conversation extends AbstractEntity { private transient List messages = null; private transient Account account = null; - private transient Contact contact; private transient SessionImpl otrSession; @@ -129,19 +128,13 @@ public class Conversation extends AbstractEntity { public String getName(boolean useSubject) { if ((getMode() == MODE_MULTI) && (getMucOptions().getSubject() != null) && useSubject) { return getMucOptions().getSubject(); - } else if (this.contact != null) { - return this.contact.getDisplayName(); } else { - return this.name; + return this.getContact().getDisplayName(); } } public String getProfilePhotoString() { - if (this.contact == null) { - return null; - } else { - return this.contact.getProfilePhoto(); - } + return this.getContact().getProfilePhoto(); } public String getAccountUuid() { @@ -153,14 +146,7 @@ public class Conversation extends AbstractEntity { } public Contact getContact() { - return this.contact; - } - - public void setContact(Contact contact) { - this.contact = contact; - if (contact != null) { - this.contactUuid = contact.getUuid(); - } + return this.account.getRoster().getContact(this.contactJid); } public void setAccount(Account account) { diff --git a/src/eu/siacs/conversations/entities/Presences.java b/src/eu/siacs/conversations/entities/Presences.java index acbaafca..fd8af573 100644 --- a/src/eu/siacs/conversations/entities/Presences.java +++ b/src/eu/siacs/conversations/entities/Presences.java @@ -4,10 +4,6 @@ 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; - import eu.siacs.conversations.xml.Element; public class Presences { @@ -47,39 +43,6 @@ public class Presences { return status; } - public String toJsonString() { - JSONArray json = new JSONArray(); - Iterator> it = presences.entrySet().iterator(); - - while (it.hasNext()) { - Entry 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; - } - public static int parseShow(Element show) { if (show == null) { return Presences.ONLINE; diff --git a/src/eu/siacs/conversations/entities/Roster.java b/src/eu/siacs/conversations/entities/Roster.java new file mode 100644 index 00000000..7c18d80a --- /dev/null +++ b/src/eu/siacs/conversations/entities/Roster.java @@ -0,0 +1,63 @@ +package eu.siacs.conversations.entities; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class Roster { + Account account; + HashMap contacts = new HashMap(); + private String version = null; + + public Roster(Account account) { + this.account = account; + } + + public boolean hasContact(String jid) { + String cleanJid = jid.split("/")[0]; + return contacts.containsKey(cleanJid); + } + + public Contact getContact(String jid) { + String cleanJid = jid.split("/")[0]; + if (contacts.containsKey(cleanJid)) { + return contacts.get(cleanJid); + } else { + Contact contact = new Contact(cleanJid); + contact.setAccount(account); + contacts.put(cleanJid, contact); + return contact; + } + } + + public void clearPresences() { + // TODO Auto-generated method stub + + } + + public void markAllAsNotInRoster() { + + } + + public List getContacts() { + return new ArrayList(this.contacts.values()); + } + + public void initContact(Contact contact) { + contact.setAccount(account); + contact.setOption(Contact.Options.IN_ROSTER); + contacts.put(contact.getJid(),contact); + } + + public void setVersion(String version) { + this.version = version; + } + + public String getVersion() { + return this.version; + } + + public Account getAccount() { + return this.account; + } +} diff --git a/src/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/eu/siacs/conversations/persistance/DatabaseBackend.java index 5a34dac6..63e050e3 100644 --- a/src/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -10,6 +10,7 @@ import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Presences; +import eu.siacs.conversations.entities.Roster; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; @@ -23,7 +24,16 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 3; + private static final int DATABASE_VERSION = 5; + + private static String CREATE_CONTATCS_STATEMENT = "create table " + + Contact.TABLENAME + "(" + Contact.UUID + " TEXT PRIMARY KEY, " + + Contact.ACCOUNT + " TEXT, " + Contact.SERVERNAME + " TEXT, " + + Contact.SYSTEMNAME + " TEXT," + Contact.JID + " TEXT," + + Contact.KEYS + " TEXT," + Contact.PHOTOURI + " TEXT," + + Contact.OPTIONS + " NUMBER," + Contact.SYSTEMACCOUNT + + " NUMBER, " + "FOREIGN KEY(" + Contact.ACCOUNT + ") REFERENCES " + + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE);"; public DatabaseBackend(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); @@ -36,7 +46,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { + " TEXT PRIMARY KEY," + Account.USERNAME + " TEXT," + Account.SERVER + " TEXT," + Account.PASSWORD + " TEXT," + Account.ROSTERVERSION + " TEXT," + Account.OPTIONS - + " NUMBER, "+Account.KEYS+" TEXT)"); + + " NUMBER, " + Account.KEYS + " TEXT)"); db.execSQL("create table " + Conversation.TABLENAME + " (" + Conversation.UUID + " TEXT PRIMARY KEY, " + Conversation.NAME + " TEXT, " + Conversation.CONTACT + " TEXT, " @@ -50,31 +60,28 @@ public class DatabaseBackend extends SQLiteOpenHelper { + " TEXT PRIMARY KEY, " + Message.CONVERSATION + " TEXT, " + Message.TIME_SENT + " NUMBER, " + Message.COUNTERPART + " TEXT, " + Message.BODY + " TEXT, " + Message.ENCRYPTION - + " NUMBER, " + Message.STATUS + " NUMBER," +Message.TYPE +" 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);"); + + " NUMBER, " + Message.STATUS + " NUMBER," + Message.TYPE + + " NUMBER, FOREIGN KEY(" + Message.CONVERSATION + + ") REFERENCES " + Conversation.TABLENAME + "(" + + Conversation.UUID + ") ON DELETE CASCADE);"); + + db.execSQL(CREATE_CONTATCS_STATEMENT); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (oldVersion < 2 && newVersion >= 2) { - // enable compression by default. - db.execSQL("update " + Account.TABLENAME - + " set " + Account.OPTIONS + " = " + Account.OPTIONS + " | 8"); + db.execSQL("update " + Account.TABLENAME + " set " + + Account.OPTIONS + " = " + Account.OPTIONS + " | 8"); } if (oldVersion < 3 && newVersion >= 3) { - //add field type to message - db.execSQL("ALTER TABLE "+Message.TABLENAME+" ADD COLUMN "+Message.TYPE+" NUMBER");; + db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + + Message.TYPE + " NUMBER"); + } + if (oldVersion < 5 && newVersion >= 5) { + db.execSQL("DROP TABLE "+Contact.TABLENAME); + db.execSQL(CREATE_CONTATCS_STATEMENT); + db.execSQL("UPDATE "+Account.TABLENAME+ " SET "+Account.ROSTERVERSION+" = NULL"); } } @@ -99,7 +106,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { 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()); @@ -145,10 +152,10 @@ public class DatabaseBackend extends SQLiteOpenHelper { public Conversation findConversation(Account account, String contactJid) { SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { account.getUuid(), contactJid+"%" }; + String[] selectionArgs = { account.getUuid(), contactJid + "%" }; Cursor cursor = db.query(Conversation.TABLENAME, null, - Conversation.ACCOUNT + "=? AND " + Conversation.CONTACTJID + " like ?", - selectionArgs, null, null, null); + Conversation.ACCOUNT + "=? AND " + Conversation.CONTACTJID + + " like ?", selectionArgs, null, null, null); if (cursor.getCount() == 0) return null; cursor.moveToFirst(); @@ -200,87 +207,20 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.update(Message.TABLENAME, message.getContentValues(), Message.UUID + "=?", args); } - - public void updateContact(Contact contact, boolean updatePresences) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { contact.getUuid() }; - ContentValues values = contact.getContentValues(); - if (!updatePresences) { - values.remove(Contact.PRESENCES); - } else { - values.remove(Contact.DISPLAYNAME); - values.remove(Contact.PHOTOURI); - values.remove(Contact.SYSTEMACCOUNT); - } - 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 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)); - updateContact(contact,false); - } else { - contact.setUuid(UUID.randomUUID().toString()); - createContact(contact); - } - } - } - public List getContactsByAccount(Account account) { - List list = new ArrayList(); + public void readRoster(Roster roster) { 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); - } + String args[] = { roster.getAccount().getUuid() }; + cursor = db.query(Contact.TABLENAME, null, Contact.ACCOUNT + "=?", + args, null, null, null); while (cursor.moveToNext()) { - list.add(Contact.fromCursor(cursor)); + roster.initContact(Contact.fromCursor(cursor)); } - return list; } - public List getContacts(String where) { - List list = new ArrayList(); - 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 writeRoster(Roster roster) { + } public void deleteMessage(Message message) { @@ -288,7 +228,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { String[] args = { message.getUuid() }; db.delete(Message.TABLENAME, Message.UUID + "=?", args); } - + public void deleteMessagesInConversation(Conversation conversation) { SQLiteDatabase db = this.getWritableDatabase(); String[] args = { conversation.getUuid() }; @@ -304,7 +244,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { public Contact getContact(String uuid) { SQLiteDatabase db = this.getWritableDatabase(); String[] args = { uuid }; - Cursor cursor = db.query(Contact.TABLENAME, null, Contact.UUID + "=?", args, null, null, null); + Cursor cursor = db.query(Contact.TABLENAME, null, Contact.UUID + "=?", + args, null, null, null); if (cursor.getCount() == 0) { return null; } @@ -315,7 +256,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { public Conversation findConversationByUuid(String conversationUuid) { SQLiteDatabase db = this.getReadableDatabase(); String[] selectionArgs = { conversationUuid }; - Cursor cursor = db.query(Conversation.TABLENAME, null, Conversation.UUID + "=?", selectionArgs, null, null, null); + Cursor cursor = db.query(Conversation.TABLENAME, null, + Conversation.UUID + "=?", selectionArgs, null, null, null); if (cursor.getCount() == 0) { return null; } @@ -326,18 +268,20 @@ public class DatabaseBackend extends SQLiteOpenHelper { public Message findMessageByUuid(String messageUuid) { SQLiteDatabase db = this.getReadableDatabase(); String[] selectionArgs = { messageUuid }; - Cursor cursor = db.query(Message.TABLENAME, null, Message.UUID + "=?", selectionArgs, null, null, null); + Cursor cursor = db.query(Message.TABLENAME, null, Message.UUID + "=?", + selectionArgs, null, null, null); if (cursor.getCount() == 0) { return null; } cursor.moveToFirst(); return Message.fromCursor(cursor); } - + public Account findAccountByUuid(String accountUuid) { SQLiteDatabase db = this.getReadableDatabase(); String[] selectionArgs = { accountUuid }; - Cursor cursor = db.query(Account.TABLENAME, null, Account.UUID + "=?", selectionArgs, null, null, null); + Cursor cursor = db.query(Account.TABLENAME, null, Account.UUID + "=?", + selectionArgs, null, null, null); if (cursor.getCount() == 0) { return null; } diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 3a02b40e..5af53a3c 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -27,10 +27,8 @@ import eu.siacs.conversations.entities.Presences; import eu.siacs.conversations.parser.MessageParser; import eu.siacs.conversations.persistance.DatabaseBackend; import eu.siacs.conversations.persistance.FileBackend; -import eu.siacs.conversations.persistance.OnPhoneContactsMerged; import eu.siacs.conversations.ui.OnAccountListChangedListener; import eu.siacs.conversations.ui.OnConversationListChangedListener; -import eu.siacs.conversations.ui.OnRosterFetchedListener; import eu.siacs.conversations.ui.UiCallback; import eu.siacs.conversations.utils.ExceptionHelper; import eu.siacs.conversations.utils.OnPhoneContactsLoadedListener; @@ -57,13 +55,13 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.database.ContentObserver; -import android.database.DatabaseUtils; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; +import android.os.Looper; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.os.SystemClock; @@ -84,6 +82,8 @@ public class XmppConnectionService extends Service { private static final int PING_TIMEOUT = 5; private static final int CONNECT_TIMEOUT = 60; private static final long CARBON_GRACE_PERIOD = 60000L; + + private static String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts"; private MessageParser mMessageParser = new MessageParser(this); @@ -110,8 +110,9 @@ public class XmppConnectionService extends Service { @Override public void onChange(boolean selfChange) { super.onChange(selfChange); - Log.d(LOGTAG, "contact list has changed"); - mergePhoneContactsWithRoster(null); + Intent intent = new Intent(getApplicationContext(), XmppConnectionService.class); + intent.setAction(ACTION_MERGE_PHONE_CONTACTS); + startService(intent); } }; @@ -300,17 +301,14 @@ public class XmppConnectionService extends Service { } } else { - Contact contact = findContact(account, fromParts[0]); - if (contact == null) { - if ("subscribe".equals(type)) { - account.getXmppConnection().addPendingSubscription( - fromParts[0]); - } else { - // Log.d(LOGTAG,packet.getFrom()+ - // " could not be found"); - } - return; - } + Contact contact = account.getRoster().getContact( + packet.getFrom()); + /* + * if (contact == null) { if ("subscribe".equals(type)) { + * account.getXmppConnection().addPendingSubscription( + * fromParts[0]); } else { // Log.d(LOGTAG,packet.getFrom()+ + * // " could not be found"); } return; } + */ if (type == null) { if (fromParts.length == 2) { contact.updatePresence(fromParts[1], Presences @@ -337,9 +335,6 @@ public class XmppConnectionService extends Service { + contact.getPgpKeyId()); } } - replaceContactInConversation(account, - contact.getJid(), contact); - databaseBackend.updateContact(contact, true); } else { // Log.d(LOGTAG,"presence without resource "+packet.toString()); } @@ -349,25 +344,16 @@ public class XmppConnectionService extends Service { } else { contact.removePresence(fromParts[1]); } - replaceContactInConversation(account, contact.getJid(), - contact); - databaseBackend.updateContact(contact, true); } else if (type.equals("subscribe")) { Log.d(LOGTAG, "received subscribe packet from " + packet.getFrom()); - if (contact - .getSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT)) { + if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) { Log.d(LOGTAG, "preemptive grant; granting"); sendPresenceUpdatesTo(contact); - contact.setSubscriptionOption(Contact.Subscription.FROM); - contact.resetSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT); - replaceContactInConversation(account, - contact.getJid(), contact); - databaseBackend.updateContact(contact, false); - if ((contact - .getSubscriptionOption(Contact.Subscription.ASKING)) - && (!contact - .getSubscriptionOption(Contact.Subscription.TO))) { + contact.setOption(Contact.Options.FROM); + contact.resetOption(Contact.Options.PREEMPTIVE_GRANT); + if ((contact.getOption(Contact.Options.ASKING)) + && (!contact.getOption(Contact.Options.TO))) { requestPresenceUpdatesFrom(contact); } } else { @@ -391,7 +377,6 @@ public class XmppConnectionService extends Service { if ((from == null) || (from.equals(account.getJid()))) { Element query = packet.findChild("query"); processRosterItems(account, query); - mergePhoneContactsWithRoster(null); } else { Log.d(LOGTAG, "unauthorized roster push from: " + from); } @@ -508,51 +493,25 @@ public class XmppConnectionService extends Service { private void processRosterItems(Account account, Element elements) { String version = elements.getAttribute("ver"); if (version != null) { - account.setRosterVersion(version); - databaseBackend.updateAccount(account); + account.getRoster().setVersion(version); } for (Element item : elements.getChildren()) { if (item.getName().equals("item")) { String jid = item.getAttribute("jid"); + String name = item.getAttribute("name"); 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); - } + Contact contact = account.getRoster().getContact(jid); + contact.setServerName(name); + if (subscription.equals("remove")) { + contact.resetOption(Contact.Options.IN_ROSTER); } else { - if (subscription.equals("remove")) { - databaseBackend.deleteContact(contact); - replaceContactInConversation(account, contact.getJid(), - null); - } else { - contact.parseSubscriptionFromElement(item); - databaseBackend.updateContact(contact, false); - replaceContactInConversation(account, contact.getJid(), - contact); - } + contact.setOption(Contact.Options.IN_ROSTER); + contact.parseSubscriptionFromElement(item); } } } } - private void replaceContactInConversation(Account account, String jid, - Contact contact) { - List conversations = getConversations(); - for (Conversation c : conversations) { - if (c.getContactJid().equals(jid) && (c.getAccount() == account)) { - c.setContact(contact); - break; - } - } - } - public class XmppConnectionBinder extends Binder { public XmppConnectionService getService() { return XmppConnectionService.this; @@ -562,7 +521,9 @@ public class XmppConnectionService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { this.wakeLock.acquire(); - // Log.d(LOGTAG,"calling start service. caller was:"+intent.getAction()); + if ((intent.getAction()!=null)&&(intent.getAction().equals(ACTION_MERGE_PHONE_CONTACTS))) { + mergePhoneContactsWithRoster(); + } ConnectivityManager cm = (ConnectivityManager) getApplicationContext() .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); @@ -636,6 +597,10 @@ public class XmppConnectionService extends Service { this.fileBackend = new FileBackend(getApplicationContext()); this.accounts = databaseBackend.getAccounts(); + for (Account account : this.accounts) { + this.databaseBackend.readRoster(account.getRoster()); + } + this.mergePhoneContactsWithRoster(); this.getConversations(); getContentResolver().registerContentObserver( @@ -654,6 +619,7 @@ public class XmppConnectionService extends Service { Log.d(LOGTAG, "stopping service"); super.onDestroy(); for (Account account : accounts) { + databaseBackend.writeRoster(account.getRoster()); if (account.getXmppConnection() != null) { disconnect(account, true); } @@ -725,10 +691,10 @@ public class XmppConnectionService extends Service { connection.setOnBindListener(new OnBindListener() { @Override - public void onBind(Account account) { - databaseBackend.clearPresences(account); //contact presences + public void onBind(final Account account) { + account.getRoster().clearPresences(); account.clearPresences(); // self presences - updateRoster(account, null); + fetchRosterFromServer(account); sendPresence(account); connectMultiModeConversations(account); if (convChangedListener != null) { @@ -887,27 +853,7 @@ public class XmppConnectionService extends Service { return packet; } - private void getRoster(Account account, - final OnRosterFetchedListener listener) { - List contacts = databaseBackend.getContactsByAccount(account); - for (int i = 0; i < contacts.size(); ++i) { - contacts.get(i).setAccount(account); - } - if (listener != null) { - listener.onRosterFetched(contacts); - } - } - - public List getRoster(Account account) { - List contacts = databaseBackend.getContactsByAccount(account); - for (int i = 0; i < contacts.size(); ++i) { - contacts.get(i).setAccount(account); - } - return contacts; - } - - public void updateRoster(final Account account, - final OnRosterFetchedListener listener) { + public void fetchRosterFromServer(Account account) { IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET); if (!"".equals(account.getRosterVersion())) { Log.d(LOGTAG, account.getJid() + ": fetching roster version " @@ -925,62 +871,23 @@ public class XmppConnectionService extends Service { IqPacket packet) { Element roster = packet.findChild("query"); if (roster != null) { - Log.d(LOGTAG, account.getJid() - + ": processing roster"); + account.getRoster().markAllAsNotInRoster(); processRosterItems(account, roster); - StringBuilder mWhere = new StringBuilder(); - mWhere.append("jid NOT IN("); - List 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 contactsToDelete = databaseBackend - .getContacts(mWhere.toString()); - for (Contact contact : contactsToDelete) { - databaseBackend.deleteContact(contact); - replaceContactInConversation(account, - contact.getJid(), null); - } - - } else { - Log.d(LOGTAG, account.getJid() - + ": empty roster returend"); } - mergePhoneContactsWithRoster(new OnPhoneContactsMerged() { - - @Override - public void phoneContactsMerged() { - if (listener != null) { - getRoster(account, listener); - } - } - }); } }); } - public void mergePhoneContactsWithRoster( - final OnPhoneContactsMerged listener) { + private void mergePhoneContactsWithRoster() { PhoneHelper.loadPhoneContacts(getApplicationContext(), new OnPhoneContactsLoadedListener() { @Override - public void onPhoneContactsLoaded( - Hashtable phoneContacts) { - List contacts = databaseBackend - .getContactsByAccount(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()); + public void onPhoneContactsLoaded(List phoneContacts) { + for (Bundle phoneContact : phoneContacts) { + for (Account account : accounts) { + String jid = phoneContact.getString("jid"); + Contact contact = account.getRoster() + .getContact(jid); String systemAccount = phoneContact .getInt("phoneid") + "#" @@ -988,28 +895,10 @@ public class XmppConnectionService extends Service { contact.setSystemAccount(systemAccount); contact.setPhotoUri(phoneContact .getString("photouri")); - contact.setDisplayName(phoneContact + contact.setSystemName(phoneContact .getString("displayname")); - databaseBackend.updateContact(contact, false); - replaceContactInConversation( - contact.getAccount(), contact.getJid(), - contact); - } else { - if ((contact.getSystemAccount() != null) - || (contact.getProfilePhoto() != null)) { - contact.setSystemAccount(null); - contact.setPhotoUri(null); - databaseBackend.updateContact(contact, - false); - replaceContactInConversation( - contact.getAccount(), - contact.getJid(), contact); - } } } - if (listener != null) { - listener.phoneContactsMerged(); - } } }); } @@ -1025,7 +914,6 @@ public class XmppConnectionService extends Service { 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)); } } @@ -1043,14 +931,6 @@ public class XmppConnectionService extends Service { 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()) { @@ -1072,11 +952,9 @@ public class XmppConnectionService extends Service { conversation.setMessages(databaseBackend.getMessages(conversation, 50)); this.databaseBackend.updateConversation(conversation); - conversation.setContact(findContact(account, - conversation.getContactJid())); } else { String conversationName; - Contact contact = findContact(account, jid); + Contact contact = account.getRoster().getContact(jid); if (contact != null) { conversationName = contact.getDisplayName(); } else { @@ -1089,7 +967,6 @@ public class XmppConnectionService extends Service { conversation = new Conversation(conversationName, account, jid, Conversation.MODE_SINGLE); } - conversation.setContact(contact); this.databaseBackend.createConversation(conversation); } this.conversations.add(conversation); @@ -1137,17 +1014,6 @@ public class XmppConnectionService extends Service { accountChangedListener.onAccountListChangedListener(); } - public void deleteContact(Contact contact) { - IqPacket iq = new IqPacket(IqPacket.TYPE_SET); - Element query = iq.query("jabber:iq:roster"); - query.addChild("item").setAttribute("jid", contact.getJid()) - .setAttribute("subscription", "remove"); - contact.getAccount().getXmppConnection().sendIqPacket(iq, null); - replaceContactInConversation(contact.getAccount(), contact.getJid(), - null); - databaseBackend.deleteContact(contact); - } - public void updateAccount(Account account) { this.statusListener.onStatusChanged(account); databaseBackend.updateAccount(account); @@ -1308,12 +1174,6 @@ public class XmppConnectionService extends Service { return mBinder; } - public void updateContact(Contact contact) { - databaseBackend.updateContact(contact, false); - replaceContactInConversation(contact.getAccount(), contact.getJid(), - contact); - } - public void updateMessage(Message message) { databaseBackend.updateMessage(message); } @@ -1322,30 +1182,34 @@ public class XmppConnectionService extends Service { SharedPreferences sharedPref = getPreferences(); boolean autoGrant = sharedPref.getBoolean("grant_new_contacts", true); if (autoGrant) { - contact.setSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT); - contact.setSubscriptionOption(Contact.Subscription.ASKING); + contact.setOption(Contact.Options.PREEMPTIVE_GRANT); + contact.setOption(Contact.Options.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); + pushContactToServer(contact); if (autoGrant) { requestPresenceUpdatesFrom(contact); - if (account.getXmppConnection().hasPendingSubscription( + if (contact.getAccount().getXmppConnection().hasPendingSubscription( contact.getJid())) { Log.d("xmppService", "contact had pending subscription"); sendPresenceUpdatesTo(contact); } } - replaceContactInConversation(contact.getAccount(), contact.getJid(), - contact); + } + + public void pushContactToServer(Contact contact) { + IqPacket iq = new IqPacket(IqPacket.TYPE_SET); + iq.query("jabber:iq:roster").addChild(contact.asElement()); + Account account = contact.getAccount(); + account.getXmppConnection().sendIqPacket(iq, null); + } + + public void deleteContactOnServer(Contact contact) { + IqPacket iq = new IqPacket(IqPacket.TYPE_SET); + Element item = iq.query("jabber:iq:roster").addChild("item"); + item.setAttribute("jid", contact.getJid()); + item.setAttribute("subscription", "remove"); + Account account = contact.getAccount(); + account.getXmppConnection().sendIqPacket(iq, null); } public void requestPresenceUpdatesFrom(Contact contact) { @@ -1392,11 +1256,10 @@ public class XmppConnectionService extends Service { PresencePacket packet = new PresencePacket(); packet.setAttribute("from", account.getFullJid()); String sig = account.getPgpSignature(); - if (sig!=null) { + if (sig != null) { packet.addChild("status").setContent("online"); - packet.addChild("x","jabber:x:signed").setContent(sig); + packet.addChild("x", "jabber:x:signed").setContent(sig); } - Log.d(LOGTAG,packet.toString()); account.getXmppConnection().sendPresencePacket(packet); } @@ -1404,18 +1267,6 @@ public class XmppConnectionService extends Service { this.databaseBackend.updateConversation(conversation); } - public Contact findContact(String uuid) { - Contact contact = this.databaseBackend.getContact(uuid); - if (contact != null) { - for (Account account : getAccounts()) { - if (contact.getAccountUuid().equals(account.getUuid())) { - contact.setAccount(account); - } - } - } - return contact; - } - public void removeOnTLSExceptionReceivedListener() { this.tlsException = null; } @@ -1517,4 +1368,13 @@ public class XmppConnectionService extends Service { getConversations(), conversation, notify); } } + + public Account findAccountByJid(String accountJid) { + for (Account account : this.accounts) { + if (account.getJid().equals(accountJid)) { + return account; + } + } + return null; + } } diff --git a/src/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/eu/siacs/conversations/ui/ContactDetailsActivity.java index 06179bc6..72a0909a 100644 --- a/src/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -1,8 +1,6 @@ package eu.siacs.conversations.ui; -import java.math.BigInteger; import java.util.Iterator; -import java.util.Locale; import org.openintents.openpgp.util.OpenPgpUtils; @@ -17,7 +15,6 @@ 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.Menu; import android.view.MenuItem; @@ -31,6 +28,7 @@ import android.widget.TextView; import android.widget.Toast; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.PgpEngine; +import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Presences; import eu.siacs.conversations.utils.UIHelper; @@ -40,12 +38,14 @@ public class ContactDetailsActivity extends XmppActivity { protected ContactDetailsActivity activity = this; - private String uuid; private Contact contact; - + + private String accountJid; + private String contactJid; + private EditText name; - private TextView contactJid; - private TextView accountJid; + private TextView contactJidTv; + private TextView accountJidTv; private TextView status; private TextView askAgain; private CheckBox send; @@ -56,7 +56,7 @@ public class ContactDetailsActivity extends XmppActivity { @Override public void onClick(DialogInterface dialog, int which) { - activity.xmppConnectionService.deleteContact(contact); + activity.xmppConnectionService.deleteContactOnServer(contact); activity.finish(); } }; @@ -65,8 +65,8 @@ public class ContactDetailsActivity extends XmppActivity { @Override public void onClick(DialogInterface dialog, int which) { - contact.setDisplayName(name.getText().toString()); - activity.xmppConnectionService.updateContact(contact); + contact.setServerName(name.getText().toString()); + activity.xmppConnectionService.pushContactToServer(contact); populateView(); } }; @@ -104,12 +104,13 @@ public class ContactDetailsActivity extends XmppActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getIntent().getAction().equals(ACTION_VIEW_CONTACT)) { - this.uuid = getIntent().getExtras().getString("uuid"); + this.accountJid = getIntent().getExtras().getString("account"); + this.contactJid = getIntent().getExtras().getString("contact"); } setContentView(R.layout.activity_contact_details); - contactJid = (TextView) findViewById(R.id.details_contactjid); - accountJid = (TextView) findViewById(R.id.details_account); + contactJidTv = (TextView) findViewById(R.id.details_contactjid); + accountJidTv = (TextView) findViewById(R.id.details_account); status = (TextView) findViewById(R.id.details_contactstatus); send = (CheckBox) findViewById(R.id.details_send_presence); receive = (CheckBox) findViewById(R.id.details_receive_presence); @@ -170,18 +171,18 @@ public class ContactDetailsActivity extends XmppActivity { private void populateView() { setTitle(contact.getDisplayName()); - if (contact.getSubscriptionOption(Contact.Subscription.FROM)) { + if (contact.getOption(Contact.Options.FROM)) { send.setChecked(true); } else { send.setText(R.string.preemptively_grant); if (contact - .getSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT)) { + .getOption(Contact.Options.PREEMPTIVE_GRANT)) { send.setChecked(true); } else { send.setChecked(false); } } - if (contact.getSubscriptionOption(Contact.Subscription.TO)) { + if (contact.getOption(Contact.Options.TO)) { receive.setChecked(true); } else { receive.setText(R.string.ask_for_presence_updates); @@ -195,7 +196,7 @@ public class ContactDetailsActivity extends XmppActivity { } }); - if (contact.getSubscriptionOption(Contact.Subscription.ASKING)) { + if (contact.getOption(Contact.Options.ASKING)) { receive.setChecked(true); } else { receive.setChecked(false); @@ -233,11 +234,11 @@ public class ContactDetailsActivity extends XmppActivity { break; } if (contact.getPresences().size() > 1) { - contactJid.setText(contact.getJid()+" ("+contact.getPresences().size()+")"); + contactJidTv.setText(contact.getJid()+" ("+contact.getPresences().size()+")"); } else { - contactJid.setText(contact.getJid()); + contactJidTv.setText(contact.getJid()); } - accountJid.setText(contact.getAccount().getJid()); + accountJidTv.setText(contact.getAccount().getJid()); UIHelper.prepareContactBadge(this, badge, contact, getApplicationContext()); @@ -286,65 +287,66 @@ public class ContactDetailsActivity extends XmppActivity { @Override public void onBackendConnected() { - if (uuid != null) { - this.contact = xmppConnectionService.findContact(uuid); - if (this.contact != null) { - populateView(); + if ((accountJid != null)&&(contactJid != null)) { + Account account = xmppConnectionService.findAccountByJid(accountJid); + if (account==null) { + return; } + this.contact = account.getRoster().getContact(contactJid); + populateView(); } } @Override protected void onStop() { super.onStop(); - boolean needsUpdating = false; - if (contact.getSubscriptionOption(Contact.Subscription.FROM)) { + boolean updated = false; + if (contact.getOption(Contact.Options.FROM)) { if (!send.isChecked()) { - contact.resetSubscriptionOption(Contact.Subscription.FROM); - contact.resetSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT); + contact.resetOption(Contact.Options.FROM); + contact.resetOption(Contact.Options.PREEMPTIVE_GRANT); activity.xmppConnectionService.stopPresenceUpdatesTo(contact); - needsUpdating = true; + updated = true; } } else { if (contact - .getSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT)) { + .getOption(Contact.Options.PREEMPTIVE_GRANT)) { if (!send.isChecked()) { - contact.resetSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT); - needsUpdating = true; + contact.resetOption(Contact.Options.PREEMPTIVE_GRANT); + updated = true; } } else { if (send.isChecked()) { - contact.setSubscriptionOption(Contact.Subscription.PREEMPTIVE_GRANT); - needsUpdating = true; + contact.setOption(Contact.Options.PREEMPTIVE_GRANT); + updated = true; } } } - if (contact.getSubscriptionOption(Contact.Subscription.TO)) { + if (contact.getOption(Contact.Options.TO)) { if (!receive.isChecked()) { - contact.resetSubscriptionOption(Contact.Subscription.TO); + contact.resetOption(Contact.Options.TO); activity.xmppConnectionService.stopPresenceUpdatesFrom(contact); - needsUpdating = true; + updated = true; } } else { - if (contact.getSubscriptionOption(Contact.Subscription.ASKING)) { + if (contact.getOption(Contact.Options.ASKING)) { if (!receive.isChecked()) { - contact.resetSubscriptionOption(Contact.Subscription.ASKING); + contact.resetOption(Contact.Options.ASKING); activity.xmppConnectionService .stopPresenceUpdatesFrom(contact); - needsUpdating = true; + updated = true; } } else { if (receive.isChecked()) { - contact.setSubscriptionOption(Contact.Subscription.ASKING); + contact.setOption(Contact.Options.ASKING); activity.xmppConnectionService .requestPresenceUpdatesFrom(contact); - needsUpdating = true; + updated = true; } } } - if (needsUpdating) { + if (updated) { Toast.makeText(getApplicationContext(), "Subscription updated", Toast.LENGTH_SHORT).show(); - activity.xmppConnectionService.updateContact(contact); } } diff --git a/src/eu/siacs/conversations/ui/ContactsActivity.java b/src/eu/siacs/conversations/ui/ContactsActivity.java index 6e15b678..d703b172 100644 --- a/src/eu/siacs/conversations/ui/ContactsActivity.java +++ b/src/eu/siacs/conversations/ui/ContactsActivity.java @@ -18,7 +18,6 @@ import android.os.Bundle; import android.preference.PreferenceManager; import android.text.Editable; import android.text.TextWatcher; -import android.util.Log; import android.util.SparseBooleanArray; import android.view.ActionMode; import android.view.LayoutInflater; @@ -34,13 +33,11 @@ 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.widget.Toast; import android.annotation.SuppressLint; import android.app.AlertDialog; -import android.app.AlertDialog.Builder; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; @@ -130,8 +127,10 @@ public class ContactsActivity extends XmppActivity { Intent intent = new Intent(getApplicationContext(), ContactDetailsActivity.class); intent.setAction(ContactDetailsActivity.ACTION_VIEW_CONTACT); - intent.putExtra("uuid", selectedContacts.get(0).getUuid()); + intent.putExtra("account", selectedContacts.get(0).getAccount().getJid()); + intent.putExtra("contact",selectedContacts.get(0).getJid()); startActivity(intent); + finish(); break; case R.id.action_invite: invite(); @@ -270,7 +269,7 @@ public class ContactsActivity extends XmppActivity { aggregatedContacts.clear(); for (Contact contact : rosterContacts) { - if (contact.match(searchString)) + if (contact.match(searchString)&&(contact.getOption(Contact.Options.IN_ROSTER))) aggregatedContacts.add(contact); } @@ -287,9 +286,8 @@ public class ContactsActivity extends XmppActivity { if (aggregatedContacts.size() == 0) { if (Validator.isValidJid(searchString)) { - String name = searchString.split("@")[0]; - Contact newContact = new Contact(null, name, searchString, null); - newContact.flagAsNotInRoster(); + Contact newContact = new Contact(searchString); + newContact.resetOption(Contact.Options.IN_ROSTER); aggregatedContacts.add(newContact); contactsHeader.setText("Create new contact"); } else { @@ -463,7 +461,7 @@ public class ContactsActivity extends XmppActivity { } public void startConversation(Contact contact, Account account, boolean muc) { - if (!contact.isInRoster()&&(!muc)) { + if (!contact.getOption(Contact.Options.IN_ROSTER)&&(!muc)) { xmppConnectionService.createContact(contact); } Conversation conversation = xmppConnectionService @@ -517,7 +515,7 @@ public class ContactsActivity extends XmppActivity { this.rosterContacts.clear(); for(Account account : accounts) { if (account.getStatus() != Account.STATUS_DISABLED) { - rosterContacts.addAll(xmppConnectionService.getRoster(account)); + rosterContacts.addAll(account.getRoster().getContacts()); } } updateAggregatedContacts(); @@ -533,52 +531,12 @@ public class ContactsActivity extends XmppActivity { @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - 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 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(); - } - }); - } - }); - } - } - } - @Override public void onActionModeStarted(ActionMode mode) { super.onActionModeStarted(mode); diff --git a/src/eu/siacs/conversations/ui/ConversationActivity.java b/src/eu/siacs/conversations/ui/ConversationActivity.java index c3626ee1..346cd2fc 100644 --- a/src/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/eu/siacs/conversations/ui/ConversationActivity.java @@ -474,10 +474,11 @@ public class ConversationActivity extends XmppActivity { break; case R.id.action_contact_details: Contact contact = this.getSelectedConversation().getContact(); - if (contact != null) { + if (contact.getOption(Contact.Options.IN_ROSTER)) { Intent intent = new Intent(this, ContactDetailsActivity.class); intent.setAction(ContactDetailsActivity.ACTION_VIEW_CONTACT); - intent.putExtra("uuid", contact.getUuid()); + intent.putExtra("account", this.getSelectedConversation().getAccount().getJid()); + intent.putExtra("contact",contact.getJid()); startActivity(intent); } else { showAddToRosterDialog(getSelectedConversation()); @@ -874,8 +875,7 @@ public class ConversationActivity extends XmppActivity { public void onClick(DialogInterface dialog, int which) { String jid = conversation.getContactJid(); Account account = getSelectedConversation().getAccount(); - String name = jid.split("@")[0]; - Contact contact = new Contact(account, name, jid, null); + Contact contact = account.getRoster().getContact(jid); xmppConnectionService.createContact(contact); } }); diff --git a/src/eu/siacs/conversations/ui/ShareWithActivity.java b/src/eu/siacs/conversations/ui/ShareWithActivity.java index 1bc9fc46..ccb1e8e7 100644 --- a/src/eu/siacs/conversations/ui/ShareWithActivity.java +++ b/src/eu/siacs/conversations/ui/ShareWithActivity.java @@ -102,7 +102,7 @@ public class ShareWithActivity extends XmppActivity { contacts.removeAllViews(); final List contactsList = new ArrayList(); for(Account account : xmppConnectionService.getAccounts()) { - for(final Contact contact : xmppConnectionService.getRoster(account)) { + for(final Contact contact : account.getRoster().getContacts()) { if (!displayedContacts.contains(contact.getUuid())) { contactsList.add(contact); } diff --git a/src/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java b/src/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java index fa8cea04..9a689768 100644 --- a/src/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java +++ b/src/eu/siacs/conversations/utils/OnPhoneContactsLoadedListener.java @@ -1,9 +1,9 @@ package eu.siacs.conversations.utils; -import java.util.Hashtable; +import java.util.List; import android.os.Bundle; public interface OnPhoneContactsLoadedListener { - public void onPhoneContactsLoaded(Hashtable phoneContacts); + public void onPhoneContactsLoaded(List phoneContacts); } diff --git a/src/eu/siacs/conversations/utils/PhoneHelper.java b/src/eu/siacs/conversations/utils/PhoneHelper.java index 6355e378..773312bb 100644 --- a/src/eu/siacs/conversations/utils/PhoneHelper.java +++ b/src/eu/siacs/conversations/utils/PhoneHelper.java @@ -1,8 +1,8 @@ package eu.siacs.conversations.utils; -import java.util.Hashtable; +import java.util.ArrayList; +import java.util.List; -import android.app.Activity; import android.content.Context; import android.content.CursorLoader; import android.content.Loader; @@ -10,21 +10,15 @@ 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; -import android.provider.MediaStore; 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 phoneContacts = new Hashtable(); - + final List phoneContacts = new ArrayList(); + final String[] PROJECTION = new String[] { ContactsContract.Data._ID, ContactsContract.Data.DISPLAY_NAME, ContactsContract.Data.PHOTO_THUMBNAIL_URI, @@ -58,15 +52,14 @@ public class PhoneHelper { .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); + + contact.putString("jid",cursor.getString(cursor + .getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA))); + phoneContacts.add(contact); } if (listener != null) { listener.onPhoneContactsLoaded(phoneContacts); } - mLooper.quit(); } }); mCursorLoader.startLoading(); diff --git a/src/eu/siacs/conversations/utils/UIHelper.java b/src/eu/siacs/conversations/utils/UIHelper.java index ef291c2b..e6aca397 100644 --- a/src/eu/siacs/conversations/utils/UIHelper.java +++ b/src/eu/siacs/conversations/utils/UIHelper.java @@ -506,7 +506,7 @@ public class UIHelper { public void onClick(DialogInterface dialog, int which) { contact.addOtrFingerprint(conversation.getOtrFingerprint()); msg.setVisibility(View.GONE); - activity.xmppConnectionService.updateContact(contact); + //activity.xmppConnectionService.updateContact(contact); } }); builder.setView(view); -- cgit v1.2.3