Merge branch 'development' of https://github.com/siacs/Conversations into development
This commit is contained in:
		
						commit
						2a1067b20a
					
				|  | @ -1,11 +1,5 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <menu xmlns:android="http://schemas.android.com/apk/res/android" > | ||||
|     <item | ||||
|         android:id="@+id/action_refresh_contacts" | ||||
|         android:orderInCategory="10" | ||||
|         android:showAsAction="always" | ||||
|         android:icon="@drawable/ic_action_refresh" | ||||
|         android:title="@string/action_refresh" /> | ||||
|     <item | ||||
|         android:id="@+id/action_accounts" | ||||
|         android:orderInCategory="90" | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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; | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -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 class Subscription { | ||||
| 	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 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; | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -49,7 +49,6 @@ public class Conversation extends AbstractEntity { | |||
| 
 | ||||
| 	private transient List<Message> 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) { | ||||
|  |  | |||
|  | @ -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<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; | ||||
| 	} | ||||
| 
 | ||||
| 	public static int parseShow(Element show) { | ||||
| 		if (show == null) { | ||||
| 			return Presences.ONLINE; | ||||
|  |  | |||
|  | @ -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<String, Contact> contacts = new HashMap<String, Contact>(); | ||||
| 	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<Contact> getContacts() { | ||||
| 		return new ArrayList<Contact>(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; | ||||
| 	} | ||||
| } | ||||
|  | @ -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"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -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(); | ||||
|  | @ -201,86 +208,19 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||
| 				+ "=?", 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<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)); | ||||
| 				updateContact(contact,false); | ||||
| 			} else { | ||||
| 				contact.setUuid(UUID.randomUUID().toString()); | ||||
| 				createContact(contact); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public List<Contact> getContactsByAccount(Account account) { | ||||
| 		List<Contact> list = new ArrayList<Contact>(); | ||||
| 	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<Contact> getContacts(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 void writeRoster(Roster roster) { | ||||
| 		 | ||||
| 	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) { | ||||
|  | @ -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,7 +268,8 @@ 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; | ||||
| 		} | ||||
|  | @ -337,7 +280,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { | |||
| 	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; | ||||
| 		} | ||||
|  |  | |||
|  | @ -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; | ||||
|  | @ -85,6 +83,8 @@ public class XmppConnectionService extends Service { | |||
| 	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); | ||||
| 
 | ||||
| 	private List<Account> accounts; | ||||
|  | @ -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<Conversation> 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<Contact> 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<Contact> getRoster(Account account) { | ||||
| 		List<Contact> 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<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 | ||||
| 									.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<String, Bundle> phoneContacts) { | ||||
| 						List<Contact> 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<Bundle> 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; | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -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); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<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(); | ||||
| 									} | ||||
| 								}); | ||||
| 							} | ||||
| 						}); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void onActionModeStarted(ActionMode mode) { | ||||
| 		super.onActionModeStarted(mode); | ||||
|  |  | |||
|  | @ -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); | ||||
| 			} | ||||
| 		}); | ||||
|  |  | |||
|  | @ -263,7 +263,7 @@ public class ConversationFragment extends Fragment { | |||
| 			} | ||||
| 
 | ||||
