added hash for status quo to make sync reply more performant
This commit is contained in:
		
							parent
							
								
									1bcbd257c3
								
							
						
					
					
						commit
						a1a625bb2d
					
				| @ -48,7 +48,7 @@ public final class Config { | ||||
| 
 | ||||
| 	public static final boolean ALLOW_NON_TLS_CONNECTIONS = false; //very dangerous. you should have a good reason to set this to true | ||||
| 
 | ||||
| 	public static final long CONTACT_SYNC_RETRY_INTERVAL = 1000L * 60 * 5; | ||||
| 	public static final long CONTACT_SYNC_RETRY_INTERVAL = 1000L * 60 * 1; | ||||
| 
 | ||||
| 
 | ||||
| 	//Notification settings | ||||
|  | ||||
| @ -4,10 +4,12 @@ import android.Manifest; | ||||
| import android.content.Context; | ||||
| import android.content.pm.PackageManager; | ||||
| import android.database.Cursor; | ||||
| import android.net.Uri; | ||||
| import android.os.Build; | ||||
| import android.provider.ContactsContract; | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import java.util.Collection; | ||||
| import java.util.Collections; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| @ -65,4 +67,13 @@ public class PhoneNumberContact extends AbstractPhoneContact { | ||||
|         } | ||||
|         return contacts; | ||||
|     } | ||||
| 
 | ||||
