Fixed contact's presence + more contacts optimizations

This commit is contained in:
Sylvain Berfini 2017-01-19 14:19:17 +01:00
parent bfff5b9ec6
commit 781a5d5bcd
4 changed files with 105 additions and 63 deletions

View file

@ -183,7 +183,7 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
LinphoneActivity.instance().selectMenu(FragmentsAvailable.CONTACT_DETAIL); LinphoneActivity.instance().selectMenu(FragmentsAvailable.CONTACT_DETAIL);
LinphoneActivity.instance().hideTabBar(false); LinphoneActivity.instance().hideTabBar(false);
} }
contact.minimalRefresh(); contact.minimalRefresh(true);
displayContact(inflater, view); displayContact(inflater, view);
} }

View file

@ -32,6 +32,7 @@ import java.util.concurrent.TimeUnit;
import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCore;
import org.linphone.core.LinphoneFriend; import org.linphone.core.LinphoneFriend;
import org.linphone.core.LinphoneFriendList;
import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.LinphoneProxyConfig;
import org.linphone.mediastream.Log; import org.linphone.mediastream.Log;
@ -285,12 +286,22 @@ public class ContactsManager extends ContentObserver {
public synchronized void setContacts(List<LinphoneContact> c) { public synchronized void setContacts(List<LinphoneContact> c) {
contacts = c; contacts = c;
sipContacts = new ArrayList<LinphoneContact>(); }
public synchronized void setSipContacts(List<LinphoneContact> c) {
sipContacts = c;
}
public synchronized void refreshSipContacts() {
for (LinphoneContact contact : contacts) { for (LinphoneContact contact : contacts) {
if (contact.hasAddress() || contact.isInLinphoneFriendList()) { if (contact.isInLinphoneFriendList() && !sipContacts.contains(contact)) {
sipContacts.add(contact); sipContacts.add(contact);
} }
} }
Collections.sort(sipContacts);
for (ContactsUpdatedListener listener : contactsUpdatedListeners) {
listener.onContactsUpdated();
}
} }
public synchronized void fetchContactsAsync() { public synchronized void fetchContactsAsync() {
@ -301,10 +312,20 @@ public class ContactsManager extends ContentObserver {
contactsFetchTask.execute(); contactsFetchTask.execute();
} }
private class ContactsFetchTask extends AsyncTask<Void, List<LinphoneContact>, List<LinphoneContact>> { private class ContactsLists {
@SuppressWarnings("unchecked") public List<LinphoneContact> contacts;
protected List<LinphoneContact> doInBackground(Void... params) { public List<LinphoneContact> sipContacts;
public ContactsLists(List<LinphoneContact> c, List<LinphoneContact> s) {
contacts = c;
sipContacts = s;
}
}
private class ContactsFetchTask extends AsyncTask<Void, ContactsLists, ContactsLists> {
protected ContactsLists doInBackground(Void... params) {
List<LinphoneContact> contacts = new ArrayList<LinphoneContact>(); List<LinphoneContact> contacts = new ArrayList<LinphoneContact>();
List<LinphoneContact> sipContacts = new ArrayList<LinphoneContact>();
Date contactsTime = new Date(); Date contactsTime = new Date();
//We need to check sometimes to know if Linphone was destroyed //We need to check sometimes to know if Linphone was destroyed
@ -317,7 +338,7 @@ public class ContactsManager extends ContentObserver {
if (c != null) { if (c != null) {
while (c.moveToNext()) { while (c.moveToNext()) {
String id = c.getString(c.getColumnIndex(Data.CONTACT_ID)); String id = c.getString(c.getColumnIndex(Data.CONTACT_ID));
String displayName = c.getString(c.getColumnIndex(Data.DISPLAY_NAME)); String displayName = c.getString(c.getColumnIndex(Data.DISPLAY_NAME_PRIMARY));
LinphoneContact contact = new LinphoneContact(); LinphoneContact contact = new LinphoneContact();
contact.setFullName(displayName); contact.setFullName(displayName);
contact.setAndroidId(id); contact.setAndroidId(id);
@ -386,13 +407,17 @@ public class ContactsManager extends ContentObserver {
// This will only get name & picture informations to be able to quickly display contacts list // This will only get name & picture informations to be able to quickly display contacts list
contact.minimalRefresh(); contact.minimalRefresh();
i++; i++;
if (contact.hasAddress()) {
sipContacts.add(contact);
}
if (i == CONTACTS_STEP) { if (i == CONTACTS_STEP) {
i = 0; i = 0;
publishProgress(contacts); publishProgress(new ContactsLists(contacts, sipContacts));
} }
} }
Collections.sort(contacts); Collections.sort(contacts);
Collections.sort(sipContacts);
timeElapsed = (new Date()).getTime() - contactsTime.getTime(); timeElapsed = (new Date()).getTime() - contactsTime.getTime();
time = String.format("%02d:%02d", time = String.format("%02d:%02d",
@ -401,7 +426,7 @@ public class ContactsManager extends ContentObserver {
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeElapsed))); TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeElapsed)));
Log.i("[ContactsManager] organization, SIP and phone numbers for " + contacts.size() + " contacts fetched in " + time); Log.i("[ContactsManager] organization, SIP and phone numbers for " + contacts.size() + " contacts fetched in " + time);
// Public the current list of contacts without all the informations populated // Public the current list of contacts without all the informations populated
publishProgress(contacts); publishProgress(new ContactsLists(contacts, sipContacts));
for (LinphoneContact contact : contacts) { for (LinphoneContact contact : contacts) {
//We need to check sometimes to know if Linphone was destroyed //We need to check sometimes to know if Linphone was destroyed
@ -410,6 +435,10 @@ public class ContactsManager extends ContentObserver {
} }
// This time fetch all informations including phone numbers and SIP addresses // This time fetch all informations including phone numbers and SIP addresses
contact.refresh(); contact.refresh();
if (contact.isInLinphoneFriendList() && !sipContacts.contains(contact)) {
sipContacts.add(contact);
}
} }
timeElapsed = (new Date()).getTime() - contactsTime.getTime(); timeElapsed = (new Date()).getTime() - contactsTime.getTime();
time = String.format("%02d:%02d", time = String.format("%02d:%02d",
@ -418,12 +447,18 @@ public class ContactsManager extends ContentObserver {
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeElapsed))); TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeElapsed)));
Log.i("[ContactsManager] linphone friends for " + contacts.size() + " contacts created in " + time); Log.i("[ContactsManager] linphone friends for " + contacts.size() + " contacts created in " + time);
return contacts; for (LinphoneFriendList lfl : lc.getFriendLists()) {
Log.d("[ContactsManager] Updating friends subscribtions");
lfl.updateSubscriptions();
} }
protected void onProgressUpdate(List<LinphoneContact>... result) { return new ContactsLists(contacts, sipContacts);
}
protected void onProgressUpdate(ContactsLists... result) {
synchronized (ContactsManager.this) { synchronized (ContactsManager.this) {
setContacts(result[0]); setContacts(result[0].contacts);
setSipContacts(result[0].sipContacts);
contactsCache.clear(); contactsCache.clear();
for (ContactsUpdatedListener listener : contactsUpdatedListeners) { for (ContactsUpdatedListener listener : contactsUpdatedListeners) {
listener.onContactsUpdated(); listener.onContactsUpdated();
@ -431,7 +466,7 @@ public class ContactsManager extends ContentObserver {
} }
} }
protected void onPostExecute(List<LinphoneContact> result) { protected void onPostExecute(ContactsLists result) {
for (ContactsUpdatedListener listener : contactsUpdatedListeners) { for (ContactsUpdatedListener listener : contactsUpdatedListeners) {
listener.onContactsUpdated(); listener.onContactsUpdated();
} }
@ -498,10 +533,10 @@ public class ContactsManager extends ContentObserver {
+ "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL " + "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL "
+ " OR (" + Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + " OR (" + Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE
+ "' AND " + CommonDataKinds.SipAddress.SIP_ADDRESS + " IS NOT NULL))"; + "' AND " + CommonDataKinds.SipAddress.SIP_ADDRESS + " IS NOT NULL))";
String[] projection = new String[] { Data.CONTACT_ID, Data.DISPLAY_NAME }; String[] projection = new String[] { Data.CONTACT_ID, Data.DISPLAY_NAME_PRIMARY };
String query = Data.DISPLAY_NAME + " IS NOT NULL AND (" + req + ")"; String query = Data.DISPLAY_NAME_PRIMARY + " IS NOT NULL AND (" + req + ")";
Cursor cursor = cr.query(Data.CONTENT_URI, projection, query, null, " lower(" + Data.DISPLAY_NAME + ") COLLATE UNICODE ASC"); Cursor cursor = cr.query(Data.CONTENT_URI, projection, query, null, " lower(" + Data.DISPLAY_NAME_PRIMARY + ") COLLATE UNICODE ASC");
if (cursor == null) { if (cursor == null) {
return cursor; return cursor;
} }
@ -509,13 +544,13 @@ public class ContactsManager extends ContentObserver {
MatrixCursor result = new MatrixCursor(cursor.getColumnNames()); MatrixCursor result = new MatrixCursor(cursor.getColumnNames());
Set<String> groupBy = new HashSet<String>(); Set<String> groupBy = new HashSet<String>();
while (cursor.moveToNext()) { while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex(Data.DISPLAY_NAME)); String name = cursor.getString(cursor.getColumnIndex(Data.DISPLAY_NAME_PRIMARY));
if (!groupBy.contains(name)) { if (!groupBy.contains(name)) {
groupBy.add(name); groupBy.add(name);
Object[] newRow = new Object[cursor.getColumnCount()]; Object[] newRow = new Object[cursor.getColumnCount()];
int contactID = cursor.getColumnIndex(Data.CONTACT_ID); int contactID = cursor.getColumnIndex(Data.CONTACT_ID);
int displayName = cursor.getColumnIndex(Data.DISPLAY_NAME); int displayName = cursor.getColumnIndex(Data.DISPLAY_NAME_PRIMARY);
newRow[contactID] = cursor.getString(contactID); newRow[contactID] = cursor.getString(contactID);
newRow[displayName] = cursor.getString(displayName); newRow[displayName] = cursor.getString(displayName);

View file

@ -401,6 +401,9 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
} }
private void createOrUpdateFriend() { private void createOrUpdateFriend() {
boolean created = false;
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (!isLinphoneFriend()) { if (!isLinphoneFriend()) {
friend = LinphoneManager.getLc().createFriend(); friend = LinphoneManager.getLc().createFriend();
friend.enableSubscribes(false); friend.enableSubscribes(false);
@ -408,31 +411,24 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
if (isAndroidContact()) { if (isAndroidContact()) {
friend.setRefKey(getAndroidId()); friend.setRefKey(getAndroidId());
} }
created = true;
} }
if (isLinphoneFriend()) { if (isLinphoneFriend()) {
updateFriend();
}
}
private void updateFriend() {
if (!isLinphoneFriend()) return;
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (lc == null) return;
friend.edit(); friend.edit();
friend.setName(fullName); friend.setName(fullName);
friend.setFamilyName(lastName); friend.setFamilyName(lastName);
friend.setGivenName(firstName); friend.setGivenName(firstName);
if (organization != null) {
friend.setOrganization(organization);
}
if (!created) {
for (LinphoneAddress address : friend.getAddresses()) { for (LinphoneAddress address : friend.getAddresses()) {
friend.removeAddress(address); friend.removeAddress(address);
} }
for (String phone : friend.getPhoneNumbers()) { for (String phone : friend.getPhoneNumbers()) {
friend.removePhoneNumber(phone); friend.removePhoneNumber(phone);
} }
if (organization != null && !organization.isEmpty()) {
friend.setOrganization(organization);
} }
for (LinphoneNumberOrAddress noa : addresses) { for (LinphoneNumberOrAddress noa : addresses) {
if (noa.isSIPAddress()) { if (noa.isSIPAddress()) {
@ -449,10 +445,10 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
} }
} }
friend.done(); friend.done();
}
if (!friend.isAlreadyPresentInFriendList()) { if (created) {
try { try {
LinphoneManager.getLcIfManagerNotDestroyedOrNull().addFriend(friend); lc.addFriend(friend);
} catch (LinphoneCoreException e) { } catch (LinphoneCoreException e) {
Log.e(e); Log.e(e);
} }
@ -500,12 +496,21 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
} }
public void minimalRefresh() { public void minimalRefresh() {
minimalRefresh(false);
}
public void minimalRefresh(boolean getAllNames) {
addresses = new ArrayList<LinphoneNumberOrAddress>(); addresses = new ArrayList<LinphoneNumberOrAddress>();
hasSipAddress = false; hasSipAddress = false;
if (isAndroidContact()) { if (isAndroidContact()) {
if (getAllNames) {
getContactNames(); getContactNames();
}
boolean isOrgVisible = LinphoneManager.getInstance().getContext().getResources().getBoolean(R.bool.display_contact_organization);
if (isOrgVisible) {
getNativeContactOrganization(); getNativeContactOrganization();
}
for (LinphoneNumberOrAddress noa : getAddressesAndNumbersForAndroidContact()) { for (LinphoneNumberOrAddress noa : getAddressesAndNumbersForAndroidContact()) {
addNumberOrAddress(noa); addNumberOrAddress(noa);

View file

@ -1000,7 +1000,9 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
public void displayMessage(LinphoneCore lc, String message) {} public void displayMessage(LinphoneCore lc, String message) {}
public void show(LinphoneCore lc) {} public void show(LinphoneCore lc) {}
public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url) {} public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url) {}
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {} public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {
ContactsManager.getInstance().refreshSipContacts();
}
@Override @Override
public void dtmfReceived(LinphoneCore lc, LinphoneCall call, int dtmf) { public void dtmfReceived(LinphoneCore lc, LinphoneCall call, int dtmf) {