| 			private void displayInfoMessage(ViewHolder viewHolder, int r) { | ||||
| 				if (viewHolder.download_button!=null) { | ||||
| 				if (viewHolder.download_button != null) { | ||||
| 					viewHolder.download_button.setVisibility(View.GONE); | ||||
| 				} | ||||
| 				viewHolder.image.setVisibility(View.GONE); | ||||
|  | @ -329,7 +329,8 @@ public class ConversationFragment extends Fragment { | |||
| 					@Override | ||||
| 					public void onClick(View v) { | ||||
| 						Intent intent = new Intent(Intent.ACTION_VIEW); | ||||
| 						intent.setDataAndType(ImageProvider.getContentUri(message), "image/*"); | ||||
| 						intent.setDataAndType( | ||||
| 								ImageProvider.getContentUri(message), "image/*"); | ||||
| 						startActivity(intent); | ||||
| 					} | ||||
| 				}); | ||||
|  | @ -486,7 +487,7 @@ public class ConversationFragment extends Fragment { | |||
| 	@Override | ||||
| 	public void onStop() { | ||||
| 		super.onStop(); | ||||
| 		if (this.conversation!=null) { | ||||
| 		if (this.conversation != null) { | ||||
| 			this.conversation.setNextMessage(chatMsg.getText().toString()); | ||||
| 		} | ||||
| 	} | ||||
|  | @ -577,13 +578,15 @@ public class ConversationFragment extends Fragment { | |||
| 	} | ||||
| 
 | ||||
| 	public void updateMessages() { | ||||
| 		if (getView()==null) { | ||||
| 		if (getView() == null) { | ||||
| 			return; | ||||
| 		} | ||||
| 		ConversationActivity activity = (ConversationActivity) getActivity(); | ||||
| 		if (this.conversation != null) { | ||||
| 			for (Message message : this.conversation.getMessages()) { | ||||
| 				if ((message.getEncryption() == Message.ENCRYPTION_PGP)&&((message.getStatus() == Message.STATUS_RECIEVED)||(message.getStatus() == Message.STATUS_SEND))) { | ||||
| 				if ((message.getEncryption() == Message.ENCRYPTION_PGP) | ||||
| 						&& ((message.getStatus() == Message.STATUS_RECIEVED) || (message | ||||
| 								.getStatus() == Message.STATUS_SEND))) { | ||||
| 					decryptMessage(message); | ||||
| 					break; | ||||
| 				} | ||||
|  | @ -623,31 +626,26 @@ public class ConversationFragment extends Fragment { | |||
| 	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() { | ||||
| 		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); | ||||
| 			} | ||||
| 				@Override | ||||
| 				public void onClick(View v) { | ||||
| 					AlertDialog dialog = UIHelper.getVerifyFingerprintDialog( | ||||
| 							(ConversationActivity) getActivity(), conversation, | ||||
| 							fingerprintWarning); | ||||
| 					dialog.show(); | ||||
| 				} | ||||
| 			}); | ||||
| 		} else { | ||||
| 			fingerprintWarning.setVisibility(View.GONE); | ||||
| 		} | ||||
|  | @ -666,35 +664,31 @@ public class ConversationFragment extends Fragment { | |||
| 		final Contact contact = message.getConversation().getContact(); | ||||
| 		if (activity.hasPgp()) { | ||||
| 			if (contact.getPgpKeyId() != 0) { | ||||
| 				xmppService.getPgpEngine().hasKey(contact, | ||||
| 						new UiCallback() { | ||||
| 				xmppService.getPgpEngine().hasKey(contact, new UiCallback() { | ||||
| 
 | ||||
| 							@Override | ||||
| 							public void userInputRequried(PendingIntent pi) { | ||||
| 								activity.runIntent( | ||||
| 										pi, | ||||
| 										ConversationActivity.REQUEST_ENCRYPT_MESSAGE); | ||||
| 							} | ||||
| 					@Override | ||||
| 					public void userInputRequried(PendingIntent pi) { | ||||
| 						activity.runIntent(pi, | ||||
| 								ConversationActivity.REQUEST_ENCRYPT_MESSAGE); | ||||
| 					} | ||||
| 
 | ||||
| 							@Override | ||||
| 							public void success() { | ||||
| 								activity.encryptTextMessage(); | ||||
| 							} | ||||
| 					@Override | ||||
| 					public void success() { | ||||
| 						activity.encryptTextMessage(); | ||||
| 					} | ||||
| 
 | ||||
| 							@Override | ||||
| 							public void error(int error) { | ||||
| 					@Override | ||||
| 					public void error(int error) { | ||||
| 
 | ||||
| 							} | ||||
| 						}); | ||||
| 					} | ||||
| 				}); | ||||
| 
 | ||||
| 			} else { | ||||
| 				showNoPGPKeyDialog(new DialogInterface.OnClickListener() { | ||||
| 
 | ||||
| 					@Override | ||||
| 					public void onClick(DialogInterface dialog, | ||||
| 							int which) { | ||||
| 						conversation | ||||
| 								.setNextEncryption(Message.ENCRYPTION_NONE); | ||||
| 					public void onClick(DialogInterface dialog, int which) { | ||||
| 						conversation.setNextEncryption(Message.ENCRYPTION_NONE); | ||||
| 						message.setEncryption(Message.ENCRYPTION_NONE); | ||||
| 						xmppService.sendMessage(message, null); | ||||
| 						chatMsg.setText(""); | ||||
|  | @ -705,13 +699,13 @@ public class ConversationFragment extends Fragment { | |||
| 	} | ||||
| 
 | ||||
| 	public void showNoPGPKeyDialog(DialogInterface.OnClickListener listener) { | ||||
| 		AlertDialog.Builder builder = new AlertDialog.Builder( | ||||
| 				getActivity()); | ||||
| 		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); | ||||
| 		builder.setTitle(getString(R.string.no_pgp_key)); | ||||
| 		builder.setIconAttribute(android.R.attr.alertDialogIcon); | ||||
| 		builder.setMessage(getText(R.string.contact_has_no_pgp_key)); | ||||
| 		builder.setNegativeButton(getString(R.string.cancel), null); | ||||
| 		builder.setPositiveButton(getString(R.string.send_unencrypted),listener); | ||||
| 		builder.setPositiveButton(getString(R.string.send_unencrypted), | ||||
| 				listener); | ||||
| 		builder.create().show(); | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,7 +17,6 @@ import android.content.SharedPreferences; | |||
| import android.graphics.Bitmap; | ||||
| import android.os.Bundle; | ||||
| import android.preference.PreferenceManager; | ||||
| import android.util.Log; | ||||
| import android.view.View; | ||||
| import android.view.View.OnClickListener; | ||||
| import android.widget.ImageView; | ||||
|  | @ -29,15 +28,6 @@ public class ShareWithActivity extends XmppActivity { | |||
| 	private LinearLayout conversations; | ||||
| 	private LinearLayout contacts; | ||||
| 	 | ||||
| 	private OnClickListener click = new OnClickListener() { | ||||
| 		 | ||||
| 		@Override | ||||
| 		public void onClick(View v) { | ||||
| 			// TODO Auto-generated method stub | ||||
| 			 | ||||
| 		} | ||||
| 	}; | ||||
| 	 | ||||
| 	@Override | ||||
| 	protected void onCreate(Bundle savedInstanceState) { | ||||
| 
 | ||||
|  | @ -71,7 +61,7 @@ public class ShareWithActivity extends XmppActivity { | |||
| 		SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); | ||||
| 		boolean useSubject = preferences.getBoolean("use_subject_in_muc", true); | ||||
| 		 | ||||
| 		Set<String> displayedContacts = new HashSet<String>(); | ||||
| 		Set<Contact> displayedContacts = new HashSet<Contact>(); | ||||
| 		conversations.removeAllViews(); | ||||
| 		List<Conversation> convList = xmppConnectionService.getConversations(); | ||||
| 		Collections.sort(convList, new Comparator<Conversation>() { | ||||
|  | @ -95,15 +85,13 @@ public class ShareWithActivity extends XmppActivity { | |||
| 				} | ||||
| 			}); | ||||
| 			conversations.addView(view); | ||||
| 			if (conversation.getContact() != null) { | ||||
| 				displayedContacts.add(conversation.getContact().getUuid()); | ||||
| 			} | ||||
| 			displayedContacts.add(conversation.getContact()); | ||||
| 		} | ||||
| 		contacts.removeAllViews(); | ||||
| 		final List<Contact> contactsList = new ArrayList<Contact>(); | ||||
| 		List<Contact> contactsList = new ArrayList<Contact>(); | ||||
| 		for(Account account : xmppConnectionService.getAccounts()) { | ||||
| 			for(final Contact contact : xmppConnectionService.getRoster(account)) { | ||||
| 				if (!displayedContacts.contains(contact.getUuid())) { | ||||
| 			for(Contact contact : account.getRoster().getContacts()) { | ||||
| 				if (!displayedContacts.contains(contact)&&(contact.getOption(Contact.Options.IN_ROSTER))) { | ||||
| 					contactsList.add(contact); | ||||
| 				} | ||||
| 			} | ||||
|  |  | |||
|  | @ -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<String, Bundle> phoneContacts); | ||||
| 	public void onPhoneContactsLoaded(List<Bundle> phoneContacts); | ||||
| } | ||||
|  |  | |||
|  | @ -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,20 +10,14 @@ 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<String, Bundle> phoneContacts = new Hashtable<String, Bundle>(); | ||||
| 		final List<Bundle> phoneContacts = new ArrayList<Bundle>(); | ||||
| 		 | ||||
| 		final String[] PROJECTION = new String[] { ContactsContract.Data._ID, | ||||
| 				ContactsContract.Data.DISPLAY_NAME, | ||||
|  | @ -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(); | ||||
|  |  | |||
|  | @ -247,13 +247,8 @@ public class UIHelper { | |||
| 
 | ||||
| 	public static Bitmap getContactPicture(Conversation conversation, int dpSize, Context context, boolean notification) { | ||||
| 		if(conversation.getMode() == Conversation.MODE_SINGLE) { | ||||
| 			if (conversation.getContact() != null){ | ||||
| 				return getContactPicture(conversation.getContact(), dpSize, | ||||
| 						context, notification); | ||||
| 			} else { | ||||
| 				return getContactPicture(conversation.getName(false), dpSize, | ||||
| 						context, notification); | ||||
| 			} | ||||
| 		} else{ | ||||
| 			int fgColor = UIHelper.FG_COLOR, | ||||
| 				bgColor = (notification) ? | ||||
|  | @ -506,7 +501,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); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 kruks23
						kruks23