refresh synced contacts even if offline

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/entities/Contact.java                      |  5 
src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java           |  2 
src/quicksy/java/eu/siacs/conversations/services/QuickConversationsService.java | 42 
3 files changed, 43 insertions(+), 6 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/entities/Contact.java 🔗

@@ -21,6 +21,7 @@ import java.util.Locale;
 import eu.siacs.conversations.Config;
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.android.AbstractPhoneContact;
+import eu.siacs.conversations.android.JabberIdContact;
 import eu.siacs.conversations.android.PhoneNumberContact;
 import eu.siacs.conversations.utils.JidHelper;
 import eu.siacs.conversations.utils.UIHelper;
@@ -529,7 +530,7 @@ public class Contact implements ListItem, Blockable {
 	}
 
 	public static int getOption(Class<? extends AbstractPhoneContact> clazz) {
-		if (clazz == PhoneNumberContact.class) {
+		if (clazz == JabberIdContact.class) {
 			return Options.SYNCED_VIA_ADDRESSBOOK;
 		} else {
 			return Options.SYNCED_VIA_OTHER;
@@ -546,6 +547,6 @@ public class Contact implements ListItem, Blockable {
 		public static final int DIRTY_PUSH = 6;
 		public static final int DIRTY_DELETE = 7;
 		private static final int SYNCED_VIA_ADDRESSBOOK = 8;
-		private static final int SYNCED_VIA_OTHER = 9;
+		public static final int SYNCED_VIA_OTHER = 9;
 	}
 }

src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java 🔗

@@ -911,7 +911,7 @@ public class DatabaseBackend extends SQLiteOpenHelper {
 		final SQLiteDatabase db = this.getWritableDatabase();
 		db.beginTransaction();
 		for (Contact contact : roster.getContacts()) {
-			if (contact.getOption(Contact.Options.IN_ROSTER) || contact.getAvatarFilename() != null) {
+			if (contact.getOption(Contact.Options.IN_ROSTER) || contact.getAvatarFilename() != null || contact.getOption(Contact.Options.SYNCED_VIA_OTHER)) {
 				db.insert(Contact.TABLENAME, null, contact.getContentValues());
 			} else {
 				String where = Contact.ACCOUNT + "=? AND " + Contact.JID + "=?";

src/quicksy/java/eu/siacs/conversations/services/QuickConversationsService.java 🔗

@@ -2,6 +2,7 @@ package eu.siacs.conversations.services;
 
 
 import android.content.SharedPreferences;
+import android.net.Uri;
 import android.os.SystemClock;
 import android.preference.PreferenceManager;
 import android.util.Log;
@@ -15,6 +16,7 @@ import java.net.URL;
 import java.net.UnknownHostException;
 import java.security.SecureRandom;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
@@ -269,16 +271,39 @@ public class QuickConversationsService extends AbstractQuickConversationsService
     public void considerSync() {
         Map<String, PhoneNumberContact> contacts = PhoneNumberContact.load(service);
         for (Account account : service.getAccounts()) {
-            considerSync(account, contacts);
+            refresh(account, contacts.values());
+            if (!considerSync(account, contacts)) {
+                service.syncRoster(account);
+            }
         }
     }
 
-    private void considerSync(Account account, final Map<String, PhoneNumberContact> contacts) {
+    private void refresh(Account account, Collection<PhoneNumberContact> contacts) {
+        for(Contact contact : account.getRoster().getWithSystemAccounts(PhoneNumberContact.class)) {
+            final Uri uri = contact.getSystemAccount();
+            if (uri == null) {
+                continue;
+            }
+            PhoneNumberContact phoneNumberContact = findByUri(contacts, uri);
+            final boolean needsCacheClean;
+            if (phoneNumberContact != null) {
+                needsCacheClean = contact.setPhoneContact(phoneNumberContact);
+            } else {
+                needsCacheClean = contact.unsetPhoneContact(PhoneNumberContact.class);
+                Log.d(Config.LOGTAG,uri.toString()+" vanished from address book");
+            }
+            if (needsCacheClean) {
+                service.getAvatarService().clear(contact);
+            }
+        }
+    }
+
+    private boolean considerSync(Account account, final Map<String, PhoneNumberContact> contacts) {
         XmppConnection xmppConnection = account.getXmppConnection();
         Jid syncServer = xmppConnection == null ? null : xmppConnection.findDiscoItemByFeature(Namespace.SYNCHRONIZATION);
         if (syncServer == null) {
             Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": skipping sync. no sync server found");
-            return;
+            return false;
         }
         Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": sending phone list to " + syncServer);
         List<Element> entries = new ArrayList<>();
@@ -315,7 +340,18 @@ public class QuickConversationsService extends AbstractQuickConversationsService
                     }
                 }
             }
+            service.syncRoster(account);
         });
+        return true;
+    }
+
+    private static PhoneNumberContact findByUri(Collection<PhoneNumberContact> haystack, Uri needle) {
+        for(PhoneNumberContact contact : haystack) {
+            if (needle.equals(contact.getLookupUri())) {
+                return contact;
+            }
+        }
+        return null;
     }
 
     public static class Entry {