|     public static PhoneNumberContact findByUri(Collection<PhoneNumberContact> haystack, Uri needle) { | ||||
|         for(PhoneNumberContact contact : haystack) { | ||||
|             if (needle.equals(contact.getLookupUri())) { | ||||
|                 return contact; | ||||
|             } | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										114
									
								
								src/quicksy/java/eu/siacs/conversations/entities/Entry.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/quicksy/java/eu/siacs/conversations/entities/Entry.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,114 @@ | ||||
| package eu.siacs.conversations.entities; | ||||
| 
 | ||||
| import android.util.Base64; | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import java.security.MessageDigest; | ||||
| import java.security.NoSuchAlgorithmException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import eu.siacs.conversations.Config; | ||||
| import eu.siacs.conversations.android.PhoneNumberContact; | ||||
| import eu.siacs.conversations.xml.Element; | ||||
| import rocks.xmpp.addr.Jid; | ||||
| 
 | ||||
| public class Entry implements Comparable<Entry> { | ||||
|     private final List<Jid> jids; | ||||
|     private final String number; | ||||
| 
 | ||||
|     private Entry(String number, List<Jid> jids) { | ||||
|         this.number = number; | ||||
|         this.jids = jids; | ||||
|     } | ||||
| 
 | ||||
|     public static Entry of(Element element) { | ||||
|         final String number = element.getAttribute("number"); | ||||
|         final List<Jid> jids = new ArrayList<>(); | ||||
|         for (Element jidElement : element.getChildren()) { | ||||
|             String content = jidElement.getContent(); | ||||
|             if (content != null) { | ||||
|                 jids.add(Jid.of(content)); | ||||
|             } | ||||
|         } | ||||
|         return new Entry(number, jids); | ||||
|     } | ||||
| 
 | ||||
|     public static List<Entry> ofPhoneBook(Element phoneBook) { | ||||
|         List<Entry> entries = new ArrayList<>(); | ||||
|         for (Element entry : phoneBook.getChildren()) { | ||||
|             if ("entry".equals(entry.getName())) { | ||||
|                 entries.add(of(entry)); | ||||
|             } | ||||
|         } | ||||
|         return entries; | ||||
|     } | ||||
| 
 | ||||
|     public static String statusQuo(final Collection<PhoneNumberContact> phoneNumberContacts, Collection<Contact> systemContacts) { | ||||
|         return statusQuo(ofPhoneNumberContactsAndContacts(phoneNumberContacts, systemContacts)); | ||||
|     } | ||||
| 
 | ||||
|     private static String statusQuo(final List<Entry> entries) { | ||||
|         Collections.sort(entries); | ||||
|         StringBuilder builder = new StringBuilder(); | ||||
|         for(Entry entry : entries) { | ||||
|             if (builder.length() != 0) { | ||||
|                 builder.append('\u001d'); | ||||
|             } | ||||
|             builder.append(entry.getNumber()); | ||||
|             List<Jid> jids = entry.getJids(); | ||||
|             Collections.sort(jids); | ||||
|             for(Jid jid : jids) { | ||||
|                 builder.append('\u001e'); | ||||
|                 builder.append(jid.asBareJid().toEscapedString()); | ||||
|             } | ||||
|         } | ||||
|         MessageDigest md; | ||||
|         try { | ||||
|             md = MessageDigest.getInstance("SHA-1"); | ||||
|         } catch (NoSuchAlgorithmException e) { | ||||
|             return ""; | ||||
|         } | ||||
|         Log.d(Config.LOGTAG,"status quo string: "+builder.toString()); | ||||
|         byte[] sha1 = md.digest(builder.toString().getBytes()); | ||||
|         return new String(Base64.encode(sha1, Base64.DEFAULT)).trim(); | ||||
|     } | ||||
| 
 | ||||
|     private static List<Entry> ofPhoneNumberContactsAndContacts(final Collection<PhoneNumberContact> phoneNumberContacts, Collection<Contact> systemContacts) { | ||||
|         ArrayList<Entry> entries = new ArrayList<>(); | ||||
|         for(Contact contact : systemContacts) { | ||||
|             PhoneNumberContact phoneNumberContact = PhoneNumberContact.findByUri(phoneNumberContacts, contact.getSystemAccount()); | ||||
|             if (phoneNumberContact != null && phoneNumberContact.getPhoneNumber() != null) { | ||||
|                 Entry entry = findOrCreateByPhoneNumber(entries, phoneNumberContact.getPhoneNumber()); | ||||
|                 entry.jids.add(contact.getJid().asBareJid()); | ||||
|             } | ||||
|         } | ||||
|         return entries; | ||||
|     } | ||||
| 
 | ||||
|     private static Entry findOrCreateByPhoneNumber(final List<Entry> entries, String number) { | ||||
|         for(Entry entry : entries) { | ||||
|             if (entry.number.equals(number)) { | ||||
|                 return entry; | ||||
|             } | ||||
|         } | ||||
|         Entry entry = new Entry(number, new ArrayList<>()); | ||||
|         entries.add(entry); | ||||
|         return entry; | ||||
|     } | ||||
| 
 | ||||
|     public List<Jid> getJids() { | ||||
|         return jids; | ||||
|     } | ||||
| 
 | ||||
|     public String getNumber() { | ||||
|         return number; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int compareTo(Entry o) { | ||||
|         return number.compareTo(o.number); | ||||
|     } | ||||
| } | ||||
| @ -34,6 +34,7 @@ import eu.siacs.conversations.android.PhoneNumberContact; | ||||
| import eu.siacs.conversations.crypto.sasl.Plain; | ||||
| import eu.siacs.conversations.entities.Account; | ||||
| import eu.siacs.conversations.entities.Contact; | ||||
| import eu.siacs.conversations.entities.Entry; | ||||
| import eu.siacs.conversations.utils.AccountUtils; | ||||
| import eu.siacs.conversations.utils.CryptoHelper; | ||||
| import eu.siacs.conversations.utils.PhoneNumberUtilWrapper; | ||||
| @ -286,7 +287,7 @@ public class QuickConversationsService extends AbstractQuickConversationsService | ||||
|             if (uri == null) { | ||||
|                 continue; | ||||
|             } | ||||
|             PhoneNumberContact phoneNumberContact = findByUri(contacts, uri); | ||||
|             PhoneNumberContact phoneNumberContact = PhoneNumberContact.findByUri(contacts, uri); | ||||
|             final boolean needsCacheClean; | ||||
|             if (phoneNumberContact != null) { | ||||
|                 needsCacheClean = contact.setPhoneContact(phoneNumberContact); | ||||
| @ -320,13 +321,17 @@ public class QuickConversationsService extends AbstractQuickConversationsService | ||||
|         } | ||||
|         IqPacket query = new IqPacket(IqPacket.TYPE.GET); | ||||
|         query.setTo(syncServer); | ||||
|         query.addChild(new Element("phone-book", Namespace.SYNCHRONIZATION).setChildren(entries)); | ||||
|         Element book = new Element("phone-book", Namespace.SYNCHRONIZATION).setChildren(entries); | ||||
|         String statusQuo = Entry.statusQuo(contacts.values(), account.getRoster().getWithSystemAccounts(PhoneNumberContact.class)); | ||||
|         Log.d(Config.LOGTAG,"status quo="+statusQuo); | ||||
|         book.setAttribute("ver",statusQuo); | ||||
|         query.addChild(book); | ||||
|         mLastSyncAttempt = Attempt.create(hash); | ||||
|         service.sendIqPacket(account, query, (a, response) -> { | ||||
|             if (response.getType() == IqPacket.TYPE.RESULT) { | ||||
|                 List<Contact> withSystemAccounts = account.getRoster().getWithSystemAccounts(PhoneNumberContact.class); | ||||
|                 final Element phoneBook = response.findChild("phone-book", Namespace.SYNCHRONIZATION); | ||||
|                 if (phoneBook != null) { | ||||
|                     List<Contact> withSystemAccounts = account.getRoster().getWithSystemAccounts(PhoneNumberContact.class); | ||||
|                     for(Entry entry : Entry.ofPhoneBook(phoneBook)) { | ||||
|                         PhoneNumberContact phoneContact = contacts.get(entry.getNumber()); | ||||
|                         if (phoneContact == null) { | ||||
| @ -341,12 +346,14 @@ public class QuickConversationsService extends AbstractQuickConversationsService | ||||
|                             withSystemAccounts.remove(contact); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 for (Contact contact : withSystemAccounts) { | ||||
|                     final boolean needsCacheClean = contact.unsetPhoneContact(PhoneNumberContact.class); | ||||
|                     if (needsCacheClean) { | ||||
|                         service.getAvatarService().clear(contact); | ||||
|                     for (Contact contact : withSystemAccounts) { | ||||
|                         final boolean needsCacheClean = contact.unsetPhoneContact(PhoneNumberContact.class); | ||||
|                         if (needsCacheClean) { | ||||
|                             service.getAvatarService().clear(contact); | ||||
|                         } | ||||
|                     } | ||||
|                 } else { | ||||
|                     Log.d(Config.LOGTAG,account.getJid().asBareJid()+": phone number contact list remains unchanged"); | ||||
|                 } | ||||
|             } | ||||
|             service.syncRoster(account); | ||||
| @ -355,14 +362,6 @@ public class QuickConversationsService extends AbstractQuickConversationsService | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     private static PhoneNumberContact findByUri(Collection<PhoneNumberContact> haystack, Uri needle) { | ||||
|         for(PhoneNumberContact contact : haystack) { | ||||
|             if (needle.equals(contact.getLookupUri())) { | ||||
|                 return contact; | ||||
|             } | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     private static class Attempt { | ||||
|         private final long timestamp; | ||||
| @ -382,46 +381,6 @@ public class QuickConversationsService extends AbstractQuickConversationsService | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static class Entry { | ||||
|         private final List<Jid> jids; | ||||
|         private final String number; | ||||
| 
 | ||||
|         private Entry(String number, List<Jid> jids) { | ||||
|             this.number = number; | ||||
|             this.jids = jids; | ||||
|         } | ||||
| 
 | ||||
|         public static Entry of(Element element) { | ||||
|             final String number = element.getAttribute("number"); | ||||
|             final List<Jid> jids = new ArrayList<>(); | ||||
|             for (Element jidElement : element.getChildren()) { | ||||
|                 String content = jidElement.getContent(); | ||||
|                 if (content != null) { | ||||
|                     jids.add(Jid.of(content)); | ||||
|                 } | ||||
|             } | ||||
|             return new Entry(number, jids); | ||||
|         } | ||||
| 
 | ||||
|         public static List<Entry> ofPhoneBook(Element phoneBook) { | ||||
|             List<Entry> entries = new ArrayList<>(); | ||||
|             for (Element entry : phoneBook.getChildren()) { | ||||
|                 if ("entry".equals(entry.getName())) { | ||||
|                     entries.add(of(entry)); | ||||
|                 } | ||||
|             } | ||||
|             return entries; | ||||
|         } | ||||
| 
 | ||||
|         public List<Jid> getJids() { | ||||
|             return jids; | ||||
|         } | ||||
| 
 | ||||
|         public String getNumber() { | ||||
|             return number; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public interface OnVerificationRequested { | ||||
|         void onVerificationRequestFailed(int code); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch