Commit 08cb9706 authored by Adrien Béraud's avatar Adrien Béraud
Browse files

account: fix deadlock, cleanup conversation sync

Change-Id: I2a65e32025281639250ce27e1d7bad06279484e1
parent 79b6d163
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package net.jami.model; package net.jami.model;
...@@ -94,7 +94,6 @@ public class Account { ...@@ -94,7 +94,6 @@ public class Account {
private final Subject<ContactLocationEntry> mLocationStartedSubject = PublishSubject.create(); private final Subject<ContactLocationEntry> mLocationStartedSubject = PublishSubject.create();
public Single<Account> historyLoader; public Single<Account> historyLoader;
//sprivate VCard mProfile;
private Single<Tuple<String, Object>> mLoadedProfile = null; private Single<Tuple<String, Object>> mLoadedProfile = null;
public Account(String bAccountID) { public Account(String bAccountID) {
...@@ -145,27 +144,31 @@ public class Account { ...@@ -145,27 +144,31 @@ public class Account {
contact.setConversationUri(conversation.getUri()); contact.setConversationUri(conversation.getUri());
} }
conversations.put(conversation.getUri().getUri(), conversation); conversations.put(conversation.getUri().getUri(), conversation);
conversationChanged();
} }
conversationChanged();
} }
public Conversation getSwarm(String conversationId) { public Conversation getSwarm(String conversationId) {
return swarmConversations.get(conversationId); synchronized (conversations) {
return swarmConversations.get(conversationId);
}
} }
public Conversation newSwarm(String conversationId, Conversation.Mode mode) { public Conversation newSwarm(String conversationId, Conversation.Mode mode) {
Conversation c = swarmConversations.get(conversationId); synchronized (conversations) {
if (c == null) { Conversation c = swarmConversations.get(conversationId);
c = new Conversation(accountID, new Uri(Uri.SWARM_SCHEME, conversationId), mode); if (c == null) {
swarmConversations.put(conversationId, c); c = new Conversation(accountID, new Uri(Uri.SWARM_SCHEME, conversationId), mode);
swarmConversations.put(conversationId, c);
}
return c;
} }
return c;
} }
public void removeSwarm(String conversationId) { public void removeSwarm(String conversationId) {
Log.w(TAG, "removeSwarm " + conversationId); Log.w(TAG, "removeSwarm " + conversationId);
Conversation conversation = swarmConversations.remove(conversationId); synchronized (conversations) {
if (conversation != null) { Conversation conversation = swarmConversations.remove(conversationId);
synchronized (conversations) { if (conversation != null) {
Conversation c = conversations.remove(conversation.getUri().getUri()); Conversation c = conversations.remove(conversation.getUri().getUri());
try { try {
Contact contact = c.getContact(); Contact contact = c.getContact();
...@@ -174,10 +177,9 @@ public class Account { ...@@ -174,10 +177,9 @@ public class Account {
contact.setConversationUri(contact.getUri()); contact.setConversationUri(contact.getUri());
contactAdded(contact); contactAdded(contact);
} }
} catch (Exception ignored) { } catch (Exception ignored) {}
} conversationChanged();
} }
conversationChanged();
} }
} }
...@@ -271,17 +273,19 @@ public class Account { ...@@ -271,17 +273,19 @@ public class Account {
} }
public void conversationChanged() { public void conversationChanged() {
conversationsChanged = true; synchronized (conversations) {
if (historyLoaded) { conversationsChanged = true;
conversationsSubject.onNext(new ArrayList<>(getSortedConversations())); if (historyLoaded) {
conversationsSubject.onNext(new ArrayList<>(getSortedConversations()));
}
updateUnreadConversations();
} }
updateUnreadConversations();
} }
public void conversationUpdated(Conversation conversation) { public void conversationUpdated(Conversation conversation) {
if (!historyLoaded) synchronized (conversations) {
return; if (!historyLoaded)
synchronized (sortedConversations) { return;
if (conversationsChanged) { if (conversationsChanged) {
getSortedConversations(); getSortedConversations();
} else { } else {
...@@ -296,15 +300,13 @@ public class Account { ...@@ -296,15 +300,13 @@ public class Account {
private void updateUnreadConversations() { private void updateUnreadConversations() {
int unread = 0; int unread = 0;
synchronized (sortedConversations) { for (Conversation model : sortedConversations) {
for (Conversation model : sortedConversations) { Interaction last = model.getLastEvent();
Interaction last = model.getLastEvent(); if (last != null && !last.isRead())
if (last != null && !last.isRead()) unread++;
unread++;
}
// Log.w(TAG, "updateUnreadConversations " + unread);
unreadConversationsSubject.onNext(unread);
} }
// Log.w(TAG, "updateUnreadConversations " + unread);
unreadConversationsSubject.onNext(unread);
} }
private void updateUnreadPending() { private void updateUnreadPending() {
...@@ -338,11 +340,19 @@ public class Account { ...@@ -338,11 +340,19 @@ public class Account {
public void updated(Conversation conversation) { public void updated(Conversation conversation) {
String key = conversation.getUri().getUri(); String key = conversation.getUri().getUri();
if (conversation == conversations.get(key)) synchronized (conversations) {
conversationUpdated(conversation); if (conversation == conversations.get(key)) {
else if (conversation == pending.get(key)) conversationUpdated(conversation);
pendingUpdated(conversation); return;
else if (conversation == cache.get(key)) { }
}
synchronized (pending) {
if (conversation == pending.get(key)) {
pendingUpdated(conversation);
return;
}
}
if (conversation == cache.get(key)) {
if (isJami() && !conversation.isSwarm() && conversation.getContacts().size() == 1 && !conversation.getContact().getConversationUri().blockingFirst().equals(conversation.getUri())) { if (isJami() && !conversation.isSwarm() && conversation.getContacts().size() == 1 && !conversation.getContact().getConversationUri().blockingFirst().equals(conversation.getUri())) {
return; return;
} }
...@@ -358,10 +368,16 @@ public class Account { ...@@ -358,10 +368,16 @@ public class Account {
} }
public void refreshed(Conversation conversation) { public void refreshed(Conversation conversation) {
if (conversations.containsValue(conversation)) synchronized (conversations) {
conversationRefreshed(conversation); if (conversations.containsValue(conversation)) {
else if (pending.containsValue(conversation)) conversationRefreshed(conversation);
pendingRefreshed(); return;
}
}
synchronized (pending) {
if (pending.containsValue(conversation))
pendingRefreshed();
}
} }
public void addTextMessage(TextMessage txt) { public void addTextMessage(TextMessage txt) {
...@@ -687,10 +703,8 @@ public class Account { ...@@ -687,10 +703,8 @@ public class Account {
TrustRequest req = mRequests.get(id); TrustRequest req = mRequests.get(id);
if (req != null) { if (req != null) {
mRequests.remove(id); mRequests.remove(id);
//trustRequestsSubject.onNext(mRequests.values());
} }
contactAdded(contact); contactAdded(contact);
//contactSubject.onNext(new ContactEvent(callContact, true));
contactListSubject.onNext(mContacts.values()); contactListSubject.onNext(mContacts.values());
} }
...@@ -708,11 +722,9 @@ public class Account { ...@@ -708,11 +722,9 @@ public class Account {
TrustRequest req = mRequests.get(id); TrustRequest req = mRequests.get(id);
if (req != null) { if (req != null) {
mRequests.remove(id); mRequests.remove(id);
//trustRequestsSubject.onNext(mRequests.values());
} }
if (contact != null) { if (contact != null) {
contactRemoved(contact.getUri()); contactRemoved(contact.getUri());
//contactSubject.onNext(new ContactEvent(callContact, false));
} }
contactListSubject.onNext(mContacts.values()); contactListSubject.onNext(mContacts.values());
} }
...@@ -756,31 +768,17 @@ public class Account { ...@@ -756,31 +768,17 @@ public class Account {
return requests; return requests;
} }
public Map<String, TrustRequest> getRequestsMigration() {
return mRequests;
}
public TrustRequest getRequest(Uri uri) { public TrustRequest getRequest(Uri uri) {
return mRequests.get(uri.getUri()); return mRequests.get(uri.getUri());
} }
public void addRequest(TrustRequest request) { public void addRequest(TrustRequest request) {
//Log.w(TAG, "addRequest start");
synchronized (pending) { synchronized (pending) {
//boolean isSwarm = request.getConversationId() != null;
String key = request.getUri().getUri(); String key = request.getUri().getUri();
//if (!isSwarm) {
mRequests.put(key, request); mRequests.put(key, request);
//trustRequestSubject.onNext(new RequestEvent(request, true));
//trustRequestsSubject.onNext(mRequests.values());
//}
Conversation conversation = pending.get(key); Conversation conversation = pending.get(key);
if (conversation == null) { if (conversation == null) {
/*if (isSwarm) { conversation = getByKey(key);
Log.w(TAG, "new public swarm request");
}*/
conversation = /*isSwarm ? newSwarm(key, Conversation.Mode.Public) : */getByKey(key);
pending.put(key, conversation); pending.put(key, conversation);
if (!conversation.isSwarm()) { if (!conversation.isSwarm()) {
Contact contact = getContactFromCache(request.getUri()); Contact contact = getContactFromCache(request.getUri());
...@@ -804,9 +802,7 @@ public class Account { ...@@ -804,9 +802,7 @@ public class Account {
Contact contact = getContactFromCache(request.getUri()); Contact contact = getContactFromCache(request.getUri());
conversation.addRequestEvent(request, contact); conversation.addRequestEvent(request, contact);
} }
//trustRequestSubject.onNext(new RequestEvent(request, true));
} }
//trustRequestsSubject.onNext(mRequests.values());
pendingChanged(); pendingChanged();
} }
} }
...@@ -815,10 +811,6 @@ public class Account { ...@@ -815,10 +811,6 @@ public class Account {
synchronized (pending) { synchronized (pending) {
String contactUri = contact.getUri(); String contactUri = contact.getUri();
TrustRequest request = mRequests.remove(contactUri); TrustRequest request = mRequests.remove(contactUri);
if (request != null) {
//trustRequestSubject.onNext(new RequestEvent(request, true));
//trustRequestsSubject.onNext(mRequests.values());
}
if (pending.remove(contactUri) != null) { if (pending.remove(contactUri) != null) {
pendingChanged(); pendingChanged();
return true; return true;
...@@ -872,53 +864,45 @@ public class Account { ...@@ -872,53 +864,45 @@ public class Account {
} }
public void setHistoryLoaded(List<Conversation> conversations) { public void setHistoryLoaded(List<Conversation> conversations) {
if (historyLoaded) synchronized (this.conversations) {
return; if (historyLoaded)
//Log.w(TAG, "setHistoryLoaded " + getAccountID() + " " + conversations.size()); return;
for (Conversation c : conversations) { //Log.w(TAG, "setHistoryLoaded " + getAccountID() + " " + conversations.size());
Contact contact = c.getContact(); for (Conversation c : conversations) {
if (!c.isSwarm() && contact != null && contact.getConversationUri().blockingFirst().equals(c.getUri())) Contact contact = c.getContact();
updated(c); if (!c.isSwarm() && contact != null && contact.getConversationUri().blockingFirst().equals(c.getUri()))
updated(c);
}
historyLoaded = true;
conversationChanged();
pendingChanged();
} }
historyLoaded = true;
conversationChanged();
pendingChanged();
} }
private List<Conversation> getSortedConversations() { private List<Conversation> getSortedConversations() {
//Log.w(TAG, "getSortedConversations() " + Thread.currentThread().getId()); if (conversationsChanged) {
synchronized (sortedConversations) { sortedConversations.clear();
if (conversationsChanged) { sortedConversations.addAll(conversations.values());
sortedConversations.clear(); for (Conversation c : sortedConversations)
synchronized (conversations) { c.sortHistory();
sortedConversations.addAll(conversations.values()); Collections.sort(sortedConversations, new ConversationComparator());
} conversationsChanged = false;
for (Conversation c : sortedConversations)
c.sortHistory();
Collections.sort(sortedConversations, new ConversationComparator());
conversationsChanged = false;
}
} }
return sortedConversations; return sortedConversations;
} }
private List<Conversation> getSortedPending() { private List<Conversation> getSortedPending() {
synchronized (sortedPending) { if (pendingsChanged) {
if (pendingsChanged) { sortedPending.clear();
sortedPending.clear(); sortedPending.addAll(pending.values());
synchronized (pending) { for (Conversation c : sortedPending)
sortedPending.addAll(pending.values()); c.sortHistory();
} Collections.sort(sortedPending, new ConversationComparator());
for (Conversation c : sortedPending) pendingsChanged = false;
c.sortHistory();
Collections.sort(sortedPending, new ConversationComparator());
pendingsChanged = false;
}
} }
return sortedPending; return sortedPending;
} }
private void contactAdded(Contact contact) { private void contactAdded(Contact contact) {
Uri uri = contact.getUri(); Uri uri = contact.getUri();
String key = uri.getUri(); String key = uri.getUri();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment